ge211  2021.5.1
A student game engine
ge211_time.hxx
1 #pragma once
2 
3 #include "ge211_forward.hxx"
4 
5 #include <chrono>
6 #include <ratio>
7 #include <thread>
8 
9 namespace ge211 {
10 
11 namespace detail {
12 
13 using Clock = std::conditional_t<
14  std::chrono::high_resolution_clock::is_steady,
17 
18 } // end namespace detail
19 
21 namespace time {
22 
30 class Duration
31 {
32 public:
34  Duration() : duration_{} {}
35 
37  explicit Duration(double seconds)
39 
41  double seconds() const
42  {
43  auto seconds =
44  std::chrono::duration_cast<std::chrono::duration<double>>(
45  duration_);
46  return seconds.count();
47  }
48 
50  long milliseconds() const
51  {
52  auto millis =
53  std::chrono::duration_cast<std::chrono::duration<long, std::milli>>(
54  duration_);
55  return millis.count();
56  }
57 
60 
62  bool operator==(Duration other) const
63  {
64  return duration_ == other.duration_;
65  }
66 
68  bool operator!=(Duration other) const
69  {
70  return duration_ != other.duration_;
71  }
72 
74  bool operator<(Duration other) const
75  {
76  return duration_ < other.duration_;
77  }
78 
80  bool operator<=(Duration other) const
81  {
82  return duration_ <= other.duration_;
83  }
84 
86  bool operator>(Duration other) const
87  {
88  return duration_ > other.duration_;
89  }
90 
92  bool operator>=(Duration other) const
93  {
94  return duration_ >= other.duration_;
95  }
96 
98 
101 
104  {
105  return {duration_ + other.duration_};
106  }
107 
110  {
111  return {duration_ - other.duration_};
112  }
113 
115  Duration operator*(double factor) const
116  {
117  return {duration_ * factor};
118  }
119 
121  Duration operator/(double factor) const
122  {
123  return {duration_ / factor};
124  }
125 
128  {
129  return *this = *this + other;
130  }
131 
134  {
135  return *this = *this - other;
136  }
137 
139  Duration& operator*=(double factor)
140  {
141  return *this = *this * factor;
142  }
143 
145  Duration& operator/=(double factor)
146  {
147  return *this = *this / factor;
148  }
149 
151 
152 private:
153  friend Time_point;
154  friend class detail::Engine;
155 
157  : Duration{std::chrono::duration_cast<detail::Clock::duration>
158  (duration)} {}
159 
160  Duration(detail::Clock::duration duration)
161  : duration_{duration} {}
162 
163  void sleep_for() const
164  {
165  std::this_thread::sleep_for(duration_);
166  }
167 
168  detail::Clock::duration duration_;
169 };
170 
175 {
176 public:
178  Time_point() : time_point_{} {}
179 
181  static Time_point now() { return Time_point(detail::Clock::now()); }
182 
185 
187  bool operator==(Time_point other) const
188  {
189  return time_point_ == other.time_point_;
190  }
191 
193  bool operator!=(Time_point other) const
194  {
195  return time_point_ != other.time_point_;
196  }
197 
199  bool operator<(Time_point other) const
200  {
201  return time_point_ < other.time_point_;
202  }
203 
205  bool operator<=(Time_point other) const
206  {
207  return time_point_ <= other.time_point_;
208  }
209 
211  bool operator>(Time_point other) const
212  {
213  return time_point_ > other.time_point_;
214  }
215 
217  bool operator>=(Time_point other) const
218  {
219  return time_point_ >= other.time_point_;
220  }
221 
223 
226 
229  {
230  return Duration{time_point_ - other.time_point_};
231  }
232 
234  Time_point operator+(Duration duration) const
235  {
236  return Time_point{time_point_ + duration.duration_};
237  }
238 
240  Time_point operator-(Duration duration) const
241  {
242  return Time_point{time_point_ - duration.duration_};
243  }
244 
247  {
248  return *this = *this + duration;
249  }
250 
253  {
254  return *this = *this - duration;
255  }
256 
258 
259 private:
260  Time_point(detail::Clock::time_point time_point)
261  : time_point_{time_point} {}
262 
263  detail::Clock::time_point time_point_;
264 };
265 
267 class Timer
268 {
269 public:
271  Timer() : start_time_{now_()} {}
272 
278  static Timer future(Duration duration)
279  {
280  Timer result;
281  result.start_time_ += duration;
282  return result;
283  }
284 
287  {
288  Time_point previous = start_time_;
289  start_time_ = now_();
290  return start_time_ - previous;
291  }
292 
297  {
298  return start_time_;
299  }
300 
305  {
306  return now_() - start_time_;
307  }
308 
309 private:
310  Time_point start_time_;
311 
312  static Time_point now_() { return Time_point::now(); }
313 };
314 
317 {
318 public:
321  explicit Pausable_timer(bool start_paused = false)
322  {
323  is_paused_ = start_paused;
324 
325  if (is_paused_)
326  elapsed_time_ = Duration{};
327  else
328  fake_start_time_ = now_();
329  }
330 
332  bool is_paused() const
333  {
334  return is_paused_;
335  }
336 
341  {
342  if (is_paused_) {
343  return elapsed_time_;
344  } else {
345  return now_() - fake_start_time_;
346  }
347  }
348 
354  {
355  if (!is_paused_) {
356  elapsed_time_ = now_() - fake_start_time_;
357  is_paused_ = true;
358  }
359 
360  return elapsed_time_;
361  }
362 
364  void resume()
365  {
366  if (is_paused_) {
367  fake_start_time_ = now_() - elapsed_time_;
368  is_paused_ = false;
369  }
370  }
371 
375  {
376  if (is_paused_) {
377  auto result = elapsed_time_;
378  elapsed_time_ = Duration{};
379  return result;
380  } else {
381  auto now = now_();
382  auto result = now - fake_start_time_;
383  fake_start_time_ = now;
384  return result;
385  }
386  }
387 
388 private:
389  union
390  {
391  Time_point fake_start_time_; // when not paused
392  Duration elapsed_time_; // when paused
393  };
394  bool is_paused_;
395 
396  static Time_point now_() { return Time_point::now(); }
397 };
398 
399 } // end namespace time
400 
401 }
402 
std::chrono::steady_clock
std::this_thread::sleep_for
T sleep_for(T... args)
ge211::time::Time_point::operator>=
bool operator>=(Time_point other) const
Is this Time_point later than or equal to that one?
Definition: ge211_time.hxx:217
ge211::time::Duration
A length of time.
Definition: ge211_time.hxx:31
ge211::time::Duration::operator/=
Duration & operator/=(double factor)
Division for Duration.
Definition: ge211_time.hxx:145
ge211::time::Timer::elapsed_time
Duration elapsed_time() const
Returns how much time has elapsed since this timer was started or most recently reset.
Definition: ge211_time.hxx:304
ge211::time::Time_point::operator>
bool operator>(Time_point other) const
Is this Time_point later than that one?
Definition: ge211_time.hxx:211
ge211::time::Pausable_timer::resume
void resume()
Unpauses the timer. If the timer is already running, has no effect.
Definition: ge211_time.hxx:364
ge211::time::Time_point::operator+=
Time_point & operator+=(Duration duration)
Offsets a Time_point by adding on a Duration.
Definition: ge211_time.hxx:246
std::chrono::duration
ge211::time::Duration::operator==
bool operator==(Duration other) const
Does this Duration equal another one?
Definition: ge211_time.hxx:62
ge211::time::Duration::seconds
double seconds() const
Gets this duration in seconds.
Definition: ge211_time.hxx:41
ge211::time::Timer::future
static Timer future(Duration duration)
Creates a timer whose “start time” is some Duration in the future.
Definition: ge211_time.hxx:278
ge211::time::Time_point
A point in time.
Definition: ge211_time.hxx:175
ge211::time::Timer::reset
Duration reset()
Resets a timer, returning the time it was at before it was reset.
Definition: ge211_time.hxx:286
ge211::time::Time_point::operator==
bool operator==(Time_point other) const
Equality for Time_point.
Definition: ge211_time.hxx:187
ge211::time::Duration::milliseconds
long milliseconds() const
Gets this duration, approximately, in milliseconds.
Definition: ge211_time.hxx:50
ge211::time::Time_point::operator-
Duration operator-(Time_point other) const
Finds the Duration between one Time_point and another.
Definition: ge211_time.hxx:228
std::chrono::high_resolution_clock
ge211
The game engine namespace.
Definition: ge211.hxx:4
ge211::time::Duration::operator<=
bool operator<=(Duration other) const
Less-than-or-equal-to for Duration.
Definition: ge211_time.hxx:80
ge211::time::Pausable_timer::is_paused
bool is_paused() const
Checks whether the timer is currently paused.
Definition: ge211_time.hxx:332
ge211::time::Pausable_timer::pause
Duration pause()
Pauses the timer.
Definition: ge211_time.hxx:353
ge211::time::Duration::operator+=
Duration & operator+=(Duration other)
Addition for Duration.
Definition: ge211_time.hxx:127
ge211::time::Duration::operator<
bool operator<(Duration other) const
Less-than for Duration.
Definition: ge211_time.hxx:74
ge211::time::Time_point::operator-
Time_point operator-(Duration duration) const
Offsets a Time_point subtracting by a Duration.
Definition: ge211_time.hxx:240
ge211::time::Duration::operator>
bool operator>(Duration other) const
Greater-than for Duration.
Definition: ge211_time.hxx:86
ge211::time::Duration::Duration
Duration()
Constructs the zero duration.
Definition: ge211_time.hxx:34
ge211::time::Timer::Timer
Timer()
Creates a new timer, running from the time it was created.
Definition: ge211_time.hxx:271
ge211::time::Duration::operator/
Duration operator/(double factor) const
Division for Duration.
Definition: ge211_time.hxx:121
ge211::time::Pausable_timer
A class for timing intervals while supporting pausing.
Definition: ge211_time.hxx:317
ge211::time::Timer
A class for timing intervals. The result is a Duration.
Definition: ge211_time.hxx:268
ge211::time::Time_point::operator<
bool operator<(Time_point other) const
Is this Time_point earlier than that one?
Definition: ge211_time.hxx:199
ge211::time::Time_point::operator<=
bool operator<=(Time_point other) const
Is this Time_point earlier than or equal to that one?
Definition: ge211_time.hxx:205
ge211::time::Duration::operator*
Duration operator*(double factor) const
Multiplication for Duration.
Definition: ge211_time.hxx:115
ge211::time::Time_point::operator!=
bool operator!=(Time_point other) const
Disequality for Time_point.
Definition: ge211_time.hxx:193
ge211::time::Time_point::Time_point
Time_point()
Constructs the zero time point (the epoch).
Definition: ge211_time.hxx:178
ge211::time::Pausable_timer::elapsed_time
Duration elapsed_time() const
The elapsed time since the start or most recent reset, not counting paused times.
Definition: ge211_time.hxx:340
ge211::time::Pausable_timer::reset
Duration reset()
Resets the timer, returning the elapsed time since starting or the most recent reset().
Definition: ge211_time.hxx:374
ge211::time::Time_point::now
static Time_point now()
Returns the current time.
Definition: ge211_time.hxx:181
ge211::time::Time_point::operator+
Time_point operator+(Duration duration) const
Offsets a Time_point by adding a Duration.
Definition: ge211_time.hxx:234
ge211::time::Time_point::operator-=
Time_point & operator-=(Duration duration)
Offsets a Time_point subtracting off a Duration.
Definition: ge211_time.hxx:252
ge211::time::Timer::start_time
Time_point start_time() const
Returns the actual time when this timer was started or most recently reset.
Definition: ge211_time.hxx:296
std::time
T time(T... args)
ge211::time::Duration::operator!=
bool operator!=(Duration other) const
Does this Duration NOT equal another one?
Definition: ge211_time.hxx:68
ge211::time::Duration::operator*=
Duration & operator*=(double factor)
Multiplication for Duration.
Definition: ge211_time.hxx:139
ge211::time::Duration::operator-
Duration operator-(Duration other) const
Subtraction for Duration.
Definition: ge211_time.hxx:109
ge211::time::Duration::operator+
Duration operator+(Duration other) const
Addition for Duration.
Definition: ge211_time.hxx:103
ge211::time::Pausable_timer::Pausable_timer
Pausable_timer(bool start_paused=false)
Constructs a new pausable timer.
Definition: ge211_time.hxx:321
ge211::time::Duration::Duration
Duration(double seconds)
Constructs the duration of the given number of seconds.
Definition: ge211_time.hxx:37
ge211::time::Duration::operator-=
Duration & operator-=(Duration other)
Subtraction for Duration.
Definition: ge211_time.hxx:133
ge211::time::Duration::operator>=
bool operator>=(Duration other) const
Greater-than-or-equal-to for Duration.
Definition: ge211_time.hxx:92