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

summaryrefslogtreecommitdiff
path: root/source/core/StarTime.hpp
blob: c230a5cfb9fe3692797ceb062ae05ad58a7da903 (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#pragma once

#include "StarThread.hpp"

namespace Star {

STAR_CLASS(Clock);
STAR_CLASS(Timer);

namespace Time {
  double timeSinceEpoch();
  int64_t millisecondsSinceEpoch();

  double monotonicTime();
  int64_t monotonicMilliseconds();
  int64_t monotonicMicroseconds();

  // Pretty print a duration of time (In days, hours, minutes, seconds, and milliseconds)
  String printDuration(double time);

  // Pretty print a given date and time
  String printDateAndTime(int64_t epochTicks, String format = "<year>-<month>-<day> <hours>:<minutes>:<seconds>.<millis>");
  String printCurrentDateAndTime(String format = "<year>-<month>-<day> <hours>:<minutes>:<seconds>.<millis>");

  // Ticks since unix epoch
  int64_t epochTicks();
  // Epoch ticks per second, static throughout application lifetime.
  int64_t epochTickFrequency();

  // Ticks since unspecified time before program start
  int64_t monotonicTicks();
  // Monotonic ticks per second, static throughout application lifetime.
  int64_t monotonicTickFrequency();

  double ticksToSeconds(int64_t ticks, int64_t tickFrequency);
  int64_t ticksToMilliseconds(int64_t ticks, int64_t tickFrequency);
  int64_t ticksToMicroseconds(int64_t ticks, int64_t tickFrequency);
  int64_t secondsToTicks(double seconds, int64_t tickFrequency);
  int64_t millisecondsToTicks(int64_t milliseconds, int64_t tickFrequency);
  int64_t microsecondsToTicks(int64_t microseconds, int64_t tickFrequency);
}

// Keeps track of elapsed real time since a given moment.  Guaranteed
// monotonically increasing and thread safe.
class Clock {
public:
  explicit Clock(bool start = true);

  Clock(Clock const& clock);

  Clock& operator=(Clock const& clock);

  // Resets clock to 0 time
  void reset();

  void stop();
  void start();

  bool running() const;

  double time() const;
  int64_t milliseconds() const;

  // Override actual elapsed time with the given time.
  void setTime(double time);
  void setMilliseconds(int64_t millis);

  // Warp the clock backwards or forwards
  void adjustTime(double timeAdjustment);
  void adjustMilliseconds(int64_t millisAdjustment);

private:
  void updateElapsed() const;

  mutable RecursiveMutex m_mutex;
  mutable int64_t m_elapsedTicks;
  mutable Maybe<int64_t> m_lastTicks;
  bool m_running;
};

// An instance of Clock that counts down a given amount of time
class Timer : private Clock {
public:
  static Timer withTime(double timeLeft, bool start = true);
  static Timer withMilliseconds(int64_t millis, bool start = true);

  // Constructs a stopped timer whose time is up.
  Timer();
  Timer(Timer const& timer);
  Timer& operator=(Timer const& timer);

  // Start the timer with the given time left.
  void restart(double timeLeft);
  void restartWithMilliseconds(int64_t millisecondsLeft);

  // Time remaining on the timer.  If negative is true, will return negative
  // time values after the timer is up, if false it stops at zero.
  double timeLeft(bool negative = false) const;
  int64_t millisecondsLeft(bool negative = false) const;

  // Is the time remaining <= 0.0?
  bool timeUp() const;

  using Clock::stop;
  using Clock::start;
  using Clock::running;
};

}