Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarTickRateMonitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/StarTickRateMonitor.cpp')
-rw-r--r--source/core/StarTickRateMonitor.cpp87
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;
+}
+
+}