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
@ -15,7 +15,7 @@ pub struct Timer {
|
|||||||
duration: Duration,
|
duration: Duration,
|
||||||
repeating: bool,
|
repeating: bool,
|
||||||
finished: bool,
|
finished: bool,
|
||||||
times_finished: u32,
|
times_finished_this_tick: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Timer {
|
impl Timer {
|
||||||
@ -76,7 +76,7 @@ impl Timer {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn just_finished(&self) -> bool {
|
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`.
|
/// 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 {
|
pub fn tick(&mut self, delta: Duration) -> &Self {
|
||||||
if self.paused() {
|
if self.paused() {
|
||||||
|
self.times_finished_this_tick = 0;
|
||||||
|
if self.repeating() {
|
||||||
|
self.finished = false;
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.repeating() && self.finished() {
|
if !self.repeating() && self.finished() {
|
||||||
self.times_finished = 0;
|
self.times_finished_this_tick = 0;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,16 +219,16 @@ impl Timer {
|
|||||||
|
|
||||||
if self.finished() {
|
if self.finished() {
|
||||||
if self.repeating() {
|
if self.repeating() {
|
||||||
self.times_finished =
|
self.times_finished_this_tick =
|
||||||
(self.elapsed().as_nanos() / self.duration().as_nanos()) as u32;
|
(self.elapsed().as_nanos() / self.duration().as_nanos()) as u32;
|
||||||
// Duration does not have a modulo
|
// 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 {
|
} else {
|
||||||
self.times_finished = 1;
|
self.times_finished_this_tick = 1;
|
||||||
self.set_elapsed(self.duration());
|
self.set_elapsed(self.duration());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.times_finished = 0;
|
self.times_finished_this_tick = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
@ -305,7 +309,7 @@ impl Timer {
|
|||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.stopwatch.reset();
|
self.stopwatch.reset();
|
||||||
self.finished = false;
|
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).
|
/// 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;
|
/// use std::time::Duration;
|
||||||
/// let mut timer = Timer::from_seconds(1.0, true);
|
/// let mut timer = Timer::from_seconds(1.0, true);
|
||||||
/// timer.tick(Duration::from_secs_f32(6.0));
|
/// 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));
|
/// 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));
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
||||||
/// assert_eq!(timer.times_finished(), 0);
|
/// assert_eq!(timer.times_finished_this_tick(), 0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn times_finished(&self) -> u32 {
|
pub fn times_finished_this_tick(&self) -> u32 {
|
||||||
self.times_finished
|
self.times_finished_this_tick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +380,7 @@ mod tests {
|
|||||||
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
||||||
assert!(!t.finished());
|
assert!(!t.finished());
|
||||||
assert!(!t.just_finished());
|
assert!(!t.just_finished());
|
||||||
assert_eq!(t.times_finished(), 0);
|
assert_eq!(t.times_finished_this_tick(), 0);
|
||||||
assert!(!t.repeating());
|
assert!(!t.repeating());
|
||||||
assert_eq!(t.percent(), 0.025);
|
assert_eq!(t.percent(), 0.025);
|
||||||
assert_eq!(t.percent_left(), 0.975);
|
assert_eq!(t.percent_left(), 0.975);
|
||||||
@ -387,7 +391,7 @@ mod tests {
|
|||||||
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
||||||
assert!(!t.finished());
|
assert!(!t.finished());
|
||||||
assert!(!t.just_finished());
|
assert!(!t.just_finished());
|
||||||
assert_eq!(t.times_finished(), 0);
|
assert_eq!(t.times_finished_this_tick(), 0);
|
||||||
assert!(!t.repeating());
|
assert!(!t.repeating());
|
||||||
assert_eq!(t.percent(), 0.025);
|
assert_eq!(t.percent(), 0.025);
|
||||||
assert_eq!(t.percent_left(), 0.975);
|
assert_eq!(t.percent_left(), 0.975);
|
||||||
@ -397,7 +401,7 @@ mod tests {
|
|||||||
assert_eq!(t.elapsed_secs(), 10.0);
|
assert_eq!(t.elapsed_secs(), 10.0);
|
||||||
assert!(t.finished());
|
assert!(t.finished());
|
||||||
assert!(t.just_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(), 1.0);
|
||||||
assert_eq!(t.percent_left(), 0.0);
|
assert_eq!(t.percent_left(), 0.0);
|
||||||
// Continuing to tick when finished should only change just_finished
|
// Continuing to tick when finished should only change just_finished
|
||||||
@ -405,7 +409,7 @@ mod tests {
|
|||||||
assert_eq!(t.elapsed_secs(), 10.0);
|
assert_eq!(t.elapsed_secs(), 10.0);
|
||||||
assert!(t.finished());
|
assert!(t.finished());
|
||||||
assert!(!t.just_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(), 1.0);
|
||||||
assert_eq!(t.percent_left(), 0.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_eq!(t.duration(), Duration::from_secs_f32(2.0));
|
||||||
assert!(!t.finished());
|
assert!(!t.finished());
|
||||||
assert!(!t.just_finished());
|
assert!(!t.just_finished());
|
||||||
assert_eq!(t.times_finished(), 0);
|
assert_eq!(t.times_finished_this_tick(), 0);
|
||||||
assert!(t.repeating());
|
assert!(t.repeating());
|
||||||
assert_eq!(t.percent(), 0.375);
|
assert_eq!(t.percent(), 0.375);
|
||||||
assert_eq!(t.percent_left(), 0.625);
|
assert_eq!(t.percent_left(), 0.625);
|
||||||
@ -428,7 +432,7 @@ mod tests {
|
|||||||
assert_eq!(t.elapsed_secs(), 0.25);
|
assert_eq!(t.elapsed_secs(), 0.25);
|
||||||
assert!(t.finished());
|
assert!(t.finished());
|
||||||
assert!(t.just_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(), 0.125);
|
||||||
assert_eq!(t.percent_left(), 0.875);
|
assert_eq!(t.percent_left(), 0.875);
|
||||||
// Continuing to tick should turn off both finished & just_finished for repeating timers
|
// 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_eq!(t.elapsed_secs(), 1.25);
|
||||||
assert!(!t.finished());
|
assert!(!t.finished());
|
||||||
assert!(!t.just_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(), 0.625);
|
||||||
assert_eq!(t.percent_left(), 0.375);
|
assert_eq!(t.percent_left(), 0.375);
|
||||||
}
|
}
|
||||||
@ -444,42 +448,70 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn times_finished_repeating() {
|
fn times_finished_repeating() {
|
||||||
let mut t = Timer::from_seconds(1.0, true);
|
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));
|
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_eq!(t.elapsed_secs(), 0.5);
|
||||||
assert!(t.finished());
|
assert!(t.finished());
|
||||||
assert!(t.just_finished());
|
assert!(t.just_finished());
|
||||||
t.tick(Duration::from_secs_f32(0.2));
|
t.tick(Duration::from_secs_f32(0.2));
|
||||||
assert_eq!(t.times_finished(), 0);
|
assert_eq!(t.times_finished_this_tick(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn times_finished() {
|
fn times_finished_this_tick() {
|
||||||
let mut t = Timer::from_seconds(1.0, false);
|
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));
|
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));
|
t.tick(Duration::from_secs_f32(0.5));
|
||||||
assert_eq!(t.times_finished(), 0);
|
assert_eq!(t.times_finished_this_tick(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn times_finished_precise() {
|
fn times_finished_this_tick_precise() {
|
||||||
let mut t = Timer::from_seconds(0.01, true);
|
let mut t = Timer::from_seconds(0.01, true);
|
||||||
let duration = Duration::from_secs_f64(0.333);
|
let duration = Duration::from_secs_f64(0.333);
|
||||||
|
|
||||||
// total duration: 0.333 => 33 times finished
|
// total duration: 0.333 => 33 times finished
|
||||||
t.tick(duration);
|
t.tick(duration);
|
||||||
assert_eq!(t.times_finished(), 33);
|
assert_eq!(t.times_finished_this_tick(), 33);
|
||||||
// total duration: 0.666 => 33 times finished
|
// total duration: 0.666 => 33 times finished
|
||||||
t.tick(duration);
|
t.tick(duration);
|
||||||
assert_eq!(t.times_finished(), 33);
|
assert_eq!(t.times_finished_this_tick(), 33);
|
||||||
// total duration: 0.999 => 33 times finished
|
// total duration: 0.999 => 33 times finished
|
||||||
t.tick(duration);
|
t.tick(duration);
|
||||||
assert_eq!(t.times_finished(), 33);
|
assert_eq!(t.times_finished_this_tick(), 33);
|
||||||
// total duration: 1.332 => 34 times finished
|
// total duration: 1.332 => 34 times finished
|
||||||
t.tick(duration);
|
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 New Issue
Block a user