Skip to content

Commit

Permalink
add on_real_time_timer run condition (#10179)
Browse files Browse the repository at this point in the history
# Objective

Fixes #10177 .

## Solution

Added a new run condition and tweaked the docs for `on_timer`.

## Changelog

### Added 
 - `on_real_time_timer` run condition
  • Loading branch information
SecretPocketCat committed Oct 20, 2023
1 parent 4d286d0 commit b1cc7ad
Showing 1 changed file with 38 additions and 2 deletions.
40 changes: 38 additions & 2 deletions crates/bevy_time/src/common_conditions.rs
@@ -1,9 +1,9 @@
use crate::{Time, Timer, TimerMode};
use crate::{Real, Time, Timer, TimerMode};
use bevy_ecs::system::Res;
use bevy_utils::Duration;

/// Run condition that is active on a regular time interval, using [`Time`] to advance
/// the timer.
/// the timer. The timer ticks at the rate of [`Time::relative_speed`].
///
/// ```rust,no_run
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup, Update};
Expand Down Expand Up @@ -38,6 +38,42 @@ pub fn on_timer(duration: Duration) -> impl FnMut(Res<Time>) -> bool + Clone {
}
}

/// Run condition that is active on a regular time interval, using [`Time<Real>`] to advance
/// the timer. The timer ticks are not scaled.
///
/// ```rust,no_run
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup, Update};
/// # use bevy_ecs::schedule::IntoSystemConfigs;
/// # use bevy_utils::Duration;
/// # use bevy_time::common_conditions::on_real_timer;
/// fn main() {
/// App::new()
/// .add_plugins(DefaultPlugins)
/// .add_systems(Update, tick.run_if(on_real_timer(Duration::from_secs(1))))
/// .run();
/// }
/// fn tick() {
/// // ran once a second
/// }
/// ```
///
/// Note that this does **not** guarantee that systems will run at exactly the
/// specified interval. If delta time is larger than the specified `duration` then
/// the system will only run once even though the timer may have completed multiple
/// times. This condition should only be used with large time durations (relative to
/// delta time).
///
/// For more accurate timers, use the [`Timer`] class directly (see
/// [`Timer::times_finished_this_tick`] to address the problem mentioned above), or
/// use fixed timesteps that allow systems to run multiple times per frame.
pub fn on_real_timer(duration: Duration) -> impl FnMut(Res<Time<Real>>) -> bool + Clone {
let mut timer = Timer::new(duration, TimerMode::Repeating);
move |time: Res<Time<Real>>| {
timer.tick(time.delta());
timer.just_finished()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit b1cc7ad

Please sign in to comment.