From 2f408cf0538ab7826404715c9d2ac7842c5d24d7 Mon Sep 17 00:00:00 2001 From: Nathan Stocks Date: Wed, 25 Nov 2020 17:43:16 -0700 Subject: [PATCH] Improve timer ergonomics. Add tests (#923) --- crates/bevy_core/src/time/timer.rs | 91 +++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 7 deletions(-) diff --git a/crates/bevy_core/src/time/timer.rs b/crates/bevy_core/src/time/timer.rs index 33ec613336..a9e9a52894 100644 --- a/crates/bevy_core/src/time/timer.rs +++ b/crates/bevy_core/src/time/timer.rs @@ -9,8 +9,11 @@ use bevy_utils::Duration; /// Repeating timers will only be in the finished state on each tick `duration` is reached or exceeded, and can still be reset at any given point. #[derive(Clone, Debug, Default, Properties)] pub struct Timer { + /// Time elapsed on the timer. Guaranteed to be between 0.0 and `duration`, inclusive. pub elapsed: f32, pub duration: f32, + /// Non repeating timers will stop tracking and stay in the finished state until reset. + /// Repeating timers will only be in the finished state on each tick `duration` is reached or exceeded, and can still be reset at any given point. pub finished: bool, /// Will only be true on the tick `duration` is reached or exceeded. pub just_finished: bool, @@ -36,16 +39,19 @@ impl Timer { /// Advances the timer by `delta` seconds. pub fn tick(&mut self, delta: f32) -> &Self { - let prev_finished = self.elapsed >= self.duration; - if !prev_finished { - self.elapsed += delta; - } + let prev_finished = self.finished; + self.elapsed += delta; self.finished = self.elapsed >= self.duration; self.just_finished = !prev_finished && self.finished; - - if self.repeating && self.finished { - self.elapsed %= self.duration; + if self.finished { + if self.repeating { + // Repeating timers wrap around + self.elapsed %= self.duration; + } else { + // Non-repeating timers clamp to duration + self.elapsed = self.duration; + } } self } @@ -55,6 +61,16 @@ impl Timer { self.just_finished = false; self.elapsed = 0.0; } + + /// Percent timer has elapsed (goes from 0.0 to 1.0) + pub fn percent(&self) -> f32 { + self.elapsed / self.duration + } + + /// Percent left on timer (goes from 1.0 to 0.0) + pub fn percent_left(&self) -> f32 { + (self.duration - self.elapsed) / self.duration + } } pub(crate) fn timer_system(time: Res