Skip to content

Commit 3f42307

Browse files
committed
Make paused timers update just_finished on tick (#4445)
# Objective Make timers update `just_finished` on tick, even if paused. Fixes #4436 ## Solution `just_finished()` returns `times_finished > 0`. So I: * Renamed `times_finished` to `times_finished_this_tick` to reduce confusion. * Set `times_finished_this_tick` to `0` on tick when paused. * Additionally set `finished` to `false` if the timer is repeating. Notably this change broke none of the existing tests, so I added a couple for this. Files changed shows a lot of noise because of the rename. Check the first commit for the relevant changes. Co-authored-by: devil-ira <[email protected]>
1 parent 18b2726 commit 3f42307

File tree

1 file changed

+64
-32
lines changed

1 file changed

+64
-32
lines changed

crates/bevy_core/src/time/timer.rs

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub struct Timer {
1515
duration: Duration,
1616
repeating: bool,
1717
finished: bool,
18-
times_finished: u32,
18+
times_finished_this_tick: u32,
1919
}
2020

2121
impl Timer {
@@ -76,7 +76,7 @@ impl Timer {
7676
/// ```
7777
#[inline]
7878
pub fn just_finished(&self) -> bool {
79-
self.times_finished > 0
79+
self.times_finished_this_tick > 0
8080
}
8181

8282
/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`.
@@ -202,11 +202,15 @@ impl Timer {
202202
/// ```
203203
pub fn tick(&mut self, delta: Duration) -> &Self {
204204
if self.paused() {
205+
self.times_finished_this_tick = 0;
206+
if self.repeating() {
207+
self.finished = false;
208+
}
205209
return self;
206210
}
207211

208212
if !self.repeating() && self.finished() {
209-
self.times_finished = 0;
213+
self.times_finished_this_tick = 0;
210214
return self;
211215
}
212216

@@ -215,16 +219,16 @@ impl Timer {
215219

216220
if self.finished() {
217221
if self.repeating() {
218-
self.times_finished =
222+
self.times_finished_this_tick =
219223
(self.elapsed().as_nanos() / self.duration().as_nanos()) as u32;
220224
// Duration does not have a modulo
221-
self.set_elapsed(self.elapsed() - self.duration() * self.times_finished);
225+
self.set_elapsed(self.elapsed() - self.duration() * self.times_finished_this_tick);
222226
} else {
223-
self.times_finished = 1;
227+
self.times_finished_this_tick = 1;
224228
self.set_elapsed(self.duration());
225229
}
226230
} else {
227-
self.times_finished = 0;
231+
self.times_finished_this_tick = 0;
228232
}
229233

230234
self
@@ -305,7 +309,7 @@ impl Timer {
305309
pub fn reset(&mut self) {
306310
self.stopwatch.reset();
307311
self.finished = false;
308-
self.times_finished = 0;
312+
self.times_finished_this_tick = 0;
309313
}
310314

311315
/// Returns the percentage of the timer elapsed time (goes from 0.0 to 1.0).
@@ -350,15 +354,15 @@ impl Timer {
350354
/// use std::time::Duration;
351355
/// let mut timer = Timer::from_seconds(1.0, true);
352356
/// timer.tick(Duration::from_secs_f32(6.0));
353-
/// assert_eq!(timer.times_finished(), 6);
357+
/// assert_eq!(timer.times_finished_this_tick(), 6);
354358
/// timer.tick(Duration::from_secs_f32(2.0));
355-
/// assert_eq!(timer.times_finished(), 2);
359+
/// assert_eq!(timer.times_finished_this_tick(), 2);
356360
/// timer.tick(Duration::from_secs_f32(0.5));
357-
/// assert_eq!(timer.times_finished(), 0);
361+
/// assert_eq!(timer.times_finished_this_tick(), 0);
358362
/// ```
359363
#[inline]
360-
pub fn times_finished(&self) -> u32 {
361-
self.times_finished
364+
pub fn times_finished_this_tick(&self) -> u32 {
365+
self.times_finished_this_tick
362366
}
363367
}
364368

@@ -376,7 +380,7 @@ mod tests {
376380
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
377381
assert!(!t.finished());
378382
assert!(!t.just_finished());
379-
assert_eq!(t.times_finished(), 0);
383+
assert_eq!(t.times_finished_this_tick(), 0);
380384
assert!(!t.repeating());
381385
assert_eq!(t.percent(), 0.025);
382386
assert_eq!(t.percent_left(), 0.975);
@@ -387,7 +391,7 @@ mod tests {
387391
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
388392
assert!(!t.finished());
389393
assert!(!t.just_finished());
390-
assert_eq!(t.times_finished(), 0);
394+
assert_eq!(t.times_finished_this_tick(), 0);
391395
assert!(!t.repeating());
392396
assert_eq!(t.percent(), 0.025);
393397
assert_eq!(t.percent_left(), 0.975);
@@ -397,15 +401,15 @@ mod tests {
397401
assert_eq!(t.elapsed_secs(), 10.0);
398402
assert!(t.finished());
399403
assert!(t.just_finished());
400-
assert_eq!(t.times_finished(), 1);
404+
assert_eq!(t.times_finished_this_tick(), 1);
401405
assert_eq!(t.percent(), 1.0);
402406
assert_eq!(t.percent_left(), 0.0);
403407
// Continuing to tick when finished should only change just_finished
404408
t.tick(Duration::from_secs_f32(1.0));
405409
assert_eq!(t.elapsed_secs(), 10.0);
406410
assert!(t.finished());
407411
assert!(!t.just_finished());
408-
assert_eq!(t.times_finished(), 0);
412+
assert_eq!(t.times_finished_this_tick(), 0);
409413
assert_eq!(t.percent(), 1.0);
410414
assert_eq!(t.percent_left(), 0.0);
411415
}
@@ -419,7 +423,7 @@ mod tests {
419423
assert_eq!(t.duration(), Duration::from_secs_f32(2.0));
420424
assert!(!t.finished());
421425
assert!(!t.just_finished());
422-
assert_eq!(t.times_finished(), 0);
426+
assert_eq!(t.times_finished_this_tick(), 0);
423427
assert!(t.repeating());
424428
assert_eq!(t.percent(), 0.375);
425429
assert_eq!(t.percent_left(), 0.625);
@@ -428,58 +432,86 @@ mod tests {
428432
assert_eq!(t.elapsed_secs(), 0.25);
429433
assert!(t.finished());
430434
assert!(t.just_finished());
431-
assert_eq!(t.times_finished(), 1);
435+
assert_eq!(t.times_finished_this_tick(), 1);
432436
assert_eq!(t.percent(), 0.125);
433437
assert_eq!(t.percent_left(), 0.875);
434438
// Continuing to tick should turn off both finished & just_finished for repeating timers
435439
t.tick(Duration::from_secs_f32(1.0));
436440
assert_eq!(t.elapsed_secs(), 1.25);
437441
assert!(!t.finished());
438442
assert!(!t.just_finished());
439-
assert_eq!(t.times_finished(), 0);
443+
assert_eq!(t.times_finished_this_tick(), 0);
440444
assert_eq!(t.percent(), 0.625);
441445
assert_eq!(t.percent_left(), 0.375);
442446
}
443447

444448
#[test]
445449
fn times_finished_repeating() {
446450
let mut t = Timer::from_seconds(1.0, true);
447-
assert_eq!(t.times_finished(), 0);
451+
assert_eq!(t.times_finished_this_tick(), 0);
448452
t.tick(Duration::from_secs_f32(3.5));
449-
assert_eq!(t.times_finished(), 3);
453+
assert_eq!(t.times_finished_this_tick(), 3);
450454
assert_eq!(t.elapsed_secs(), 0.5);
451455
assert!(t.finished());
452456
assert!(t.just_finished());
453457
t.tick(Duration::from_secs_f32(0.2));
454-
assert_eq!(t.times_finished(), 0);
458+
assert_eq!(t.times_finished_this_tick(), 0);
455459
}
456460

457461
#[test]
458-
fn times_finished() {
462+
fn times_finished_this_tick() {
459463
let mut t = Timer::from_seconds(1.0, false);
460-
assert_eq!(t.times_finished(), 0);
464+
assert_eq!(t.times_finished_this_tick(), 0);
461465
t.tick(Duration::from_secs_f32(1.5));
462-
assert_eq!(t.times_finished(), 1);
466+
assert_eq!(t.times_finished_this_tick(), 1);
463467
t.tick(Duration::from_secs_f32(0.5));
464-
assert_eq!(t.times_finished(), 0);
468+
assert_eq!(t.times_finished_this_tick(), 0);
465469
}
466470

467471
#[test]
468-
fn times_finished_precise() {
472+
fn times_finished_this_tick_precise() {
469473
let mut t = Timer::from_seconds(0.01, true);
470474
let duration = Duration::from_secs_f64(0.333);
471475

472476
// total duration: 0.333 => 33 times finished
473477
t.tick(duration);
474-
assert_eq!(t.times_finished(), 33);
478+
assert_eq!(t.times_finished_this_tick(), 33);
475479
// total duration: 0.666 => 33 times finished
476480
t.tick(duration);
477-
assert_eq!(t.times_finished(), 33);
481+
assert_eq!(t.times_finished_this_tick(), 33);
478482
// total duration: 0.999 => 33 times finished
479483
t.tick(duration);
480-
assert_eq!(t.times_finished(), 33);
484+
assert_eq!(t.times_finished_this_tick(), 33);
481485
// total duration: 1.332 => 34 times finished
482486
t.tick(duration);
483-
assert_eq!(t.times_finished(), 34);
487+
assert_eq!(t.times_finished_this_tick(), 34);
488+
}
489+
490+
#[test]
491+
fn paused() {
492+
let mut t = Timer::from_seconds(10.0, false);
493+
494+
t.tick(Duration::from_secs_f32(10.0));
495+
assert!(t.just_finished());
496+
assert!(t.finished());
497+
// A paused timer should change just_finished to false after a tick
498+
t.pause();
499+
t.tick(Duration::from_secs_f32(5.0));
500+
assert!(!t.just_finished());
501+
assert!(t.finished());
502+
}
503+
504+
#[test]
505+
fn paused_repeating() {
506+
let mut t = Timer::from_seconds(10.0, true);
507+
508+
t.tick(Duration::from_secs_f32(10.0));
509+
assert!(t.just_finished());
510+
assert!(t.finished());
511+
// A paused repeating timer should change finished and just_finished to false after a tick
512+
t.pause();
513+
t.tick(Duration::from_secs_f32(5.0));
514+
assert!(!t.just_finished());
515+
assert!(!t.finished());
484516
}
485517
}

0 commit comments

Comments
 (0)