mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Count number of times a repeating Timer wraps around in a tick (#1112)
Added just_finished_count() function
This commit is contained in:
parent
1e8060a5a2
commit
ac7d2de67c
1 changed files with 36 additions and 11 deletions
|
@ -13,8 +13,8 @@ pub struct Timer {
|
|||
elapsed: f32,
|
||||
duration: f32,
|
||||
finished: bool,
|
||||
/// Will only be true on the tick `duration` is reached or exceeded.
|
||||
just_finished: bool,
|
||||
/// Will only be non-zero on the tick `duration` is reached or exceeded.
|
||||
just_finished_count: u32,
|
||||
paused: bool,
|
||||
repeating: bool,
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ impl Timer {
|
|||
self.paused
|
||||
}
|
||||
|
||||
/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`, inclusive.
|
||||
/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`.
|
||||
/// Will only equal `duration` when the timer is finished and non repeating.
|
||||
#[inline]
|
||||
pub fn elapsed(&self) -> f32 {
|
||||
self.elapsed
|
||||
|
@ -74,8 +75,9 @@ impl Timer {
|
|||
|
||||
/// Returns the finished state of the timer.
|
||||
///
|
||||
/// 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.
|
||||
/// 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, so in that case
|
||||
/// this function is equivalent to `just_finished`.
|
||||
#[inline]
|
||||
pub fn finished(&self) -> bool {
|
||||
self.finished
|
||||
|
@ -84,7 +86,16 @@ impl Timer {
|
|||
/// Will only be true on the tick the timer's duration is reached or exceeded.
|
||||
#[inline]
|
||||
pub fn just_finished(&self) -> bool {
|
||||
self.just_finished
|
||||
self.just_finished_count > 0
|
||||
}
|
||||
|
||||
/// Returns the total number of times the timer finished during this tick.
|
||||
///
|
||||
/// This value can be used to ensure no completions of a repeating timer are skipped over due to a tick with an unexpectedly
|
||||
/// long delta time. For non repeating timers, the value will only ever be 0 or 1.
|
||||
#[inline]
|
||||
pub fn just_finished_count(&self) -> u32 {
|
||||
self.just_finished_count
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -92,8 +103,11 @@ impl Timer {
|
|||
self.repeating
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_repeating(&mut self, repeating: bool) {
|
||||
if !self.repeating && repeating && self.finished {
|
||||
self.elapsed = 0.0;
|
||||
self.finished = self.just_finished();
|
||||
}
|
||||
self.repeating = repeating
|
||||
}
|
||||
|
||||
|
@ -102,20 +116,24 @@ impl Timer {
|
|||
if self.paused {
|
||||
return self;
|
||||
}
|
||||
|
||||
let prev_finished = self.finished;
|
||||
self.elapsed += delta;
|
||||
|
||||
self.finished = self.elapsed >= self.duration;
|
||||
self.just_finished = !prev_finished && self.finished;
|
||||
|
||||
if self.finished {
|
||||
if self.repeating {
|
||||
// Count the number of times the timer will wrap around from this tick
|
||||
self.just_finished_count = (self.elapsed / self.duration) as u32;
|
||||
// Repeating timers wrap around
|
||||
self.elapsed %= self.duration;
|
||||
} else {
|
||||
self.just_finished_count = if prev_finished { 0 } else { 1 };
|
||||
// Non-repeating timers clamp to duration
|
||||
self.elapsed = self.duration;
|
||||
}
|
||||
} else {
|
||||
self.just_finished_count = 0;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -123,7 +141,7 @@ impl Timer {
|
|||
#[inline]
|
||||
pub fn reset(&mut self) {
|
||||
self.finished = false;
|
||||
self.just_finished = false;
|
||||
self.just_finished_count = 0;
|
||||
self.elapsed = 0.0;
|
||||
}
|
||||
|
||||
|
@ -151,6 +169,7 @@ mod tests {
|
|||
assert_eq!(t.duration(), 10.0);
|
||||
assert_eq!(t.finished(), false);
|
||||
assert_eq!(t.just_finished(), false);
|
||||
assert_eq!(t.just_finished_count(), 0);
|
||||
assert_eq!(t.repeating(), false);
|
||||
assert_eq!(t.percent(), 0.025);
|
||||
assert_eq!(t.percent_left(), 0.975);
|
||||
|
@ -161,6 +180,7 @@ mod tests {
|
|||
assert_eq!(t.duration(), 10.0);
|
||||
assert_eq!(t.finished(), false);
|
||||
assert_eq!(t.just_finished(), false);
|
||||
assert_eq!(t.just_finished_count(), 0);
|
||||
assert_eq!(t.repeating(), false);
|
||||
assert_eq!(t.percent(), 0.025);
|
||||
assert_eq!(t.percent_left(), 0.975);
|
||||
|
@ -170,6 +190,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed(), 10.0);
|
||||
assert_eq!(t.finished(), true);
|
||||
assert_eq!(t.just_finished(), true);
|
||||
assert_eq!(t.just_finished_count(), 1);
|
||||
assert_eq!(t.percent(), 1.0);
|
||||
assert_eq!(t.percent_left(), 0.0);
|
||||
// Continuing to tick when finished should only change just_finished
|
||||
|
@ -177,6 +198,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed(), 10.0);
|
||||
assert_eq!(t.finished(), true);
|
||||
assert_eq!(t.just_finished(), false);
|
||||
assert_eq!(t.just_finished_count(), 0);
|
||||
assert_eq!(t.percent(), 1.0);
|
||||
assert_eq!(t.percent_left(), 0.0);
|
||||
}
|
||||
|
@ -190,14 +212,16 @@ mod tests {
|
|||
assert_eq!(t.duration(), 2.0);
|
||||
assert_eq!(t.finished(), false);
|
||||
assert_eq!(t.just_finished(), false);
|
||||
assert_eq!(t.just_finished_count(), 0);
|
||||
assert_eq!(t.repeating(), true);
|
||||
assert_eq!(t.percent(), 0.375);
|
||||
assert_eq!(t.percent_left(), 0.625);
|
||||
// Tick past the end and make sure elapsed wraps
|
||||
t.tick(1.5);
|
||||
t.tick(3.5);
|
||||
assert_eq!(t.elapsed(), 0.25);
|
||||
assert_eq!(t.finished(), true);
|
||||
assert_eq!(t.just_finished(), true);
|
||||
assert_eq!(t.just_finished_count(), 2);
|
||||
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
|
||||
|
@ -205,6 +229,7 @@ mod tests {
|
|||
assert_eq!(t.elapsed(), 1.25);
|
||||
assert_eq!(t.finished(), false);
|
||||
assert_eq!(t.just_finished(), false);
|
||||
assert_eq!(t.just_finished_count(), 0);
|
||||
assert_eq!(t.percent(), 0.625);
|
||||
assert_eq!(t.percent_left(), 0.375);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue