mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
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 <justthecooldude@gmail.com>
This commit is contained in:
parent
18b27269c0
commit
3f423074bf
1 changed files with 64 additions and 32 deletions
|
@ -15,7 +15,7 @@ pub struct Timer {
|
|||
duration: Duration,
|
||||
repeating: bool,
|
||||
finished: bool,
|
||||
times_finished: u32,
|
||||
times_finished_this_tick: u32,
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
|
@ -76,7 +76,7 @@ impl Timer {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn just_finished(&self) -> bool {
|
||||
self.times_finished > 0
|
||||
self.times_finished_this_tick > 0
|
||||
}
|
||||
|
||||
/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`.
|
||||
|
@ -202,11 +202,15 @@ impl Timer {
|
|||
/// ```
|
||||
pub fn tick(&mut self, delta: Duration) -> &Self {
|
||||
if self.paused() {
|
||||
self.times_finished_this_tick = 0;
|
||||
if self.repeating() {
|
||||
self.finished = false;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
if !self.repeating() && self.finished() {
|
||||
self.times_finished = 0;
|
||||
self.times_finished_this_tick = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -215,16 +219,16 @@ impl Timer {
|
|||
|
||||
if self.finished() {
|
||||
if self.repeating() {
|
||||
self.times_finished =
|
||||
self.times_finished_this_tick =
|
||||
(self.elapsed().as_nanos() / self.duration().as_nanos()) as u32;
|
||||
// Duration does not have a modulo
|
||||
self.set_elapsed(self.elapsed() - self.duration() * self.times_finished);
|
||||
self.set_elapsed(self.elapsed() - self.duration() * self.times_finished_this_tick);
|
||||
} else {
|
||||
self.times_finished = 1;
|
||||
self.times_finished_this_tick = 1;
|
||||
self.set_elapsed(self.duration());
|
||||
}
|
||||
} else {
|
||||
self.times_finished = 0;
|
||||
self.times_finished_this_tick = 0;
|
||||
}
|
||||
|
||||
self
|
||||
|
@ -305,7 +309,7 @@ impl Timer {
|
|||
pub fn reset(&mut self) {
|
||||
self.stopwatch.reset();
|
||||
self.finished = false;
|
||||
self.times_finished = 0;
|
||||
self.times_finished_this_tick = 0;
|
||||
}
|
||||
|
||||
/// Returns the percentage of the timer elapsed time (goes from 0.0 to 1.0).
|
||||
|
@ -350,15 +354,15 @@ impl Timer {
|
|||
/// use std::time::Duration;
|
||||
/// let mut timer = Timer::from_seconds(1.0, true);
|
||||
/// timer.tick(Duration::from_secs_f32(6.0));
|
||||
/// assert_eq!(timer.times_finished(), 6);
|
||||
/// assert_eq!(timer.times_finished_this_tick(), 6);
|
||||
/// timer.tick(Duration::from_secs_f32(2.0));
|
||||
/// assert_eq!(timer.times_finished(), 2);
|
||||
/// assert_eq!(timer.times_finished_this_tick(), 2);
|
||||
/// timer.tick(Duration::from_secs_f32(0.5));
|
||||
/// assert_eq!(timer.times_finished(), 0);
|
||||
/// assert_eq!(timer.times_finished_this_tick(), 0);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn times_finished(&self) -> u32 {
|
||||
self.times_finished
|
||||
pub fn times_finished_this_tick(&self) -> u32 {
|
||||
self.times_finished_this_tick
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,7 +380,7 @@ mod tests {
|
|||
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
||||
assert!(!t.finished());
|
||||
assert!(!t.just_finished());
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
assert!(!t.repeating());
|
||||
assert_eq!(t.percent(), 0.025);
|
||||
assert_eq!(t.percent_left(), 0.975);
|
||||
|
@ -387,7 +391,7 @@ mod tests {
|
|||
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
||||
assert!(!t.finished());
|
||||
assert!(!t.just_finished());
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
assert!(!t.repeating());
|
||||
assert_eq!(t.percent(), 0.025);
|
||||
assert_eq!(t.percent_left(), 0.975);
|
||||
|
@ -397,7 +401,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed_secs(), 10.0);
|
||||
assert!(t.finished());
|
||||
assert!(t.just_finished());
|
||||
assert_eq!(t.times_finished(), 1);
|
||||
assert_eq!(t.times_finished_this_tick(), 1);
|
||||
assert_eq!(t.percent(), 1.0);
|
||||
assert_eq!(t.percent_left(), 0.0);
|
||||
// Continuing to tick when finished should only change just_finished
|
||||
|
@ -405,7 +409,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed_secs(), 10.0);
|
||||
assert!(t.finished());
|
||||
assert!(!t.just_finished());
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
assert_eq!(t.percent(), 1.0);
|
||||
assert_eq!(t.percent_left(), 0.0);
|
||||
}
|
||||
|
@ -419,7 +423,7 @@ mod tests {
|
|||
assert_eq!(t.duration(), Duration::from_secs_f32(2.0));
|
||||
assert!(!t.finished());
|
||||
assert!(!t.just_finished());
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
assert!(t.repeating());
|
||||
assert_eq!(t.percent(), 0.375);
|
||||
assert_eq!(t.percent_left(), 0.625);
|
||||
|
@ -428,7 +432,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed_secs(), 0.25);
|
||||
assert!(t.finished());
|
||||
assert!(t.just_finished());
|
||||
assert_eq!(t.times_finished(), 1);
|
||||
assert_eq!(t.times_finished_this_tick(), 1);
|
||||
assert_eq!(t.percent(), 0.125);
|
||||
assert_eq!(t.percent_left(), 0.875);
|
||||
// Continuing to tick should turn off both finished & just_finished for repeating timers
|
||||
|
@ -436,7 +440,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed_secs(), 1.25);
|
||||
assert!(!t.finished());
|
||||
assert!(!t.just_finished());
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
assert_eq!(t.percent(), 0.625);
|
||||
assert_eq!(t.percent_left(), 0.375);
|
||||
}
|
||||
|
@ -444,42 +448,70 @@ mod tests {
|
|||
#[test]
|
||||
fn times_finished_repeating() {
|
||||
let mut t = Timer::from_seconds(1.0, true);
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
t.tick(Duration::from_secs_f32(3.5));
|
||||
assert_eq!(t.times_finished(), 3);
|
||||
assert_eq!(t.times_finished_this_tick(), 3);
|
||||
assert_eq!(t.elapsed_secs(), 0.5);
|
||||
assert!(t.finished());
|
||||
assert!(t.just_finished());
|
||||
t.tick(Duration::from_secs_f32(0.2));
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn times_finished() {
|
||||
fn times_finished_this_tick() {
|
||||
let mut t = Timer::from_seconds(1.0, false);
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
t.tick(Duration::from_secs_f32(1.5));
|
||||
assert_eq!(t.times_finished(), 1);
|
||||
assert_eq!(t.times_finished_this_tick(), 1);
|
||||
t.tick(Duration::from_secs_f32(0.5));
|
||||
assert_eq!(t.times_finished(), 0);
|
||||
assert_eq!(t.times_finished_this_tick(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn times_finished_precise() {
|
||||
fn times_finished_this_tick_precise() {
|
||||
let mut t = Timer::from_seconds(0.01, true);
|
||||
let duration = Duration::from_secs_f64(0.333);
|
||||
|
||||
// total duration: 0.333 => 33 times finished
|
||||
t.tick(duration);
|
||||
assert_eq!(t.times_finished(), 33);
|
||||
assert_eq!(t.times_finished_this_tick(), 33);
|
||||
// total duration: 0.666 => 33 times finished
|
||||
t.tick(duration);
|
||||
assert_eq!(t.times_finished(), 33);
|
||||
assert_eq!(t.times_finished_this_tick(), 33);
|
||||
// total duration: 0.999 => 33 times finished
|
||||
t.tick(duration);
|
||||
assert_eq!(t.times_finished(), 33);
|
||||
assert_eq!(t.times_finished_this_tick(), 33);
|
||||
// total duration: 1.332 => 34 times finished
|
||||
t.tick(duration);
|
||||
assert_eq!(t.times_finished(), 34);
|
||||
assert_eq!(t.times_finished_this_tick(), 34);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paused() {
|
||||
let mut t = Timer::from_seconds(10.0, false);
|
||||
|
||||
t.tick(Duration::from_secs_f32(10.0));
|
||||
assert!(t.just_finished());
|
||||
assert!(t.finished());
|
||||
// A paused timer should change just_finished to false after a tick
|
||||
t.pause();
|
||||
t.tick(Duration::from_secs_f32(5.0));
|
||||
assert!(!t.just_finished());
|
||||
assert!(t.finished());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn paused_repeating() {
|
||||
let mut t = Timer::from_seconds(10.0, true);
|
||||
|
||||
t.tick(Duration::from_secs_f32(10.0));
|
||||
assert!(t.just_finished());
|
||||
assert!(t.finished());
|
||||
// A paused repeating timer should change finished and just_finished to false after a tick
|
||||
t.pause();
|
||||
t.tick(Duration::from_secs_f32(5.0));
|
||||
assert!(!t.just_finished());
|
||||
assert!(!t.finished());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue