diff options
Diffstat (limited to 'source/core/StarTickRateMonitor.cpp')
-rw-r--r-- | source/core/StarTickRateMonitor.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/source/core/StarTickRateMonitor.cpp b/source/core/StarTickRateMonitor.cpp new file mode 100644 index 0000000..78a423a --- /dev/null +++ b/source/core/StarTickRateMonitor.cpp @@ -0,0 +1,87 @@ +#include "StarTickRateMonitor.hpp" +#include "StarTime.hpp" + +namespace Star { + +TickRateMonitor::TickRateMonitor(double window) : m_window(window) { + reset(); +} + +double TickRateMonitor::window() const { + return m_window; +} + +void TickRateMonitor::reset() { + m_lastTick = Time::monotonicTime() - m_window; + m_ticks = 0; +} + +double TickRateMonitor::tick(unsigned count) { + double currentTime = Time::monotonicTime(); + + if (m_lastTick > currentTime) { + m_lastTick = currentTime - m_window; + m_ticks = 0; + } else if (m_lastTick < currentTime) { + double timePast = currentTime - m_lastTick; + double rate = m_ticks / m_window; + m_ticks = max(0.0, m_ticks - timePast * rate); + m_lastTick = currentTime; + } + + m_ticks += count; + + return m_ticks / m_window; +} + +double TickRateMonitor::rate() const { + return TickRateMonitor(*this).tick(0); +} + +TickRateApproacher::TickRateApproacher(double targetTickRate, double window) + : m_tickRateMonitor(window), m_targetTickRate(targetTickRate) {} + +double TickRateApproacher::window() const { + return m_tickRateMonitor.window(); +} + +void TickRateApproacher::setWindow(double window) { + if (window != m_tickRateMonitor.window()) { + m_tickRateMonitor = TickRateMonitor(window); + tick(m_targetTickRate * window); + } +} + +double TickRateApproacher::targetTickRate() const { + return m_targetTickRate; +} + +void TickRateApproacher::setTargetTickRate(double targetTickRate) { + m_targetTickRate = targetTickRate; +} + +void TickRateApproacher::reset() { + setWindow(window()); +} + +double TickRateApproacher::tick(unsigned count) { + return m_tickRateMonitor.tick(count); +} + +double TickRateApproacher::rate() const { + return m_tickRateMonitor.rate(); +} + +double TickRateApproacher::ticksBehind() { + return (m_targetTickRate - m_tickRateMonitor.rate()) * window(); +} + +double TickRateApproacher::ticksAhead() { + return -ticksBehind(); +} + +double TickRateApproacher::spareTime() { + return ticksAhead() / m_targetTickRate; +} + +} |