⏱️ golxzn::os::chrono ⏱️ 1.2.4
Chrono for golxzn's projects.
Loading...
Searching...
No Matches
timer.hpp
Go to the documentation of this file.
1/**
2 * @file golxzn/os/chrono/timer.hpp
3 * @author Ruslan Golovinskii (golxzn@gmail.com)
4 * @brief Timer classes to measure time intervals
5 * @date 2023-10-24
6 *
7 * @copyright Copyright (c) 2023
8 */
9
10#pragma once
11
12#include <thread>
13
15
16namespace golxzn::os::chrono {
17
18namespace constants {
19
20/**
21 * @brief Default precision of timer.
22 * > Only if `GOLXZN_MULTITHREADING` is defined.
23 * This value is used as time to wait inside timer thread.
24 * @code{.cpp}
25 * while(is_running()) {
26 * std::this_thread::sleep_for(default_precision);
27 * }
28 * @endcode
29 */
30static constexpr std::chrono::microseconds default_precision{ i64{ 1 } };
31
32} // namespace constants
33
34/**
35 * @brief Class that represents timer.
36 * @ingroup Chrono timers
37 * @warning This class behaviour is different with and without `GOLXZN_MULTITHREADING` macros definition.
38 * @tparam OnTimerDone type of function that will be called when timer is done.
39 * @tparam BaseClock clock that will be used for measurement. It has to be monotonic and STL compatible.
40 *
41 * This class is used to measure time. It calls callback when it's done.
42 * If `GOLXZN_MULTITHREADING` __is not__ defined it doesn't use a thread.
43 * So to call callback it has to be updated in main thread. It storing callback.
44 * If `GOLXZN_MULTITHREADING` __is__ defined it uses a thread.
45 * So to call callback it doesn't have to be updated. It doesn't storing callback, but std::thread
46 *
47 * Example of using:
48 * @code{.cpp}
49 * std::atomic_bool executed{ false };
50 * golxzn::os::chrono::timer timer2{ 10ms,
51 * std::function<void()>{ [&executed] { executed.store(true); } }
52 * };
53 *
54 * while(!timer2.is_done()) {
55 * std::this_thread::sleep_for(1ms);
56 * }
57 * @endcode
58 */
59template<class OnTimerDone, class BaseClock = utils::default_base_clock>
60class timer {
61 static_assert(BaseClock::is_steady,
62 "[golxzn::os::chrono::timer] BaseClock is not a monotonic clock");
63 static_assert(utils::enough_resolution_v<BaseClock>,
64 "[golxzn::os::chrono::timer] BaseClock's resolution is less than microseconds!");
65 static_assert(std::is_invocable_v<OnTimerDone>,
66 "[golxzn::os::chrono::timer] OnTimerDone is not invocable!");
67
68public:
69 using base_clock = BaseClock; ///< Base clock type
70 using time_point = typename base_clock::time_point; ///< Type of time point from base_clock
71 using timer_end_callback = OnTimerDone; ///< Type of callback that will be called when timer is done
72
73 /**
74 * @brief Timer constructor from timer interval and callback.
75 * @ingroup Chrono timers construction
76 * @details Timer's callback will be called after timer_interval.
77 * @warning There's no invalid function checking! It'll terminate if callback is invalid.
78 * @param timer_interval Timer interval.
79 * @param callback Function that will be called after timer_interval.
80 * @param precision Precision of timer. By default it's 1 microsecond (1us). Only if `GOLXZN_MULTITHREADING` is defined.
81 */
82 template<class Rep, class Period>
83 timer(const std::chrono::duration<Rep, Period> timer_interval, timer_end_callback &&callback
84#if defined(GOLXZN_MULTITHREADING)
85 , const std::chrono::microseconds precision = constants::default_precision
86#endif // defined(GOLXZN_MULTITHREADING)
87 );
88
89 /**
90 * @brief Timer constructor from timer interval and callback.
91 * @ingroup Chrono timers construction
92 * @details Timer's callback will be called after timer_interval.
93 * @warning There's no invalid function checking! It'll terminate if callback is invalid.
94 * @param timer_interval Timer interval.
95 * @param callback Function that will be called after timer_interval.
96 * @param precision Precision of timer. By default it's 1 microsecond (1us). Only if `GOLXZN_MULTITHREADING` is defined.
97 */
98 timer(const time timer_interval, timer_end_callback &&callback
99#if defined(GOLXZN_MULTITHREADING)
100 , const std::chrono::microseconds precision = constants::default_precision
101#endif // defined(GOLXZN_MULTITHREADING)
102 );
103
104#if defined(GOLXZN_MULTITHREADING)
105 ~timer() noexcept;
106#endif // defined(GOLXZN_MULTITHREADING)
107
108#if !defined(GOLXZN_MULTITHREADING)
109 /**
110 * @brief Updates timer. (only when GOLXZN_MULTITHREADING is not defined)
111 * @warning There's no invalid function checking! It'll terminate if callback is invalid.
112 * @details Should be called in main thread. It's not needed if `GOLXZN_MULTITHREADING` is defined.
113 */
114 void update();
115#endif // !defined(GOLXZN_MULTITHREADING)
116
117 /**
118 * @brief Returns true if timer is done.
119 * @see is_running()
120 * @see time_left()
121 */
122 [[nodiscard]] bool is_done() const noexcept;
123
124 /**
125 * @brief Returns true if timer is running.
126 * @see is_done()
127 * @see time_left()
128 */
129 [[nodiscard]] bool is_running() const noexcept;
130
131 /**
132 * @brief Returns time left to the end of the timer.
133 * @see is_running()
134 * @see is_done()
135 */
136 [[nodiscard]] time time_left() const noexcept;
137
138private:
139 const time_point m_start_time{ base_clock::now() };
140 const time_point m_timer_interval;
141
142#if defined(GOLXZN_MULTITHREADING)
143 std::thread m_timer_thread;
144#else // ^^^ defined(GOLXZN_MULTITHREADING) ^^^ / vvv !defined(GOLXZN_MULTITHREADING) vvv
145 timer_end_callback m_callback;
146#endif // !defined(GOLXZN_MULTITHREADING)
147};
148
149/**
150 * @brief Class that represents fast_timer.
151 * @details Compared to golxzn::os::chrono::timer it doesn't use a thread and callback.
152 * @ingroup Chrono timers
153 * @tparam BaseClock clock that will be used for measurement. It has to be monotonic and STL compatible.
154 *
155 * This class is used to measure time. It doesn't use a thread and callback.
156 * It stores only start time and timer interval, which is passing in constructor.
157 * So it's very lightweight. It's just check if the creating time + interval is less than current time.
158 *
159 * Example of using:
160 * @code{.cpp}
161 * golxzn::os::chrono::fast_timer<> timer{ 100ms }
162 * while (timer.is_running()) {
163 * const auto left{ timer.time_left() };
164 * // do something
165 * }
166 * @endcode
167 */
168template<class BaseClock = utils::default_base_clock>
170 static_assert(BaseClock::is_steady,
171 "[golxzn::os::chrono::fast_timer] BaseClock is not a monotonic clock");
172 static_assert(utils::enough_resolution_v<BaseClock>,
173 "[golxzn::os::chrono::fast_timer] BaseClock's resolution is less than microseconds!");
174
175public:
176 using base_clock = BaseClock; ///< Base clock type
177 using time_point = typename base_clock::time_point; ///< Type of time point from base_clock
178
179 /**
180 * @brief fast_timer constructor from timer interval.
181 * @ingroup Chrono timers construction
182 * @param timer_interval Timer interval.
183 * @see constexpr fast_timer(const time timer_interval) noexcept
184 * @see constexpr fast_timer(const std::chrono::duration<Rep, Period> timer_interval) noexcept
185 */
186 explicit constexpr fast_timer(const time timer_interval) noexcept;
187
188 /**
189 * @brief fast_timer constructor from timer interval.
190 * @ingroup Chrono timers construction
191 * @param timer_interval Timer interval.
192 * @see constexpr fast_timer(const time timer_interval) noexcept
193 * @see constexpr fast_timer(const std::chrono::duration<Rep, Period> timer_interval) noexcept
194 */
195 explicit constexpr fast_timer(const time_point timer_interval) noexcept;
196
197 /**
198 * @brief fast_timer constructor from timer interval.
199 * @ingroup Chrono timers construction
200 * @param timer_interval Timer interval.
201 * @see constexpr fast_timer(const time timer_interval)
202 * @see constexpr fast_timer(const time_point timer_interval)
203 */
204 template<class Rep, class Period>
205 explicit constexpr fast_timer(const std::chrono::duration<Rep, Period> timer_interval) noexcept;
206
207 /**
208 * @brief Returns true if timer is done.
209 * @see constexpr bool is_running() const noexcept
210 * @see constexpr time time_left() const noexcept
211 */
212 [[nodiscard]] constexpr bool is_done() const noexcept;
213
214 /**
215 * @brief Returns true if timer is running.
216 * @see constexpr bool is_done() const noexcept
217 * @see constexpr time time_left() const noexcept
218 */
219 [[nodiscard]] constexpr bool is_running() const noexcept;
220
221 /**
222 * @brief Returns time left to the end of the timer.
223 * @see constexpr bool is_running() const noexcept
224 * @see constexpr bool is_done() const noexcept
225 */
226 [[nodiscard]] constexpr time time_left() const noexcept;
227
228private:
229 const time_point m_start_time{ base_clock::now() };
230 const time_point m_timer_interval;
231};
232
233#include "golxzn/os/chrono/impl/timer.inl"
234
235} // namespace golxzn::os::chrono
Class that represents fast_timer.
Definition timer.hpp:169
constexpr fast_timer(const time timer_interval) noexcept
fast_timer constructor from timer interval.
constexpr time time_left() const noexcept
Returns time left to the end of the timer.
constexpr bool is_running() const noexcept
Returns true if timer is running.
constexpr fast_timer(const time_point timer_interval) noexcept
fast_timer constructor from timer interval.
constexpr fast_timer(const std::chrono::duration< Rep, Period > timer_interval) noexcept
fast_timer constructor from timer interval.
BaseClock base_clock
Base clock type.
Definition timer.hpp:176
constexpr bool is_done() const noexcept
Returns true if timer is done.
typename base_clock::time_point time_point
Type of time point from base_clock.
Definition timer.hpp:177
Class that represents time.
Definition time.hpp:30
Class that represents timer.
Definition timer.hpp:60
timer(const time timer_interval, timer_end_callback &&callback)
Timer constructor from timer interval and callback.
BaseClock base_clock
Base clock type.
Definition timer.hpp:69
time time_left() const noexcept
Returns time left to the end of the timer.
bool is_running() const noexcept
Returns true if timer is running.
bool is_done() const noexcept
Returns true if timer is done.
OnTimerDone timer_end_callback
Type of callback that will be called when timer is done.
Definition timer.hpp:71
timer(const std::chrono::duration< Rep, Period > timer_interval, timer_end_callback &&callback)
Timer constructor from timer interval and callback.
typename base_clock::time_point time_point
Type of time point from base_clock.
Definition timer.hpp:70
void update()
Updates timer. (only when GOLXZN_MULTITHREADING is not defined)
Class that represents time.
static constexpr std::chrono::microseconds default_precision
Default precision of timer. ‍Only if GOLXZN_MULTITHREADING is defined. This value is used as time to ...
Definition timer.hpp:30