blob: 78a423a53cbe9ad60addd60039c9a2c177fc6fa3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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;
}
}
|