1#[cfg(feature = "bevy_reflect")]
2use bevy_reflect::Reflect;
3use bevy_utils::{Duration, Instant};
4
5use crate::time::Time;
6
7#[derive(Debug, Copy, Clone)]
33#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
34pub struct Real {
35 startup: Instant,
36 first_update: Option<Instant>,
37 last_update: Option<Instant>,
38}
39
40impl Default for Real {
41 fn default() -> Self {
42 Self {
43 startup: Instant::now(),
44 first_update: None,
45 last_update: None,
46 }
47 }
48}
49
50impl Time<Real> {
51 pub fn new(startup: Instant) -> Self {
54 Self::new_with(Real {
55 startup,
56 ..Default::default()
57 })
58 }
59
60 pub fn update(&mut self) {
66 let instant = Instant::now();
67 self.update_with_instant(instant);
68 }
69
70 pub fn update_with_duration(&mut self, duration: Duration) {
78 let last_update = self.context().last_update.unwrap_or(self.context().startup);
79 self.update_with_instant(last_update + duration);
80 }
81
82 pub fn update_with_instant(&mut self, instant: Instant) {
89 let Some(last_update) = self.context().last_update else {
90 let context = self.context_mut();
91 context.first_update = Some(instant);
92 context.last_update = Some(instant);
93 return;
94 };
95 let delta = instant - last_update;
96 self.advance_by(delta);
97 self.context_mut().last_update = Some(instant);
98 }
99
100 #[inline]
104 pub fn startup(&self) -> Instant {
105 self.context().startup
106 }
107
108 #[inline]
113 pub fn first_update(&self) -> Option<Instant> {
114 self.context().first_update
115 }
116
117 #[inline]
122 pub fn last_update(&self) -> Option<Instant> {
123 self.context().last_update
124 }
125}
126
127#[cfg(test)]
128mod test {
129 use super::*;
130
131 #[test]
132 fn test_update() {
133 let startup = Instant::now();
134 let mut time = Time::<Real>::new(startup);
135
136 assert_eq!(time.startup(), startup);
137 assert_eq!(time.first_update(), None);
138 assert_eq!(time.last_update(), None);
139 assert_eq!(time.delta(), Duration::ZERO);
140 assert_eq!(time.elapsed(), Duration::ZERO);
141
142 time.update();
143
144 assert_ne!(time.first_update(), None);
145 assert_ne!(time.last_update(), None);
146 assert_eq!(time.delta(), Duration::ZERO);
147 assert_eq!(time.elapsed(), Duration::ZERO);
148
149 time.update();
150
151 assert_ne!(time.first_update(), None);
152 assert_ne!(time.last_update(), None);
153 assert_ne!(time.last_update(), time.first_update());
154 assert_ne!(time.delta(), Duration::ZERO);
155 assert_eq!(time.elapsed(), time.delta());
156
157 let prev_elapsed = time.elapsed();
158 time.update();
159
160 assert_ne!(time.delta(), Duration::ZERO);
161 assert_eq!(time.elapsed(), prev_elapsed + time.delta());
162 }
163
164 #[test]
165 fn test_update_with_instant() {
166 let startup = Instant::now();
167 let mut time = Time::<Real>::new(startup);
168
169 let first_update = Instant::now();
170 time.update_with_instant(first_update);
171
172 assert_eq!(time.startup(), startup);
173 assert_eq!(time.first_update(), Some(first_update));
174 assert_eq!(time.last_update(), Some(first_update));
175 assert_eq!(time.delta(), Duration::ZERO);
176 assert_eq!(time.elapsed(), Duration::ZERO);
177
178 let second_update = Instant::now();
179 time.update_with_instant(second_update);
180
181 assert_eq!(time.first_update(), Some(first_update));
182 assert_eq!(time.last_update(), Some(second_update));
183 assert_eq!(time.delta(), second_update - first_update);
184 assert_eq!(time.elapsed(), second_update - first_update);
185
186 let third_update = Instant::now();
187 time.update_with_instant(third_update);
188
189 assert_eq!(time.first_update(), Some(first_update));
190 assert_eq!(time.last_update(), Some(third_update));
191 assert_eq!(time.delta(), third_update - second_update);
192 assert_eq!(time.elapsed(), third_update - first_update);
193 }
194
195 #[test]
196 fn test_update_with_duration() {
197 let startup = Instant::now();
198 let mut time = Time::<Real>::new(startup);
199
200 time.update_with_duration(Duration::from_secs(1));
201
202 assert_eq!(time.startup(), startup);
203 assert_eq!(time.first_update(), Some(startup + Duration::from_secs(1)));
204 assert_eq!(time.last_update(), Some(startup + Duration::from_secs(1)));
205 assert_eq!(time.delta(), Duration::ZERO);
206 assert_eq!(time.elapsed(), Duration::ZERO);
207
208 time.update_with_duration(Duration::from_secs(1));
209
210 assert_eq!(time.first_update(), Some(startup + Duration::from_secs(1)));
211 assert_eq!(time.last_update(), Some(startup + Duration::from_secs(2)));
212 assert_eq!(time.delta(), Duration::from_secs(1));
213 assert_eq!(time.elapsed(), Duration::from_secs(1));
214
215 time.update_with_duration(Duration::from_secs(1));
216
217 assert_eq!(time.first_update(), Some(startup + Duration::from_secs(1)));
218 assert_eq!(time.last_update(), Some(startup + Duration::from_secs(3)));
219 assert_eq!(time.delta(), Duration::from_secs(1));
220 assert_eq!(time.elapsed(), Duration::from_secs(2));
221 }
222}