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

summaryrefslogtreecommitdiff
path: root/source/core/StarTickRateMonitor.cpp
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;
}

}