#include <chrono>
#include <iostream>
#include <thread>
#include <string>
using namespace std;
using namespace std::chrono;
using namespace std::this_thread;

typedef std::chrono::high_resolution_clock Clock;
struct LogFPS
{
    LogFPS(string name, Clock::time_point time) : _name(name), _time(time), _frameCount(0) {}
    void tick()
    {
        _frameCount++;
        Clock::time_point newTime = Clock::now();
        milliseconds totalTicks = duration_cast<milliseconds>(newTime - _time);
        if (totalTicks.count() > 1000)
        {
            cout << _name << " calls per second : " << _frameCount << endl;
            _frameCount = 0;
            _time = newTime;
        }

    }
    string _name;
    int _frameCount;
    Clock::time_point _time;
};

int main()
{
    Clock::time_point mLastEndTime;
    milliseconds mDeltaTime(0);
    milliseconds frameTime(0);

    const milliseconds kMaxDeltatime((int)((1.0f / 60.0f)*1000.0f));
    const milliseconds updateFrameCost(5);
    const milliseconds renderFrameCost(10);
    
    mLastEndTime = Clock::now();

    LogFPS rFPS(string("RenderFrame"), mLastEndTime);
    LogFPS uFPS(string("UpdateFrame"), mLastEndTime);

    while(true)
    {
        Clock::time_point currentTime = Clock::now();
        frameTime = duration_cast<milliseconds>(currentTime-mLastEndTime);
        mLastEndTime = currentTime;
        
        while (frameTime.count() > 0)
        {
            frameTime -= min(frameTime, kMaxDeltatime);
            sleep_for(updateFrameCost); // fake state processing     
            uFPS.tick();
        }
        sleep_for(renderFrameCost); // fake renderframe
        rFPS.tick();
    }
}
