Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow timers to be paused #914

Merged
merged 9 commits into from
Nov 26, 2020
1 change: 0 additions & 1 deletion crates/bevy_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ impl Plugin for CorePlugin {
.register_property::<Quat>()
.register_property::<Option<String>>()
.add_system_to_stage(stage::FIRST, time_system)
.add_system_to_stage(stage::FIRST, timer_system)
.add_system_to_stage(stage::PRE_UPDATE, entity_labels_system);
}
}
86 changes: 70 additions & 16 deletions crates/bevy_core/src/time/timer.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
use crate::time::Time;
use bevy_ecs::prelude::*;
use bevy_property::Properties;
use bevy_utils::Duration;

/// Tracks elapsed time. Enters the finished state once `duration` is reached.
///
/// 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.
///
/// Paused timers will not have elapsed time increased.
#[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,
elapsed: f32,
duration: f32,
finished: bool,
/// Will only be true on the tick `duration` is reached or exceeded.
pub just_finished: bool,
pub repeating: bool,
just_finished: bool,
paused: bool,
repeating: bool,
}

impl Timer {
Expand All @@ -37,6 +35,67 @@ impl Timer {
}
}

#[inline]
pub fn pause(&mut self) {
ambeeeeee marked this conversation as resolved.
Show resolved Hide resolved
self.paused = true
}

#[inline]
pub fn resume(&mut self) {
self.paused = false
}

#[inline]
pub fn is_paused(&self) -> bool {
self.paused
}

/// Returns the time elapsed on the timer. Guaranteed to be between 0.0 and `duration`, inclusive.
#[inline]
pub fn elapsed(&self) -> f32 {
self.elapsed
}

#[inline]
pub fn set_elapsed(&mut self, elapsed: f32) {
self.elapsed = elapsed
}

#[inline]
pub fn duration(&self) -> f32 {
self.duration
}

#[inline]
pub fn set_duration(&mut self, duration: f32) {
self.duration = duration
}

/// 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.
#[inline]
pub fn is_finished(&self) -> bool {
self.finished
}

/// 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
}

#[inline]
pub fn is_repeating(&self) -> bool {
self.repeating
}

#[inline]
pub fn set_repeating(&mut self, repeating: bool) {
self.repeating = repeating
}

/// Advances the timer by `delta` seconds.
pub fn tick(&mut self, delta: f32) -> &Self {
let prev_finished = self.finished;
Expand All @@ -56,6 +115,7 @@ impl Timer {
self
}

#[inline]
pub fn reset(&mut self) {
self.finished = false;
self.just_finished = false;
Expand All @@ -73,12 +133,6 @@ impl Timer {
}
}

pub(crate) fn timer_system(time: Res<Time>, mut query: Query<&mut Timer>) {
for mut timer in query.iter_mut() {
timer.tick(time.delta_seconds);
}
}

#[cfg(test)]
mod tests {
use super::Timer;
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_diagnostic/src/print_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl PrintDiagnosticsPlugin {
time: Res<Time>,
diagnostics: Res<Diagnostics>,
) {
if state.timer.tick(time.delta_seconds).finished {
if state.timer.tick(time.delta_seconds).is_finished() {
println!("Diagnostics:");
println!("{}", "-".repeat(93));
if let Some(ref filter) = state.filter {
Expand All @@ -86,7 +86,7 @@ impl PrintDiagnosticsPlugin {
time: Res<Time>,
diagnostics: Res<Diagnostics>,
) {
if state.timer.tick(time.delta_seconds).finished {
if state.timer.tick(time.delta_seconds).is_finished() {
println!("Diagnostics (Debug):");
println!("{}", "-".repeat(93));
if let Some(ref filter) = state.filter {
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/contributors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn select_system(
) {
let mut timer_fired = false;
for mut t in tq.iter_mut() {
if !t.just_finished {
if !t.just_finished() {
continue;
}
t.reset();
Expand Down
2 changes: 1 addition & 1 deletion examples/2d/sprite_sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn animate_sprite_system(
mut query: Query<(&mut Timer, &mut TextureAtlasSprite, &Handle<TextureAtlas>)>,
) {
for (timer, mut sprite, texture_atlas_handle) in query.iter_mut() {
if timer.finished {
if timer.is_finished() {
let texture_atlas = texture_atlases.get(texture_atlas_handle).unwrap();
sprite.index = ((sprite.index as usize + 1) % texture_atlas.textures.len()) as u32;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/app/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ struct PrintMessageState {
}

fn print_message_system(mut state: ResMut<PrintMessageState>, time: Res<Time>) {
if state.timer.tick(time.delta_seconds).finished {
if state.timer.tick(time.delta_seconds).is_finished() {
println!("{}", state.message);
}
}
2 changes: 1 addition & 1 deletion examples/ecs/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn event_trigger_system(
mut state: ResMut<EventTriggerState>,
mut my_events: ResMut<Events<MyEvent>>,
) {
if state.event_timer.tick(time.delta_seconds).finished {
if state.event_timer.tick(time.delta_seconds).is_finished() {
my_events.send(MyEvent {
message: "MyEvent just happened!".to_string(),
});
Expand Down
2 changes: 1 addition & 1 deletion examples/ui/font_atlas_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn atlas_render_system(
}

fn text_update_system(mut state: ResMut<State>, time: Res<Time>, mut query: Query<&mut Text>) {
if state.timer.tick(time.delta_seconds).finished {
if state.timer.tick(time.delta_seconds).is_finished() {
for mut text in query.iter_mut() {
let c = rand::random::<u8>() as char;
if !text.value.contains(c) {
Expand Down