libdonut  2.3.2
Application framework for cross-platform game development in C++20
Time.hpp
Go to the documentation of this file.
1 #ifndef DONUT_TIME_HPP
2 #define DONUT_TIME_HPP
3 
4 #include <donut/math.hpp>
5 
6 #include <chrono> // std::chrono::...
7 #include <cstddef> // std::size_t
8 #include <fmt/format.h> // fmt::formatter, fmt::format_to
9 #include <ratio> // std::ratio
10 
11 namespace donut {
12 
22 template <typename T, typename Period = std::ratio<1>>
23 class Time {
24 public:
28  using Duration = std::chrono::duration<T, Period>;
29 
33  constexpr Time() noexcept = default;
34 
40  constexpr Time(Duration duration) noexcept
41  : duration(duration) {}
42 
48  constexpr Time(std::chrono::seconds seconds) noexcept
49  : duration(duration_cast<Duration>(seconds)) {}
50 
57  constexpr Time(std::chrono::milliseconds milliseconds) noexcept
58  : duration(duration_cast<Duration>(milliseconds)) {}
59 
66  constexpr Time(std::chrono::microseconds microseconds) noexcept
67  : duration(duration_cast<Duration>(microseconds)) {}
68 
75  constexpr Time(std::chrono::nanoseconds nanoseconds) noexcept
76  : duration(duration_cast<Duration>(nanoseconds)) {}
77 
83  constexpr Time(std::chrono::minutes minutes) noexcept
84  : duration(duration_cast<Duration>(minutes)) {}
85 
91  constexpr Time(std::chrono::hours hours) noexcept
92  : duration(duration_cast<Duration>(hours)) {}
93 
99  constexpr operator Duration() const noexcept {
100  return duration;
101  }
102 
108  constexpr operator T() const noexcept {
109  return duration.count();
110  }
111 
121  [[nodiscard]] friend constexpr bool operator==(const Time& a, const Time& b) noexcept {
122  return a.duration == b.duration;
123  }
124 
134  [[nodiscard]] friend constexpr bool operator!=(const Time& a, const Time& b) noexcept {
135  return a.duration != b.duration;
136  }
137 
147  [[nodiscard]] friend constexpr bool operator<(const Time& a, const Time& b) noexcept {
148  return a.duration < b.duration;
149  }
150 
160  [[nodiscard]] friend constexpr bool operator<=(const Time& a, const Time& b) noexcept {
161  return a.duration <= b.duration;
162  }
163 
173  [[nodiscard]] friend constexpr bool operator>(const Time& a, const Time& b) noexcept {
174  return a.duration > b.duration;
175  }
176 
186  [[nodiscard]] friend constexpr bool operator>=(const Time& a, const Time& b) noexcept {
187  return a.duration >= b.duration;
188  }
189 
197  constexpr Time& operator+=(Time deltaTime) noexcept {
198  duration += deltaTime;
199  return *this;
200  }
201 
209  constexpr Time& operator-=(Time deltaTime) noexcept {
210  duration -= deltaTime;
211  return *this;
212  }
213 
221  friend constexpr Time operator+(Time a) noexcept {
222  return Time{+a.duration};
223  }
224 
232  friend constexpr Time operator-(Time a) noexcept {
233  return Time{-a.duration};
234  }
235 
244  friend constexpr Time operator+(Time a, Time b) noexcept {
245  a += b;
246  return a;
247  }
248 
257  friend constexpr Time operator-(Time a, Time b) noexcept {
258  a -= b;
259  return a;
260  }
261 
278  constexpr bool countDown(Time deltaTime, Time targetTime = Duration{}) noexcept {
279  duration -= deltaTime;
280  if (duration <= targetTime) {
281  duration = targetTime;
282  return true;
283  }
284  return false;
285  }
286 
303  constexpr bool countUp(Time deltaTime, Time targetTime) noexcept {
304  duration += deltaTime;
305  if (duration >= targetTime) {
306  duration = targetTime;
307  return true;
308  }
309  return false;
310  }
311 
330  [[nodiscard]] constexpr std::size_t countDownLoop(Time deltaTime, Time interval) noexcept {
331  if (interval <= Time{}) {
332  duration = Time{};
333  return 1;
334  }
335  std::size_t ticks = 0;
336  duration -= deltaTime;
337  while (duration <= Time{}) {
338  duration += interval;
339  ++ticks;
340  }
341  return ticks;
342  }
343 
362  [[nodiscard]] constexpr std::size_t countUpLoop(Time deltaTime, Time interval) noexcept {
363  if (interval <= Time{}) {
364  duration = Time{};
365  return 1;
366  }
367  std::size_t ticks = 0;
368  duration += deltaTime;
369  while (duration >= interval) {
370  duration -= interval;
371  ++ticks;
372  }
373  return ticks;
374  }
375 
408  [[nodiscard]] constexpr std::size_t countDownLoop(Time deltaTime, Time interval, bool active) noexcept {
409  if (active) {
410  return countDownLoop(deltaTime, interval);
411  }
412  countDown(deltaTime);
413  return 0;
414  }
415 
445  [[nodiscard]] constexpr std::size_t countUpLoop(Time deltaTime, Time interval, bool active) noexcept {
446  if (active) {
447  return countUpLoop(deltaTime, interval);
448  }
449  *this = Time{};
450  return 0;
451  }
452 
453 private:
454  Duration duration{};
455 };
456 
457 template <typename T, typename Period>
458 [[nodiscard]] constexpr Time<T, Period> operator*(Time<T, Period> a, T b) noexcept {
459  return static_cast<typename Time<T, Period>::Duration>(a) * b;
460 }
461 
462 template <typename T, typename Period>
463 [[nodiscard]] constexpr Time<T, Period> operator*(T a, Time<T, Period> b) noexcept {
464  return a * static_cast<typename Time<T, Period>::Duration>(b);
465 }
466 
467 template <typename T, typename Period>
468 [[nodiscard]] constexpr Time<T, Period> operator/(Time<T, Period> a, T b) noexcept {
469  return static_cast<typename Time<T, Period>::Duration>(a) / b;
470 }
471 
472 template <length_t L, typename T, typename Period>
473 [[nodiscard]] constexpr vec<L, T> operator*(vec<L, T> a, Time<T, Period> b) noexcept {
474  return a * static_cast<T>(b);
475 }
476 
477 template <length_t L, typename T, typename Period>
478 [[nodiscard]] constexpr vec<L, T> operator*(Time<T, Period> a, vec<L, T> b) noexcept {
479  return static_cast<T>(a) * b;
480 }
481 
482 template <length_t L, typename T, typename Period>
483 [[nodiscard]] constexpr vec<L, T> operator/(vec<L, T> a, Time<T, Period> b) noexcept {
484  return a / static_cast<T>(b);
485 }
486 
487 template <length_t L, typename T, typename Period>
488 [[nodiscard]] constexpr vec<L, T> operator/(Time<T, Period> a, vec<L, T> b) noexcept {
489  return static_cast<T>(a) / b;
490 }
491 
492 } // namespace donut
493 
494 template <typename T, typename Period, typename CharT>
495 struct fmt::formatter<donut::Time<T, Period>, CharT> {
496  constexpr auto parse(auto& pc) {
497  return pc.begin();
498  }
499 
500  auto format(const donut::Time<T, Period>& time, auto& fc) const {
501  return fmt::format_to(fc.out(), "{}", static_cast<typename donut::Time<T, Period>::Duration>(time));
502  }
503 };
504 
505 #endif
Time duration value wrapper.
Definition: Time.hpp:23
constexpr Time(std::chrono::hours hours) noexcept
Construct a time value from a number of hours.
Definition: Time.hpp:91
constexpr Time() noexcept=default
Construct a time value of 0.
constexpr friend Time operator+(Time a) noexcept
Get the additive identity of a time value.
Definition: Time.hpp:221
constexpr friend bool operator<(const Time &a, const Time &b) noexcept
Check if a time value is less than another time value.
Definition: Time.hpp:147
constexpr friend bool operator>(const Time &a, const Time &b) noexcept
Check if a time value is greater than another time value.
Definition: Time.hpp:173
constexpr friend Time operator-(Time a, Time b) noexcept
Subtract a time value from another.
Definition: Time.hpp:257
constexpr Time(std::chrono::milliseconds milliseconds) noexcept
Construct a time value from a number of milliseconds.
Definition: Time.hpp:57
constexpr bool countUp(Time deltaTime, Time targetTime) noexcept
Add time to this value and then check if it reached a given target time value.
Definition: Time.hpp:303
constexpr std::size_t countDownLoop(Time deltaTime, Time interval, bool active) noexcept
Update a countdown loop with a boolean trigger that determines whether the loop is active or not.
Definition: Time.hpp:408
constexpr friend bool operator!=(const Time &a, const Time &b) noexcept
Compare two time values for inequality.
Definition: Time.hpp:134
std::chrono::duration< T, Period > Duration
Underlying duration type.
Definition: Time.hpp:28
constexpr Time(std::chrono::minutes minutes) noexcept
Construct a time value from a number of minutes.
Definition: Time.hpp:83
constexpr bool countDown(Time deltaTime, Time targetTime=Duration{}) noexcept
Subtract time from this value and then check if it reached a given target time value.
Definition: Time.hpp:278
constexpr Time & operator-=(Time deltaTime) noexcept
Subtract time from this time value.
Definition: Time.hpp:209
constexpr friend Time operator+(Time a, Time b) noexcept
Add two time values.
Definition: Time.hpp:244
constexpr friend bool operator<=(const Time &a, const Time &b) noexcept
Check if a time value is less than or equal to another time value.
Definition: Time.hpp:160
constexpr friend bool operator>=(const Time &a, const Time &b) noexcept
Check if a time value is greater than or equal to another time value.
Definition: Time.hpp:186
constexpr friend bool operator==(const Time &a, const Time &b) noexcept
Compare two time values for equality.
Definition: Time.hpp:121
constexpr std::size_t countUpLoop(Time deltaTime, Time interval) noexcept
Add time to this value and then check how many times it reached a given time interval while looping b...
Definition: Time.hpp:362
constexpr std::size_t countDownLoop(Time deltaTime, Time interval) noexcept
Subtract time from this value and then check how many times it reached 0 while looping back to a give...
Definition: Time.hpp:330
constexpr std::size_t countUpLoop(Time deltaTime, Time interval, bool active) noexcept
Update a countup loop with a boolean trigger that determines whether the loop is active or not.
Definition: Time.hpp:445
constexpr Time & operator+=(Time deltaTime) noexcept
Add time to this time value.
Definition: Time.hpp:197
constexpr Time(std::chrono::seconds seconds) noexcept
Construct a time value from a number of seconds.
Definition: Time.hpp:48
constexpr Time(std::chrono::microseconds microseconds) noexcept
Construct a time value from a number of microseconds.
Definition: Time.hpp:66
constexpr friend Time operator-(Time a) noexcept
Get the additive inverse of a time value.
Definition: Time.hpp:232
constexpr Time(std::chrono::nanoseconds nanoseconds) noexcept
Construct a time value from a number of nanoseconds.
Definition: Time.hpp:75
Definition: Application.hpp:9
constexpr Time< T, Period > operator*(Time< T, Period > a, T b) noexcept
Definition: Time.hpp:458
constexpr Time< T, Period > operator/(Time< T, Period > a, T b) noexcept
Definition: Time.hpp:468
constexpr auto parse(auto &pc)
Definition: Time.hpp:496
auto format(const donut::Time< T, Period > &time, auto &fc) const
Definition: Time.hpp:500