18069771cSKrzysztof Grobelny #pragma once
28069771cSKrzysztof Grobelny 
38069771cSKrzysztof Grobelny #include "interfaces/clock.hpp"
4*51f0fd50SKrzysztof Grobelny #include "types/duration_types.hpp"
58069771cSKrzysztof Grobelny 
68069771cSKrzysztof Grobelny class ClockFake : public interfaces::Clock
78069771cSKrzysztof Grobelny {
88069771cSKrzysztof Grobelny   public:
9*51f0fd50SKrzysztof Grobelny     template <class ClockType>
10*51f0fd50SKrzysztof Grobelny     struct InternalClock
118069771cSKrzysztof Grobelny     {
12*51f0fd50SKrzysztof Grobelny         using clock = ClockType;
13*51f0fd50SKrzysztof Grobelny         using time_point = typename clock::time_point;
14*51f0fd50SKrzysztof Grobelny 
timestampClockFake::InternalClock15*51f0fd50SKrzysztof Grobelny         Milliseconds timestamp() const noexcept
16*51f0fd50SKrzysztof Grobelny         {
17*51f0fd50SKrzysztof Grobelny             return ClockFake::toTimestamp(now);
188069771cSKrzysztof Grobelny         }
198069771cSKrzysztof Grobelny 
advanceClockFake::InternalClock20*51f0fd50SKrzysztof Grobelny         void advance(Milliseconds delta) noexcept
218069771cSKrzysztof Grobelny         {
22*51f0fd50SKrzysztof Grobelny             now += delta;
238069771cSKrzysztof Grobelny         }
248069771cSKrzysztof Grobelny 
setClockFake::InternalClock258069771cSKrzysztof Grobelny         void set(Milliseconds timeSinceEpoch) noexcept
268069771cSKrzysztof Grobelny         {
27*51f0fd50SKrzysztof Grobelny             now = time_point{timeSinceEpoch};
288069771cSKrzysztof Grobelny         }
298069771cSKrzysztof Grobelny 
resetClockFake::InternalClock30*51f0fd50SKrzysztof Grobelny         void reset() noexcept
317e098e93SLukasz Kazmierczak         {
32*51f0fd50SKrzysztof Grobelny             now = time_point{Milliseconds{0u}};
338069771cSKrzysztof Grobelny         }
348069771cSKrzysztof Grobelny 
358069771cSKrzysztof Grobelny       private:
36*51f0fd50SKrzysztof Grobelny         time_point now = clock::now();
37*51f0fd50SKrzysztof Grobelny     };
38*51f0fd50SKrzysztof Grobelny 
39*51f0fd50SKrzysztof Grobelny     template <class TimePoint>
toTimestamp(TimePoint tp)40*51f0fd50SKrzysztof Grobelny     static Milliseconds toTimestamp(TimePoint tp)
41*51f0fd50SKrzysztof Grobelny     {
42*51f0fd50SKrzysztof Grobelny         return std::chrono::time_point_cast<Milliseconds>(tp)
43*51f0fd50SKrzysztof Grobelny             .time_since_epoch();
44*51f0fd50SKrzysztof Grobelny     }
45*51f0fd50SKrzysztof Grobelny 
steadyTimestamp() const46*51f0fd50SKrzysztof Grobelny     Milliseconds steadyTimestamp() const noexcept override
47*51f0fd50SKrzysztof Grobelny     {
48*51f0fd50SKrzysztof Grobelny         return steady.timestamp();
49*51f0fd50SKrzysztof Grobelny     }
50*51f0fd50SKrzysztof Grobelny 
systemTimestamp() const51*51f0fd50SKrzysztof Grobelny     Milliseconds systemTimestamp() const noexcept override
52*51f0fd50SKrzysztof Grobelny     {
53*51f0fd50SKrzysztof Grobelny         return system.timestamp();
54*51f0fd50SKrzysztof Grobelny     }
55*51f0fd50SKrzysztof Grobelny 
advance(Milliseconds delta)56*51f0fd50SKrzysztof Grobelny     void advance(Milliseconds delta) noexcept
57*51f0fd50SKrzysztof Grobelny     {
58*51f0fd50SKrzysztof Grobelny         steady.advance(delta);
59*51f0fd50SKrzysztof Grobelny         system.advance(delta);
60*51f0fd50SKrzysztof Grobelny     }
61*51f0fd50SKrzysztof Grobelny 
62*51f0fd50SKrzysztof Grobelny     InternalClock<std::chrono::steady_clock> steady;
63*51f0fd50SKrzysztof Grobelny     InternalClock<std::chrono::system_clock> system;
648069771cSKrzysztof Grobelny };
65