2021-02-11 17:19:55 +00:00
|
|
|
#ifndef OPENMW_COMPONENTS_MISC_FRAMERATELIMITER_H
|
|
|
|
#define OPENMW_COMPONENTS_MISC_FRAMERATELIMITER_H
|
|
|
|
|
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
namespace Misc
|
|
|
|
{
|
|
|
|
class FrameRateLimiter
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
template <class Rep, class Ratio>
|
|
|
|
explicit FrameRateLimiter(std::chrono::duration<Rep, Ratio> maxFrameDuration,
|
|
|
|
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now())
|
|
|
|
: mMaxFrameDuration(std::chrono::duration_cast<std::chrono::steady_clock::duration>(maxFrameDuration))
|
|
|
|
, mLastMeasurement(now)
|
2021-04-17 06:53:47 +00:00
|
|
|
, mLastFrameDuration(0)
|
2021-02-11 17:19:55 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
std::chrono::steady_clock::duration getLastFrameDuration() const { return mLastFrameDuration; }
|
2022-09-22 18:26:05 +00:00
|
|
|
|
2021-02-11 17:19:55 +00:00
|
|
|
void limit(std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now())
|
2022-09-22 18:26:05 +00:00
|
|
|
{
|
2021-02-11 17:19:55 +00:00
|
|
|
const auto passed = now - mLastMeasurement;
|
|
|
|
const auto left = mMaxFrameDuration - passed;
|
|
|
|
if (left > left.zero())
|
|
|
|
{
|
|
|
|
std::this_thread::sleep_for(left);
|
|
|
|
mLastMeasurement = now + left;
|
|
|
|
mLastFrameDuration = mMaxFrameDuration;
|
|
|
|
}
|
2022-09-22 18:26:05 +00:00
|
|
|
else
|
2021-02-11 17:19:55 +00:00
|
|
|
{
|
|
|
|
mLastMeasurement = now;
|
|
|
|
mLastFrameDuration = passed;
|
|
|
|
}
|
2022-09-22 18:26:05 +00:00
|
|
|
}
|
2021-02-11 17:19:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::chrono::steady_clock::duration mMaxFrameDuration;
|
|
|
|
std::chrono::steady_clock::time_point mLastMeasurement;
|
|
|
|
std::chrono::steady_clock::duration mLastFrameDuration;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline Misc::FrameRateLimiter makeFrameRateLimiter(float frameRateLimit)
|
|
|
|
{
|
|
|
|
if (frameRateLimit > 0.0f)
|
|
|
|
return Misc::FrameRateLimiter(std::chrono::duration<float>(1.0f / frameRateLimit));
|
|
|
|
else
|
|
|
|
return Misc::FrameRateLimiter(std::chrono::steady_clock::duration::zero());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|