EtcPal  HEAD (unstable)
ETC Platform Abstraction Layer (EtcPal)
View other versions:
timer.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2022 ETC Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************
16  * This file is a part of EtcPal. For more information, go to:
17  * https://github.com/ETCLabs/EtcPal
18  ******************************************************************************/
19 
22 
23 #ifndef ETCPAL_CPP_TIMER_H_
24 #define ETCPAL_CPP_TIMER_H_
25 
26 #include <algorithm>
27 #include <chrono>
28 #include <limits>
29 #include <sstream>
30 #include <string>
31 #include "etcpal/timer.h"
32 #include "etcpal/cpp/common.h"
33 
34 namespace etcpal
35 {
52 
59 inline std::string DurationToString(int32_t duration_ms) noexcept
60 {
61  std::stringstream res;
62 
63  std::chrono::milliseconds milliseconds{std::abs(duration_ms)};
64 
65  auto seconds = std::chrono::duration_cast<std::chrono::seconds>(milliseconds);
66  milliseconds -= std::chrono::duration_cast<std::chrono::milliseconds>(seconds);
67  auto minutes = std::chrono::duration_cast<std::chrono::minutes>(seconds);
68  seconds -= std::chrono::duration_cast<std::chrono::seconds>(minutes);
69  auto hours = std::chrono::duration_cast<std::chrono::hours>(minutes);
70  minutes -= std::chrono::duration_cast<std::chrono::minutes>(hours);
71 
72  if (duration_ms < 0)
73  res << "-";
74  if (hours > std::chrono::hours{0})
75  res << hours.count() << " hr ";
76  if (minutes > std::chrono::minutes{0})
77  res << minutes.count() << " min ";
78  if (seconds > std::chrono::seconds{0})
79  res << seconds.count() << " sec ";
80 
81  res << milliseconds.count() << " ms";
82 
83  return res.str();
84 }
85 
135 {
136 public:
142  TimePoint() = default;
143  constexpr TimePoint(uint32_t ms);
144 
145  constexpr uint32_t value() const noexcept;
146 
147  ETCPAL_CONSTEXPR_14 TimePoint& operator+=(uint32_t duration) noexcept;
148  ETCPAL_CONSTEXPR_14 TimePoint& operator-=(uint32_t duration) noexcept;
149 
150  static TimePoint Now() noexcept;
151 
152 private:
153  uint32_t ms_{0};
154 };
155 
157 constexpr TimePoint::TimePoint(uint32_t ms) : ms_(ms)
158 {
159 }
160 
162 constexpr uint32_t TimePoint::value() const noexcept
163 {
164  return ms_;
165 }
166 
169 {
170  ms_ += duration;
171  return *this;
172 }
173 
176 {
177  ms_ -= duration;
178  return *this;
179 }
180 
182 inline TimePoint TimePoint::Now() noexcept
183 {
184  return etcpal_getms();
185 }
186 
207 class Timer
208 {
209 public:
211  Timer() = default;
212  // Note: this constructor is not explicit by design, to allow implicit conversions e.g.
213  // etcpal::Timer timer = etcpal_c_function_that_returns_timer();
214  constexpr Timer(const EtcPalTimer& c_timer) noexcept;
215  Timer& operator=(const EtcPalTimer& c_timer) noexcept;
216  explicit Timer(uint32_t interval) noexcept;
217  template <typename Rep, typename Period>
218  explicit Timer(const std::chrono::duration<Rep, Period>& interval) noexcept;
219 
220  constexpr const EtcPalTimer& get() const noexcept;
221  ETCPAL_CONSTEXPR_14 EtcPalTimer& get() noexcept;
222 
223  TimePoint GetStartTime() const noexcept;
224  uint32_t GetInterval() const noexcept;
225  uint32_t GetElapsed() const noexcept;
226  uint32_t GetRemaining() const noexcept;
227  bool IsExpired() const noexcept;
228 
229  void Start(uint32_t interval) noexcept;
230  template <typename Rep, typename Period>
231  void Start(const std::chrono::duration<Rep, Period>& interval) noexcept;
232  void Reset() noexcept;
233 
234 private:
235  EtcPalTimer timer_{};
236 };
237 
239 constexpr Timer::Timer(const EtcPalTimer& c_timer) noexcept : timer_(c_timer)
240 {
241 }
242 
244 inline Timer& Timer::operator=(const EtcPalTimer& c_timer) noexcept
245 {
246  timer_ = c_timer;
247  return *this;
248 }
249 
251 inline Timer::Timer(uint32_t interval) noexcept
252 {
253  Start(interval);
254 }
255 
259 template <typename Rep, typename Period>
260 Timer::Timer(const std::chrono::duration<Rep, Period>& interval) noexcept
261 {
262  Start(interval);
263 }
264 
266 constexpr const EtcPalTimer& Timer::get() const noexcept
267 {
268  return timer_;
269 }
270 
273 {
274  return timer_;
275 }
276 
278 inline TimePoint Timer::GetStartTime() const noexcept
279 {
280  return timer_.reset_time;
281 }
282 
284 inline uint32_t Timer::GetInterval() const noexcept
285 {
286  return timer_.interval;
287 }
288 
290 inline uint32_t Timer::GetElapsed() const noexcept
291 {
292  return etcpal_timer_elapsed(&timer_);
293 }
294 
296 inline uint32_t Timer::GetRemaining() const noexcept
297 {
298  return etcpal_timer_remaining(&timer_);
299 }
300 
302 inline bool Timer::IsExpired() const noexcept
303 {
304  return etcpal_timer_is_expired(&timer_);
305 }
306 
310 inline void Timer::Start(uint32_t interval) noexcept
311 {
312  etcpal_timer_start(&timer_, interval);
313 }
314 
318 template <typename Rep, typename Period>
319 void Timer::Start(const std::chrono::duration<Rep, Period>& interval) noexcept
320 {
321  uint32_t interval_clamped = static_cast<uint32_t>(
322  std::min(std::chrono::milliseconds(interval).count(),
323  static_cast<std::chrono::milliseconds::rep>(std::numeric_limits<uint32_t>::max())));
324  etcpal_timer_start(&timer_, interval_clamped);
325 }
326 
328 inline void Timer::Reset() noexcept
329 {
330  etcpal_timer_reset(&timer_);
331 }
332 
335 
339 constexpr int32_t operator-(const TimePoint& a, const TimePoint& b) noexcept
340 {
341  return static_cast<int32_t>(a.value() - b.value());
342 }
343 
344 constexpr bool operator==(const TimePoint& a, const TimePoint& b) noexcept
345 {
346  return (a.value() == b.value());
347 }
348 
349 constexpr bool operator!=(const TimePoint& a, const TimePoint& b) noexcept
350 {
351  return !(a == b);
352 }
353 
354 constexpr bool operator<(const TimePoint& a, const TimePoint& b) noexcept
355 {
356  return (a - b) < 0;
357 }
358 
359 constexpr bool operator>(const TimePoint& a, const TimePoint& b) noexcept
360 {
361  return b < a;
362 }
363 
364 constexpr bool operator<=(const TimePoint& a, const TimePoint& b) noexcept
365 {
366  return !(b < a);
367 }
368 
369 constexpr bool operator>=(const TimePoint& a, const TimePoint& b) noexcept
370 {
371  return !(a < b);
372 }
373 
376 
377 }; // namespace etcpal
378 
379 #endif // ETCPAL_CPP_TIMER_H_
Represents a point in time.
Definition: timer.h:135
ETCPAL_CONSTEXPR_14 TimePoint & operator-=(uint32_t duration) noexcept
Subtract a millisecond duration from a TimePoint.
Definition: timer.h:175
constexpr uint32_t value() const noexcept
Get the raw millisecond value from a TimePoint.
Definition: timer.h:162
ETCPAL_CONSTEXPR_14 TimePoint & operator+=(uint32_t duration) noexcept
Add a millisecond duration to a TimePoint.
Definition: timer.h:168
TimePoint()=default
Construct a TimePoint with a value of 0 by default.
static TimePoint Now() noexcept
Get a TimePoint representing the current time.
Definition: timer.h:182
A wrapper class for the EtcPal timer type.
Definition: timer.h:208
Timer()=default
Creates an expired timer with an interval of 0.
TimePoint GetStartTime() const noexcept
Get the time when this timer was started or reset.
Definition: timer.h:278
bool IsExpired() const noexcept
Whether the timer's interval is expired.
Definition: timer.h:302
Timer & operator=(const EtcPalTimer &c_timer) noexcept
Assign an instance of the C EtcPalTimer type to an instance of this class.
Definition: timer.h:244
void Reset() noexcept
Reset the timer while keeping the same interval.
Definition: timer.h:328
constexpr const EtcPalTimer & get() const noexcept
Get a const reference to the underlying C type.
Definition: timer.h:266
uint32_t GetElapsed() const noexcept
Get the time since the timer was reset.
Definition: timer.h:290
uint32_t GetInterval() const noexcept
Get the current interval being timed by the timer.
Definition: timer.h:284
void Start(uint32_t interval) noexcept
Start the timer with a new interval.
Definition: timer.h:310
uint32_t GetRemaining() const noexcept
Get the amount of time remaining in the timer's interval (returns 0 if the timer is expired).
Definition: timer.h:296
Common definitions used by EtcPal C++ wrappers.
std::string DurationToString(int32_t duration_ms) noexcept
Get a string represention of a millisecond duration.
Definition: timer.h:59
#define ETCPAL_CONSTEXPR_14
Stand-in for "constexpr" on entities that can only be defined "constexpr" in C++14 or later.
Definition: common.h:53
#define ETCPAL_CONSTEXPR_14_OR_INLINE
Defined to "constexpr" in C++14 or later, "inline" earlier.
Definition: common.h:54
uint32_t etcpal_timer_elapsed(const EtcPalTimer *timer)
Get the time since a timer was reset.
Definition: timer.c:56
void etcpal_timer_start(EtcPalTimer *timer, uint32_t interval)
Start a timer.
Definition: timer.c:30
uint32_t etcpal_timer_remaining(const EtcPalTimer *timer)
Get the amount of time remaining in a timer.
Definition: timer.c:87
bool etcpal_timer_is_expired(const EtcPalTimer *timer)
Check to see if a timer is expired.
Definition: timer.c:73
uint32_t etcpal_getms(void)
Get a monotonically-increasing millisecond value.
void etcpal_timer_reset(EtcPalTimer *timer)
Reset a timer while keeping the same interval.
Definition: timer.c:43
A millisecond-resolution timer.
Definition: timer.h:102
uint32_t reset_time
The time at which this timer was reset.
Definition: timer.h:103
uint32_t interval
This timer's timeout interval.
Definition: timer.h:104