diff options
Diffstat (limited to 'source/game/StarGameTimers.cpp')
-rw-r--r-- | source/game/StarGameTimers.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/source/game/StarGameTimers.cpp b/source/game/StarGameTimers.cpp new file mode 100644 index 0000000..0bdd1e5 --- /dev/null +++ b/source/game/StarGameTimers.cpp @@ -0,0 +1,162 @@ +#include "StarGameTimers.hpp" +#include "StarJsonExtra.hpp" +#include "StarDataStreamExtra.hpp" + +namespace Star { + +GameTimer::GameTimer() : time(), timer() {} + +GameTimer::GameTimer(float time) : time(time) { + reset(); +} + +bool GameTimer::tick(float dt) { + timer = approach(0.0f, timer, dt); + return timer == 0.0f; +} + +bool GameTimer::ready() const { + return timer == 0.0f; +} + +bool GameTimer::wrapTick(float dt) { + auto res = tick(dt); + if (res) + reset(); + return res; +} + +void GameTimer::reset() { + timer = time; +} + +void GameTimer::setDone() { + timer = 0.0f; +} + +void GameTimer::invert() { + timer = time - timer; +} + +float GameTimer::percent() const { + if (time) + return timer / time; + else + return 0.0f; +} + +DataStream& operator>>(DataStream& ds, GameTimer& gt) { + ds >> gt.time; + ds >> gt.timer; + return ds; +} + +DataStream& operator<<(DataStream& ds, GameTimer const& gt) { + ds << gt.time; + ds << gt.timer; + return ds; +} + +SlidingWindow::SlidingWindow() : windowSize(1.0f), resolution(1) {} + +SlidingWindow::SlidingWindow(float windowSize, size_t resolution, float initialValue) + : windowSize(windowSize), resolution(resolution) { + sampleTimer = GameTimer(windowSize / resolution); + window = std::vector<float>(resolution); + reset(initialValue); +} + +void SlidingWindow::reset(float initialValue) { + sampleTimer.reset(); + currentIndex = 0; + currentMin = initialValue; + currentMax = initialValue; + currentAverage = initialValue; + std::fill(window.begin(), window.end(), initialValue); +} + +void SlidingWindow::update(function<float()> sampleFunction) { + if (sampleTimer.wrapTick()) { + processUpdate(sampleFunction()); + } +} + +void SlidingWindow::update(float newValue) { + if (sampleTimer.wrapTick()) { + processUpdate(newValue); + } +} + +void SlidingWindow::processUpdate(float newValue) { + ++currentIndex; + currentIndex = currentIndex % resolution; + window[currentIndex] = newValue; + + currentMin = std::numeric_limits<float>::max(); + currentMax = 0; + float total = 0; + for (float v : window) { + total += v; + currentMin = std::min(currentMin, v); + currentMax = std::max(currentMax, v); + } + currentAverage = total / resolution; +} + +float SlidingWindow::min() { + return currentMin; +} + +float SlidingWindow::max() { + return currentMax; +} + +float SlidingWindow::average() { + return currentAverage; +} + +EpochTimer::EpochTimer() : m_elapsedTime(0.0) {} + +EpochTimer::EpochTimer(Json json) { + m_lastSeenEpochTime = json.get("lastEpochTime").optDouble(); + m_elapsedTime = json.getDouble("elapsedTime"); +} + +Json EpochTimer::toJson() const { + return JsonObject{{"lastEpochTime", jsonFromMaybe(m_lastSeenEpochTime)}, {"elapsedTime", m_elapsedTime}}; +} + +void EpochTimer::update(double newEpochTime) { + if (!m_lastSeenEpochTime) { + m_lastSeenEpochTime = newEpochTime; + } else { + // Don't allow elapsed time to go backwards in the case of the epoch time + // being lost or wrong. + double difference = newEpochTime - *m_lastSeenEpochTime; + if (difference > 0) + m_elapsedTime += difference; + m_lastSeenEpochTime = newEpochTime; + } +} + +double EpochTimer::elapsedTime() const { + return m_elapsedTime; +} + +void EpochTimer::setElapsedTime(double elapsedTime) { + m_elapsedTime = elapsedTime; +} + +DataStream& operator>>(DataStream& ds, EpochTimer& et) { + ds >> et.m_lastSeenEpochTime; + ds >> et.m_elapsedTime; + return ds; +} + +DataStream& operator<<(DataStream& ds, EpochTimer const& et) { + ds << et.m_lastSeenEpochTime; + ds << et.m_elapsedTime; + return ds; +} + +} |