1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

FramerateManager now uses chrono instead of SDL_Ticks

This commit is contained in:
Ivan Savenko
2023-05-13 01:12:11 +03:00
parent 03df274450
commit 3ecdff2a21
6 changed files with 65 additions and 68 deletions

View File

@@ -11,55 +11,47 @@
#include "StdInc.h"
#include "FramerateManager.h"
#include <SDL_timer.h>
FramerateManager::FramerateManager(int newRate)
: rate(0)
, rateticks(0)
, fps(0)
, accumulatedFrames(0)
, accumulatedTime(0)
, lastticks(0)
, timeElapsed(0)
FramerateManager::FramerateManager(int targetFrameRate)
: targetFrameTime(Duration(boost::chrono::seconds(1)) / targetFrameRate)
, lastFrameIndex(0)
, lastFrameTimes({})
, lastTimePoint (Clock::now())
{
init(newRate);
}
void FramerateManager::init(int newRate)
{
rate = newRate;
rateticks = 1000.0 / rate;
this->lastticks = SDL_GetTicks();
boost::range::fill(lastFrameTimes, targetFrameTime);
}
void FramerateManager::framerateDelay()
{
ui32 currentTicks = SDL_GetTicks();
timeElapsed = currentTicks - lastticks;
accumulatedFrames++;
Duration timeSpentBusy = Clock::now() - lastTimePoint;
// FPS is higher than it should be, then wait some time
if(timeElapsed < rateticks)
{
int timeToSleep = (uint32_t)ceil(this->rateticks) - timeElapsed;
boost::this_thread::sleep(boost::posix_time::milliseconds(timeToSleep));
}
if(timeSpentBusy < targetFrameTime)
boost::this_thread::sleep_for(targetFrameTime - timeSpentBusy);
currentTicks = SDL_GetTicks();
// recalculate timeElapsed for external calls via getElapsed()
// compute actual timeElapsed taking into account actual sleep interval
// limit it to 100 ms to avoid breaking animation in case of huge lag (e.g. triggered breakpoint)
timeElapsed = std::min<ui32>(currentTicks - lastticks, 100);
TimePoint currentTicks = Clock::now();
Duration timeElapsed = currentTicks - lastTimePoint;
if(timeElapsed > boost::chrono::milliseconds(100))
timeElapsed = boost::chrono::milliseconds(100);
lastticks = SDL_GetTicks();
accumulatedTime += timeElapsed;
if(accumulatedFrames >= 100)
{
//about 2 second should be passed
fps = static_cast<int>(ceil(1000.0 / (accumulatedTime / accumulatedFrames)));
accumulatedTime = 0;
accumulatedFrames = 0;
}
lastTimePoint = currentTicks;
lastFrameIndex = (lastFrameIndex + 1) % lastFrameTimes.size();
lastFrameTimes[lastFrameIndex] = timeElapsed;
}
ui32 FramerateManager::getElapsedMilliseconds() const
{
return lastFrameTimes[lastFrameIndex] / boost::chrono::milliseconds(1);
}
ui32 FramerateManager::getFramerate() const
{
Duration accumulatedTime = std::accumulate(lastFrameTimes.begin(), lastFrameTimes.end(), Duration());
auto actualFrameTime = accumulatedTime / lastFrameTimes.size();
if(actualFrameTime == actualFrameTime.zero())
return 0;
return std::round(boost::chrono::duration<double>(1) / actualFrameTime);
};