bones_framework/time/
stopwatch.rs

1use std::time::Duration;
2
3/// A Stopwatch is a struct that track elapsed time when started.
4///
5/// # Examples
6///
7/// ```no_run
8/// # use bones_framework::prelude::*;
9/// use std::time::Duration;
10/// let mut stopwatch = Stopwatch::new();
11/// assert_eq!(stopwatch.elapsed_secs(), 0.0);
12///
13/// stopwatch.tick(Duration::from_secs_f32(1.0)); // tick one second
14/// assert_eq!(stopwatch.elapsed_secs(), 1.0);
15///
16/// stopwatch.pause();
17/// stopwatch.tick(Duration::from_secs_f32(1.0)); // paused stopwatches don't tick
18/// assert_eq!(stopwatch.elapsed_secs(), 1.0);
19///
20/// stopwatch.reset(); // reset the stopwatch
21/// assert!(stopwatch.paused());
22/// assert_eq!(stopwatch.elapsed_secs(), 0.0);
23/// ```
24#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
25pub struct Stopwatch {
26    paused: bool,
27    elapsed: Duration,
28}
29
30impl Stopwatch {
31    /// Create a new unpaused `Stopwatch` with no elapsed time.
32    ///
33    /// # Examples
34    /// ```no_run
35    /// # use bones_framework::prelude::*;
36    /// let stopwatch = Stopwatch::new();
37    /// assert_eq!(stopwatch.elapsed_secs(), 0.0);
38    /// assert_eq!(stopwatch.paused(), false);
39    /// ```
40    pub fn new() -> Self {
41        Default::default()
42    }
43
44    /// Returns the elapsed time since the last [`reset`](Stopwatch::reset)
45    /// of the stopwatch.
46    ///
47    /// # Examples
48    /// ```no_run
49    /// # use bones_framework::prelude::*;
50    /// use std::time::Duration;
51    /// let mut stopwatch = Stopwatch::new();
52    /// stopwatch.tick(Duration::from_secs(1));
53    /// assert_eq!(stopwatch.elapsed(), Duration::from_secs(1));
54    /// ```
55    ///
56    /// # See Also
57    ///
58    /// [`elapsed_secs`](Stopwatch::elapsed_secs) - if an `f32` value is desirable instead.
59    /// [`elapsed_secs_f64`](Stopwatch::elapsed_secs_f64) - if an `f64` is desirable instead.
60    #[inline]
61    pub fn elapsed(&self) -> Duration {
62        self.elapsed
63    }
64
65    /// Returns the elapsed time since the last [`reset`](Stopwatch::reset)
66    /// of the stopwatch, in seconds.
67    ///
68    /// # Examples
69    /// ```no_run
70    /// # use bones_framework::prelude::*;
71    /// use std::time::Duration;
72    /// let mut stopwatch = Stopwatch::new();
73    /// stopwatch.tick(Duration::from_secs(1));
74    /// assert_eq!(stopwatch.elapsed_secs(), 1.0);
75    /// ```
76    ///
77    /// # See Also
78    ///
79    /// [`elapsed`](Stopwatch::elapsed) - if a `Duration` is desirable instead.
80    /// [`elapsed_secs_f64`](Stopwatch::elapsed_secs_f64) - if an `f64` is desirable instead.
81    #[inline]
82    pub fn elapsed_secs(&self) -> f32 {
83        self.elapsed().as_secs_f32()
84    }
85
86    /// Returns the elapsed time since the last [`reset`](Stopwatch::reset)
87    /// of the stopwatch, in seconds, as f64.
88    ///
89    /// # See Also
90    ///
91    /// [`elapsed`](Stopwatch::elapsed) - if a `Duration` is desirable instead.
92    /// [`elapsed_secs`](Stopwatch::elapsed_secs) - if an `f32` is desirable instead.
93    #[inline]
94    pub fn elapsed_secs_f64(&self) -> f64 {
95        self.elapsed().as_secs_f64()
96    }
97
98    /// Sets the elapsed time of the stopwatch.
99    ///
100    /// # Examples
101    /// ```no_run
102    /// # use bones_framework::prelude::*;
103    /// use std::time::Duration;
104    /// let mut stopwatch = Stopwatch::new();
105    /// stopwatch.set_elapsed(Duration::from_secs_f32(1.0));
106    /// assert_eq!(stopwatch.elapsed_secs(), 1.0);
107    /// ```
108    #[inline]
109    pub fn set_elapsed(&mut self, time: Duration) {
110        self.elapsed = time;
111    }
112
113    /// Advance the stopwatch by `delta` seconds.
114    /// If the stopwatch is paused, ticking will not have any effect
115    /// on elapsed time.
116    ///
117    /// # Examples
118    /// ```no_run
119    /// # use bones_framework::prelude::*;
120    /// use std::time::Duration;
121    /// let mut stopwatch = Stopwatch::new();
122    /// stopwatch.tick(Duration::from_secs_f32(1.5));
123    /// assert_eq!(stopwatch.elapsed_secs(), 1.5);
124    /// ```
125    pub fn tick(&mut self, delta: Duration) -> &Self {
126        if !self.paused() {
127            self.elapsed += delta;
128        }
129        self
130    }
131
132    /// Pauses the stopwatch. Any call to [`tick`](Stopwatch::tick) while
133    /// paused will not have any effect on the elapsed time.
134    ///
135    /// # Examples
136    /// ```no_run
137    /// # use bones_framework::prelude::*;
138    /// use std::time::Duration;
139    /// let mut stopwatch = Stopwatch::new();
140    /// stopwatch.pause();
141    /// stopwatch.tick(Duration::from_secs_f32(1.5));
142    /// assert!(stopwatch.paused());
143    /// assert_eq!(stopwatch.elapsed_secs(), 0.0);
144    /// ```
145    #[inline]
146    pub fn pause(&mut self) {
147        self.paused = true;
148    }
149
150    /// Unpauses the stopwatch. Resume the effect of ticking on elapsed time.
151    ///
152    /// # Examples
153    /// ```no_run
154    /// # use bones_framework::prelude::*;
155    /// use std::time::Duration;
156    /// let mut stopwatch = Stopwatch::new();
157    /// stopwatch.pause();
158    /// stopwatch.tick(Duration::from_secs_f32(1.0));
159    /// stopwatch.unpause();
160    /// stopwatch.tick(Duration::from_secs_f32(1.0));
161    /// assert!(!stopwatch.paused());
162    /// assert_eq!(stopwatch.elapsed_secs(), 1.0);
163    /// ```
164    #[inline]
165    pub fn unpause(&mut self) {
166        self.paused = false;
167    }
168
169    /// Returns `true` if the stopwatch is paused.
170    ///
171    /// # Examples
172    /// ```no_run
173    /// # use bones_framework::prelude::*;
174    /// let mut stopwatch = Stopwatch::new();
175    /// assert!(!stopwatch.paused());
176    /// stopwatch.pause();
177    /// assert!(stopwatch.paused());
178    /// stopwatch.unpause();
179    /// assert!(!stopwatch.paused());
180    /// ```
181    #[inline]
182    pub fn paused(&self) -> bool {
183        self.paused
184    }
185
186    /// Resets the stopwatch. The reset doesn't affect the paused state of the stopwatch.
187    ///
188    /// # Examples
189    /// ```no_run
190    /// # use bones_framework::prelude::*;
191    /// use std::time::Duration;
192    /// let mut stopwatch = Stopwatch::new();
193    /// stopwatch.tick(Duration::from_secs_f32(1.5));
194    /// stopwatch.reset();
195    /// assert_eq!(stopwatch.elapsed_secs(), 0.0);
196    /// ```
197    #[inline]
198    pub fn reset(&mut self) {
199        self.elapsed = Default::default();
200    }
201}