2021-03-05 19:59:14 +00:00
|
|
|
use crate::Stopwatch;
|
2022-05-03 19:20:13 +00:00
|
|
|
use bevy_reflect::prelude::*;
|
2020-11-22 00:38:24 +00:00
|
|
|
use bevy_utils::Duration;
|
2020-06-04 02:53:41 +00:00
|
|
|
|
2020-08-09 23:13:04 +00:00
|
|
|
/// Tracks elapsed time. Enters the finished state once `duration` is reached.
|
2020-08-21 21:57:25 +00:00
|
|
|
///
|
|
|
|
/// Non repeating timers will stop tracking and stay in the finished state until reset.
|
2021-03-11 00:27:30 +00:00
|
|
|
/// 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.
|
2020-11-26 19:25:36 +00:00
|
|
|
///
|
|
|
|
/// Paused timers will not have elapsed time increased.
|
2022-02-03 23:56:57 +00:00
|
|
|
#[derive(Clone, Debug, Default, Reflect)]
|
2022-05-03 19:20:13 +00:00
|
|
|
#[reflect(Default)]
|
2020-06-04 02:53:41 +00:00
|
|
|
pub struct Timer {
|
2021-03-05 19:59:14 +00:00
|
|
|
stopwatch: Stopwatch,
|
|
|
|
duration: Duration,
|
2020-11-26 19:25:36 +00:00
|
|
|
repeating: bool,
|
2021-03-05 19:59:14 +00:00
|
|
|
finished: bool,
|
2022-04-26 18:42:42 +00:00
|
|
|
times_finished_this_tick: u32,
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Timer {
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Creates a new timer with a given duration.
|
|
|
|
///
|
|
|
|
/// See also [`Timer::from_seconds`](Timer::from_seconds).
|
2020-08-21 21:57:25 +00:00
|
|
|
pub fn new(duration: Duration, repeating: bool) -> Self {
|
2021-03-05 19:59:14 +00:00
|
|
|
Self {
|
|
|
|
duration,
|
2020-08-21 21:57:25 +00:00
|
|
|
repeating,
|
2020-06-04 02:53:41 +00:00
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
2020-07-28 21:24:03 +00:00
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Creates a new timer with a given duration in seconds.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// ```
|
|
|
|
pub fn from_seconds(duration: f32, repeating: bool) -> Self {
|
|
|
|
Self {
|
|
|
|
duration: Duration::from_secs_f32(duration),
|
2020-08-21 21:57:25 +00:00
|
|
|
repeating,
|
2020-06-04 02:53:41 +00:00
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns `true` if the timer has reached its duration.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// assert!(timer.finished());
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert!(timer.finished());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn finished(&self) -> bool {
|
|
|
|
self.finished
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns `true` only on the tick the timer reached its duration.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// assert!(timer.just_finished());
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert!(!timer.just_finished());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn just_finished(&self) -> bool {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick > 0
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-01-19 22:41:37 +00:00
|
|
|
/// 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.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::elapsed`](Stopwatch::elapsed).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.elapsed(), Duration::from_secs_f32(0.5));
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn elapsed(&self) -> Duration {
|
|
|
|
self.stopwatch.elapsed()
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the time elapsed on the timer as a `f32`.
|
|
|
|
/// See also [`Timer::elapsed`](Timer::elapsed).
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn elapsed_secs(&self) -> f32 {
|
|
|
|
self.stopwatch.elapsed_secs()
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Sets the elapsed time of the timer without any other considerations.
|
2020-11-26 19:25:36 +00:00
|
|
|
///
|
2021-03-05 19:59:14 +00:00
|
|
|
/// See also [`Stopwatch::set`](Stopwatch::set).
|
|
|
|
///
|
|
|
|
/// #
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.set_elapsed(Duration::from_secs(2));
|
|
|
|
/// assert_eq!(timer.elapsed(), Duration::from_secs(2));
|
|
|
|
/// // the timer is not finished even if the elapsed time is greater than the duration.
|
|
|
|
/// assert!(!timer.finished());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn set_elapsed(&mut self, time: Duration) {
|
|
|
|
self.stopwatch.set_elapsed(time);
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the duration of the timer.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let timer = Timer::new(Duration::from_secs(1), false);
|
|
|
|
/// assert_eq!(timer.duration(), Duration::from_secs(1));
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn duration(&self) -> Duration {
|
|
|
|
self.duration
|
2021-01-19 22:41:37 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Sets the duration of the timer.
|
2021-01-19 22:41:37 +00:00
|
|
|
///
|
2021-03-05 19:59:14 +00:00
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.5, false);
|
|
|
|
/// timer.set_duration(Duration::from_secs(1));
|
|
|
|
/// assert_eq!(timer.duration(), Duration::from_secs(1));
|
|
|
|
/// ```
|
2021-01-19 22:41:37 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn set_duration(&mut self, duration: Duration) {
|
|
|
|
self.duration = duration;
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns `true` if the timer is repeating.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, true);
|
|
|
|
/// assert!(timer.repeating());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2020-11-27 19:39:33 +00:00
|
|
|
pub fn repeating(&self) -> bool {
|
2020-11-26 19:25:36 +00:00
|
|
|
self.repeating
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Sets whether the timer is repeating or not.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, true);
|
|
|
|
/// timer.set_repeating(false);
|
|
|
|
/// assert!(!timer.repeating());
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
2020-11-26 19:25:36 +00:00
|
|
|
pub fn set_repeating(&mut self, repeating: bool) {
|
2021-01-19 22:41:37 +00:00
|
|
|
if !self.repeating && repeating && self.finished {
|
2021-03-05 19:59:14 +00:00
|
|
|
self.stopwatch.reset();
|
2021-01-19 22:41:37 +00:00
|
|
|
self.finished = self.just_finished();
|
|
|
|
}
|
2022-02-13 22:33:55 +00:00
|
|
|
self.repeating = repeating;
|
2020-11-26 19:25:36 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Advance the timer by `delta` seconds.
|
|
|
|
/// Non repeating timer will clamp at duration.
|
|
|
|
/// Repeating timer will wrap around.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::tick`](Stopwatch::tick).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// let mut repeating = Timer::from_seconds(1.0, true);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// repeating.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 1.0);
|
|
|
|
/// assert_eq!(repeating.elapsed_secs(), 0.5);
|
|
|
|
/// ```
|
|
|
|
pub fn tick(&mut self, delta: Duration) -> &Self {
|
|
|
|
if self.paused() {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
|
|
|
if self.repeating() {
|
|
|
|
self.finished = false;
|
|
|
|
}
|
2020-11-27 19:39:33 +00:00
|
|
|
return self;
|
|
|
|
}
|
2021-01-19 22:41:37 +00:00
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
if !self.repeating() && self.finished() {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
2021-03-05 19:59:14 +00:00
|
|
|
return self;
|
|
|
|
}
|
2020-11-27 19:39:33 +00:00
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
self.stopwatch.tick(delta);
|
|
|
|
self.finished = self.elapsed() >= self.duration();
|
|
|
|
|
|
|
|
if self.finished() {
|
|
|
|
if self.repeating() {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick =
|
2021-06-26 19:49:34 +00:00
|
|
|
(self.elapsed().as_nanos() / self.duration().as_nanos()) as u32;
|
2021-03-05 19:59:14 +00:00
|
|
|
// Duration does not have a modulo
|
2022-04-26 18:42:42 +00:00
|
|
|
self.set_elapsed(self.elapsed() - self.duration() * self.times_finished_this_tick);
|
2020-11-26 00:43:16 +00:00
|
|
|
} else {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 1;
|
2021-03-05 19:59:14 +00:00
|
|
|
self.set_elapsed(self.duration());
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
2021-01-19 22:41:37 +00:00
|
|
|
} else {
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
2021-03-05 19:59:14 +00:00
|
|
|
|
2020-11-13 02:03:03 +00:00
|
|
|
self
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Pauses the Timer. Disables the ticking of the timer.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::pause`](Stopwatch::pause).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.pause();
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 0.0);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn pause(&mut self) {
|
|
|
|
self.stopwatch.pause();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Unpauses the Timer. Resumes the ticking of the timer.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::unpause()`](Stopwatch::unpause).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.pause();
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// timer.unpause();
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 0.5);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn unpause(&mut self) {
|
|
|
|
self.stopwatch.unpause();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if the timer is paused.
|
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::paused`](Stopwatch::paused).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// assert!(!timer.paused());
|
|
|
|
/// timer.pause();
|
|
|
|
/// assert!(timer.paused());
|
|
|
|
/// timer.unpause();
|
|
|
|
/// assert!(!timer.paused());
|
|
|
|
/// ```
|
2020-11-26 19:25:36 +00:00
|
|
|
#[inline]
|
2021-03-05 19:59:14 +00:00
|
|
|
pub fn paused(&self) -> bool {
|
|
|
|
self.stopwatch.paused()
|
|
|
|
}
|
|
|
|
|
2022-09-18 23:36:05 +00:00
|
|
|
/// Resets the timer. The reset doesn't affect the `paused` state of the timer.
|
2021-03-05 19:59:14 +00:00
|
|
|
///
|
|
|
|
/// See also [`Stopwatch::reset`](Stopwatch::reset).
|
|
|
|
///
|
|
|
|
/// Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(1.5));
|
|
|
|
/// timer.reset();
|
|
|
|
/// assert!(!timer.finished());
|
|
|
|
/// assert!(!timer.just_finished());
|
|
|
|
/// assert_eq!(timer.elapsed_secs(), 0.0);
|
|
|
|
/// ```
|
2020-06-04 02:53:41 +00:00
|
|
|
pub fn reset(&mut self) {
|
2021-03-05 19:59:14 +00:00
|
|
|
self.stopwatch.reset();
|
2020-06-04 02:53:41 +00:00
|
|
|
self.finished = false;
|
2022-04-26 18:42:42 +00:00
|
|
|
self.times_finished_this_tick = 0;
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
2020-11-26 00:43:16 +00:00
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the percentage of the timer elapsed time (goes from 0.0 to 1.0).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(2.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.percent(), 0.25);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
2020-11-26 00:43:16 +00:00
|
|
|
pub fn percent(&self) -> f32 {
|
2021-03-05 19:59:14 +00:00
|
|
|
self.elapsed().as_secs_f32() / self.duration().as_secs_f32()
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the percentage of the timer remaining time (goes from 0.0 to 1.0).
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(2.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.percent_left(), 0.75);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
2020-11-26 00:43:16 +00:00
|
|
|
pub fn percent_left(&self) -> f32 {
|
2021-03-05 19:59:14 +00:00
|
|
|
1.0 - self.percent()
|
|
|
|
}
|
|
|
|
|
2022-09-14 18:57:13 +00:00
|
|
|
/// Returns the remaining time in seconds
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
|
|
|
/// # use bevy_time::*;
|
|
|
|
/// use std::cmp::Ordering;
|
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(2.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// let result = timer.remaining_secs().total_cmp(&1.5);
|
|
|
|
/// assert_eq!(Ordering::Equal, result);
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn remaining_secs(&self) -> f32 {
|
|
|
|
self.remaining().as_secs_f32()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the remaining time using Duration
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
|
|
|
/// # use bevy_time::*;
|
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(2.0, false);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
|
|
|
/// assert_eq!(timer.remaining(), Duration::from_secs_f32(1.5));
|
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn remaining(&self) -> Duration {
|
|
|
|
self.duration() - self.elapsed()
|
|
|
|
}
|
|
|
|
|
2021-03-05 19:59:14 +00:00
|
|
|
/// Returns the number of times a repeating timer
|
|
|
|
/// finished during the last [`tick`](Timer<T>::tick) call.
|
|
|
|
///
|
|
|
|
/// For non repeating-timers, this method will only ever
|
|
|
|
/// return 0 or 1.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
/// ```
|
2022-05-26 00:27:18 +00:00
|
|
|
/// # use bevy_time::*;
|
2021-03-05 19:59:14 +00:00
|
|
|
/// use std::time::Duration;
|
|
|
|
/// let mut timer = Timer::from_seconds(1.0, true);
|
|
|
|
/// timer.tick(Duration::from_secs_f32(6.0));
|
2022-04-26 18:42:42 +00:00
|
|
|
/// assert_eq!(timer.times_finished_this_tick(), 6);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(2.0));
|
2022-04-26 18:42:42 +00:00
|
|
|
/// assert_eq!(timer.times_finished_this_tick(), 2);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// timer.tick(Duration::from_secs_f32(0.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
/// assert_eq!(timer.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2022-04-26 18:42:42 +00:00
|
|
|
pub fn times_finished_this_tick(&self) -> u32 {
|
|
|
|
self.times_finished_this_tick
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|
2020-06-04 02:53:41 +00:00
|
|
|
}
|
|
|
|
|
2020-11-26 00:43:16 +00:00
|
|
|
#[cfg(test)]
|
2021-02-22 08:42:19 +00:00
|
|
|
#[allow(clippy::float_cmp)]
|
2020-11-26 00:43:16 +00:00
|
|
|
mod tests {
|
2021-03-05 19:59:14 +00:00
|
|
|
use super::*;
|
2020-11-26 00:43:16 +00:00
|
|
|
|
|
|
|
#[test]
|
2021-03-05 19:59:14 +00:00
|
|
|
fn non_repeating_timer() {
|
2020-11-26 00:43:16 +00:00
|
|
|
let mut t = Timer::from_seconds(10.0, false);
|
|
|
|
// Tick once, check all attributes
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(0.25));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.25);
|
|
|
|
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.repeating());
|
2020-11-27 19:39:33 +00:00
|
|
|
assert_eq!(t.percent(), 0.025);
|
|
|
|
assert_eq!(t.percent_left(), 0.975);
|
|
|
|
// Ticking while paused changes nothing
|
|
|
|
t.pause();
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(500.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.25);
|
|
|
|
assert_eq!(t.duration(), Duration::from_secs_f32(10.0));
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.repeating());
|
2020-11-26 00:43:16 +00:00
|
|
|
assert_eq!(t.percent(), 0.025);
|
|
|
|
assert_eq!(t.percent_left(), 0.975);
|
|
|
|
// Tick past the end and make sure elapsed doesn't go past 0.0 and other things update
|
2020-11-27 19:39:33 +00:00
|
|
|
t.unpause();
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(500.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 10.0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.finished());
|
|
|
|
assert!(t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 1);
|
2020-11-26 00:43:16 +00:00
|
|
|
assert_eq!(t.percent(), 1.0);
|
|
|
|
assert_eq!(t.percent_left(), 0.0);
|
|
|
|
// Continuing to tick when finished should only change just_finished
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 10.0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2020-11-26 00:43:16 +00:00
|
|
|
assert_eq!(t.percent(), 1.0);
|
|
|
|
assert_eq!(t.percent_left(), 0.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2021-03-05 19:59:14 +00:00
|
|
|
fn repeating_timer() {
|
2020-11-26 00:43:16 +00:00
|
|
|
let mut t = Timer::from_seconds(2.0, true);
|
|
|
|
// Tick once, check all attributes
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(0.75));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.75);
|
|
|
|
assert_eq!(t.duration(), Duration::from_secs_f32(2.0));
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.repeating());
|
2020-11-26 00:43:16 +00:00
|
|
|
assert_eq!(t.percent(), 0.375);
|
|
|
|
assert_eq!(t.percent_left(), 0.625);
|
|
|
|
// Tick past the end and make sure elapsed wraps
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.5));
|
|
|
|
assert_eq!(t.elapsed_secs(), 0.25);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(t.finished());
|
|
|
|
assert!(t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 1);
|
2020-11-26 00:43:16 +00:00
|
|
|
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
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.0));
|
|
|
|
assert_eq!(t.elapsed_secs(), 1.25);
|
2021-06-18 00:08:39 +00:00
|
|
|
assert!(!t.finished());
|
|
|
|
assert!(!t.just_finished());
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2020-11-26 00:43:16 +00:00
|
|
|
assert_eq!(t.percent(), 0.625);
|
|
|
|
assert_eq!(t.percent_left(), 0.375);
|
|
|
|
}
|
2021-03-05 19:59:14 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn times_finished_repeating() {
|
|
|
|
let mut t = Timer::from_seconds(1.0, true);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(3.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 3);
|
2021-03-05 19:59:14 +00:00
|
|
|
assert_eq!(t.elapsed_secs(), 0.5);
|
|
|
|
assert!(t.finished());
|
|
|
|
assert!(t.just_finished());
|
|
|
|
t.tick(Duration::from_secs_f32(0.2));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2022-04-26 18:42:42 +00:00
|
|
|
fn times_finished_this_tick() {
|
2021-03-05 19:59:14 +00:00
|
|
|
let mut t = Timer::from_seconds(1.0, false);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(1.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 1);
|
2021-03-05 19:59:14 +00:00
|
|
|
t.tick(Duration::from_secs_f32(0.5));
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 0);
|
2021-03-05 19:59:14 +00:00
|
|
|
}
|
2021-06-26 19:49:34 +00:00
|
|
|
|
|
|
|
#[test]
|
2022-04-26 18:42:42 +00:00
|
|
|
fn times_finished_this_tick_precise() {
|
2021-06-26 19:49:34 +00:00
|
|
|
let mut t = Timer::from_seconds(0.01, true);
|
2022-01-28 16:17:54 +00:00
|
|
|
let duration = Duration::from_secs_f64(0.333);
|
2021-06-26 19:49:34 +00:00
|
|
|
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 0.333 => 33 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 33);
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 0.666 => 33 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 33);
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 0.999 => 33 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
assert_eq!(t.times_finished_this_tick(), 33);
|
2022-01-28 16:17:54 +00:00
|
|
|
// total duration: 1.332 => 34 times finished
|
2021-06-26 19:49:34 +00:00
|
|
|
t.tick(duration);
|
2022-04-26 18:42:42 +00:00
|
|
|
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());
|
2021-06-26 19:49:34 +00:00
|
|
|
}
|
2020-11-26 00:43:16 +00:00
|
|
|
}
|