henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 11 | #ifndef API_NETEQ_TICK_TIMER_H_ |
| 12 | #define API_NETEQ_TICK_TIMER_H_ |
henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 13 | |
Yves Gerey | 988cc08 | 2018-10-23 12:03:01 +0200 | [diff] [blame] | 14 | #include <stdint.h> |
Jonas Olsson | a4d8737 | 2019-07-05 19:08:33 +0200 | [diff] [blame] | 15 | |
henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 16 | #include <memory> |
| 17 | |
Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 18 | #include "rtc_base/checks.h" |
henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 19 | |
| 20 | namespace webrtc { |
| 21 | |
| 22 | // Implements a time counter. The counter is advanced with the Increment() |
| 23 | // methods, and is queried with the ticks() accessor. It is assumed that one |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 24 | // "tick" of the counter corresponds to 10 ms. |
henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 25 | // A TickTimer object can provide two types of associated time-measuring |
| 26 | // objects: Stopwatch and Countdown. |
| 27 | class TickTimer { |
| 28 | public: |
| 29 | // Stopwatch measures time elapsed since it was started, by querying the |
| 30 | // associated TickTimer for the current time. The intended use is to request a |
| 31 | // new Stopwatch object from a TickTimer object with the GetNewStopwatch() |
| 32 | // method. Note: since the Stopwatch object contains a reference to the |
| 33 | // TickTimer it is associated with, it cannot outlive the TickTimer. |
| 34 | class Stopwatch { |
| 35 | public: |
| 36 | explicit Stopwatch(const TickTimer& ticktimer); |
| 37 | |
| 38 | uint64_t ElapsedTicks() const { return ticktimer_.ticks() - starttick_; } |
| 39 | |
| 40 | uint64_t ElapsedMs() const { |
| 41 | const uint64_t elapsed_ticks = ticktimer_.ticks() - starttick_; |
| 42 | const int ms_per_tick = ticktimer_.ms_per_tick(); |
| 43 | return elapsed_ticks < UINT64_MAX / ms_per_tick |
| 44 | ? elapsed_ticks * ms_per_tick |
| 45 | : UINT64_MAX; |
| 46 | } |
| 47 | |
| 48 | private: |
| 49 | const TickTimer& ticktimer_; |
| 50 | const uint64_t starttick_; |
| 51 | }; |
| 52 | |
| 53 | // Countdown counts down from a given start value with each tick of the |
| 54 | // associated TickTimer, until zero is reached. The Finished() method will |
| 55 | // return true if zero has been reached, false otherwise. The intended use is |
| 56 | // to request a new Countdown object from a TickTimer object with the |
| 57 | // GetNewCountdown() method. Note: since the Countdown object contains a |
| 58 | // reference to the TickTimer it is associated with, it cannot outlive the |
| 59 | // TickTimer. |
| 60 | class Countdown { |
| 61 | public: |
| 62 | Countdown(const TickTimer& ticktimer, uint64_t ticks_to_count); |
| 63 | |
| 64 | ~Countdown(); |
| 65 | |
| 66 | bool Finished() const { |
| 67 | return stopwatch_->ElapsedTicks() >= ticks_to_count_; |
| 68 | } |
| 69 | |
| 70 | private: |
| 71 | const std::unique_ptr<Stopwatch> stopwatch_; |
| 72 | const uint64_t ticks_to_count_; |
| 73 | }; |
| 74 | |
| 75 | TickTimer() : TickTimer(10) {} |
| 76 | explicit TickTimer(int ms_per_tick) : ms_per_tick_(ms_per_tick) { |
| 77 | RTC_DCHECK_GT(ms_per_tick_, 0); |
| 78 | } |
| 79 | |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 80 | TickTimer(const TickTimer&) = delete; |
| 81 | TickTimer& operator=(const TickTimer&) = delete; |
| 82 | |
henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 83 | void Increment() { ++ticks_; } |
| 84 | |
| 85 | // Mainly intended for testing. |
| 86 | void Increment(uint64_t x) { ticks_ += x; } |
| 87 | |
| 88 | uint64_t ticks() const { return ticks_; } |
| 89 | |
| 90 | int ms_per_tick() const { return ms_per_tick_; } |
| 91 | |
| 92 | // Returns a new Stopwatch object, based on the current TickTimer. Note that |
| 93 | // the new Stopwatch object contains a reference to the current TickTimer, |
| 94 | // and must therefore not outlive the TickTimer. |
| 95 | std::unique_ptr<Stopwatch> GetNewStopwatch() const { |
| 96 | return std::unique_ptr<Stopwatch>(new Stopwatch(*this)); |
| 97 | } |
| 98 | |
| 99 | // Returns a new Countdown object, based on the current TickTimer. Note that |
| 100 | // the new Countdown object contains a reference to the current TickTimer, |
| 101 | // and must therefore not outlive the TickTimer. |
| 102 | std::unique_ptr<Countdown> GetNewCountdown(uint64_t ticks_to_count) const { |
| 103 | return std::unique_ptr<Countdown>(new Countdown(*this, ticks_to_count)); |
| 104 | } |
| 105 | |
| 106 | private: |
| 107 | uint64_t ticks_ = 0; |
| 108 | const int ms_per_tick_; |
henrik.lundin | 8053f79 | 2016-04-22 13:21:43 -0700 | [diff] [blame] | 109 | }; |
| 110 | |
| 111 | } // namespace webrtc |
Ivo Creusen | 3ce44a3 | 2019-10-31 14:38:11 +0100 | [diff] [blame] | 112 | #endif // API_NETEQ_TICK_TIMER_H_ |