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}