Timer Resource/Component

This commit is contained in:
Carter Anderson 2020-06-03 19:53:41 -07:00
parent 5927bad382
commit a4c15f96de
10 changed files with 94 additions and 48 deletions

View File

@ -6,6 +6,7 @@ edition = "2018"
[dependencies] [dependencies]
bevy_app = { path = "../bevy_app" } bevy_app = { path = "../bevy_app" }
bevy_property = { path = "../bevy_property" }
bevy_type_registry = { path = "../bevy_type_registry" } bevy_type_registry = { path = "../bevy_type_registry" }
bevy_transform = { path = "../bevy_transform" } bevy_transform = { path = "../bevy_transform" }
legion = { path = "../bevy_legion" } legion = { path = "../bevy_legion" }

View File

@ -12,7 +12,7 @@ use bevy_transform::{
}; };
use glam::{Mat3, Mat4, Quat, Vec2, Vec3}; use glam::{Mat3, Mat4, Quat, Vec2, Vec3};
use legion::prelude::IntoSystem; use legion::prelude::IntoSystem;
use time::{timer_system, Time}; use time::{time_system, Time, Timer, timer_system};
#[derive(Default)] #[derive(Default)]
pub struct CorePlugin; pub struct CorePlugin;
@ -31,11 +31,13 @@ impl AppPlugin for CorePlugin {
.register_component::<Rotation>() .register_component::<Rotation>()
.register_component::<Scale>() .register_component::<Scale>()
.register_component::<NonUniformScale>() .register_component::<NonUniformScale>()
.register_component::<Timer>()
.register_property_type::<Vec2>() .register_property_type::<Vec2>()
.register_property_type::<Vec3>() .register_property_type::<Vec3>()
.register_property_type::<Mat3>() .register_property_type::<Mat3>()
.register_property_type::<Mat4>() .register_property_type::<Mat4>()
.register_property_type::<Quat>() .register_property_type::<Quat>()
.add_system_to_stage(stage::FIRST, time_system.system())
.add_system_to_stage(stage::FIRST, timer_system.system()); .add_system_to_stage(stage::FIRST, timer_system.system());
} }
} }

View File

@ -0,0 +1,5 @@
mod time;
mod timer;
pub use time::*;
pub use timer::*;

View File

@ -29,12 +29,12 @@ impl Time {
if let Some(instant) = self.instant { if let Some(instant) = self.instant {
self.delta = now - instant; self.delta = now - instant;
self.delta_seconds_f64 = self.delta_seconds_f64 =
self.delta.as_secs() as f64 + (self.delta.subsec_nanos() as f64 / 1.0e9); self.delta.as_secs_f64();
self.delta_seconds = self.delta_seconds_f64 as f32; self.delta_seconds = self.delta.as_secs_f32();
} }
let duration_since_startup = now - self.startup; let duration_since_startup = now - self.startup;
self.seconds_since_startup = duration_since_startup.as_secs() as f64 + (duration_since_startup.subsec_nanos() as f64 / 1.0e9); self.seconds_since_startup = duration_since_startup.as_secs_f64();
self.instant = Some(now); self.instant = Some(now);
} }
@ -43,6 +43,6 @@ impl Time {
} }
} }
pub fn timer_system(mut time: ResMut<Time>) { pub fn time_system(mut time: ResMut<Time>) {
time.update(); time.update();
} }

View File

@ -0,0 +1,42 @@
use std::time::Duration;
use bevy_property::Properties;
use legion::prelude::{Res, ComMut};
use crate::time::Time;
#[derive(Clone, Debug, Default, Properties)]
pub struct Timer {
pub elapsed: f32,
pub duration: f32,
pub finished: bool,
}
impl Timer {
pub fn from_seconds(seconds: f32) -> Self {
Timer {
duration: seconds,
..Default::default()
}
}
pub fn new(duration: Duration) -> Self {
Timer {
duration: duration.as_secs_f32(),
..Default::default()
}
}
pub fn tick(&mut self, delta: f32) {
self.elapsed = (self.elapsed + delta).min(self.duration);
if self.elapsed >= self.duration {
self.finished = true;
}
}
pub fn reset(&mut self) {
self.finished = false;
self.elapsed = 0.0;
}
}
pub fn timer_system(time: Res<Time>, mut timer: ComMut<Timer>) {
timer.tick(time.delta_seconds);
}

View File

@ -1,6 +1,6 @@
use super::{Diagnostic, DiagnosticId, Diagnostics}; use super::{Diagnostic, DiagnosticId, Diagnostics};
use bevy_app::{stage, AppPlugin}; use bevy_app::{stage, AppPlugin};
use bevy_core::time::Time; use bevy_core::time::{Timer, Time};
use legion::prelude::*; use legion::prelude::*;
use std::time::Duration; use std::time::Duration;
@ -11,8 +11,7 @@ pub struct PrintDiagnosticsPlugin {
} }
pub struct PrintDiagnosticsState { pub struct PrintDiagnosticsState {
elapsed: f64, timer: Timer,
wait_seconds: f64,
filter: Option<Vec<DiagnosticId>>, filter: Option<Vec<DiagnosticId>>,
} }
@ -29,8 +28,7 @@ impl Default for PrintDiagnosticsPlugin {
impl AppPlugin for PrintDiagnosticsPlugin { impl AppPlugin for PrintDiagnosticsPlugin {
fn build(&self, app: &mut bevy_app::AppBuilder) { fn build(&self, app: &mut bevy_app::AppBuilder) {
app.add_resource(PrintDiagnosticsState { app.add_resource(PrintDiagnosticsState {
elapsed: 0.0, timer: Timer::new(self.wait_duration),
wait_seconds: self.wait_duration.as_secs_f64(),
filter: self.filter.clone(), filter: self.filter.clone(),
}); });
@ -69,9 +67,8 @@ impl PrintDiagnosticsPlugin {
time: Res<Time>, time: Res<Time>,
diagnostics: Res<Diagnostics>, diagnostics: Res<Diagnostics>,
) { ) {
state.elapsed += time.delta_seconds_f64; state.timer.tick(time.delta_seconds);
if state.elapsed >= state.wait_seconds { if state.timer.finished {
state.elapsed = 0.0;
println!("Diagnostics:"); println!("Diagnostics:");
println!("{}", "-".repeat(60)); println!("{}", "-".repeat(60));
if let Some(ref filter) = state.filter { if let Some(ref filter) = state.filter {
@ -83,6 +80,8 @@ impl PrintDiagnosticsPlugin {
Self::print_diagnostic(diagnostic); Self::print_diagnostic(diagnostic);
} }
} }
state.timer.reset();
} }
} }
@ -91,9 +90,8 @@ impl PrintDiagnosticsPlugin {
time: Res<Time>, time: Res<Time>,
diagnostics: Res<Diagnostics>, diagnostics: Res<Diagnostics>,
) { ) {
state.elapsed += time.delta_seconds_f64; state.timer.tick(time.delta_seconds);
if state.elapsed >= state.wait_seconds { if state.timer.finished {
state.elapsed = 0.0;
println!("Diagnostics (Debug):"); println!("Diagnostics (Debug):");
println!("{}", "-".repeat(60)); println!("{}", "-".repeat(60));
if let Some(ref filter) = state.filter { if let Some(ref filter) = state.filter {
@ -105,6 +103,8 @@ impl PrintDiagnosticsPlugin {
println!("{:#?}\n", diagnostic); println!("{:#?}\n", diagnostic);
} }
} }
state.timer.reset();
} }
} }
} }

View File

@ -1,33 +1,23 @@
use bevy::{input::system::exit_on_esc_system, prelude::*}; use bevy::prelude::*;
use bevy_sprite::{SpriteSheet, SpriteSheetSprite};
fn main() { fn main() {
App::build() App::build()
.init_resource::<State>()
.add_default_plugins() .add_default_plugins()
.add_startup_system(setup.system()) .add_startup_system(setup.system())
.init_system(exit_on_esc_system)
.add_system(animate_sprite_system.system()) .add_system(animate_sprite_system.system())
.run(); .run();
} }
#[derive(Default)]
struct State {
elapsed: f32,
}
fn animate_sprite_system( fn animate_sprite_system(
mut state: ResMut<State>,
time: Res<Time>,
sprite_sheets: Res<Assets<SpriteSheet>>, sprite_sheets: Res<Assets<SpriteSheet>>,
mut timer: ComMut<Timer>,
mut sprite: ComMut<SpriteSheetSprite>, mut sprite: ComMut<SpriteSheetSprite>,
sprite_sheet_handle: Com<Handle<SpriteSheet>>, sprite_sheet_handle: Com<Handle<SpriteSheet>>,
) { ) {
state.elapsed += time.delta_seconds; if timer.finished {
if state.elapsed > 0.1 {
state.elapsed = 0.0;
let sprite_sheet = sprite_sheets.get(&sprite_sheet_handle).unwrap(); let sprite_sheet = sprite_sheets.get(&sprite_sheet_handle).unwrap();
sprite.index = ((sprite.index as usize + 1) % sprite_sheet.sprites.len()) as u32; sprite.index = ((sprite.index as usize + 1) % sprite_sheet.sprites.len()) as u32;
timer.reset();
} }
} }
@ -55,5 +45,6 @@ fn setup(
position: Vec3::new(0.0, 0.0, -0.5), position: Vec3::new(0.0, 0.0, -0.5),
}, },
..Default::default() ..Default::default()
}); })
.add(Timer::from_seconds(0.1));
} }

View File

@ -26,8 +26,7 @@ impl AppPlugin for PrintMessagePlugin {
fn build(&self, app: &mut AppBuilder) { fn build(&self, app: &mut AppBuilder) {
let state = PrintMessageState { let state = PrintMessageState {
message: self.message.clone(), message: self.message.clone(),
elapsed_time: 0.0, timer: Timer::new(self.wait_duration),
duration: self.wait_duration,
}; };
app.add_resource(state) app.add_resource(state)
.add_system(print_message_system.system()); .add_system(print_message_system.system());
@ -36,14 +35,13 @@ impl AppPlugin for PrintMessagePlugin {
struct PrintMessageState { struct PrintMessageState {
message: String, message: String,
duration: Duration, timer: Timer,
elapsed_time: f32,
} }
fn print_message_system(time: Res<Time>, mut state: ResMut<PrintMessageState>) { fn print_message_system(mut state: ResMut<PrintMessageState>, time: Res<Time>) {
state.elapsed_time += time.delta_seconds; state.timer.tick(time.delta_seconds);
if state.elapsed_time > state.duration.as_secs_f32() { if state.timer.finished {
println!("{}", state.message); println!("{}", state.message);
state.elapsed_time = 0.0; state.timer.reset();
} }
} }

View File

@ -15,24 +15,31 @@ struct MyEvent {
pub message: String, pub message: String,
} }
#[derive(Default)]
struct EventTriggerState { struct EventTriggerState {
elapsed: f32, event_timer: Timer,
}
impl Default for EventTriggerState {
fn default() -> Self {
EventTriggerState {
event_timer: Timer::from_seconds(1.0)
}
}
} }
// sends MyEvent every second // sends MyEvent every second
fn event_trigger_system( fn event_trigger_system(
time: Res<Time>,
mut state: ResMut<EventTriggerState>, mut state: ResMut<EventTriggerState>,
mut my_events: ResMut<Events<MyEvent>>, mut my_events: ResMut<Events<MyEvent>>,
time: Res<Time>,
) { ) {
state.elapsed += time.delta_seconds; state.event_timer.tick(time.delta_seconds);
if state.elapsed > 1.0 { if state.event_timer.finished {
my_events.send(MyEvent { my_events.send(MyEvent {
message: "MyEvent just happened!".to_string(), message: "MyEvent just happened!".to_string(),
}); });
state.elapsed = 0.0; state.event_timer.reset();
} }
} }

View File

@ -2,7 +2,7 @@
pub use crate::asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle}; pub use crate::asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
#[cfg(feature = "core")] #[cfg(feature = "core")]
pub use crate::core::{ pub use crate::core::{
time::Time, time::{Time, Timer},
transform::{CommandBufferBuilderSource, WorldBuilder, WorldBuilderSource}, transform::{CommandBufferBuilderSource, WorldBuilder, WorldBuilderSource},
}; };
#[cfg(feature = "derive")] #[cfg(feature = "derive")]
@ -33,7 +33,7 @@ pub use crate::render::{
#[cfg(feature = "scene")] #[cfg(feature = "scene")]
pub use crate::scene::{Scene, SceneSpawner}; pub use crate::scene::{Scene, SceneSpawner};
#[cfg(feature = "sprite")] #[cfg(feature = "sprite")]
pub use crate::sprite::{ColorMaterial, Quad, Sprite, entity::{SpriteEntity, SpriteSheetEntity}}; pub use crate::sprite::{ColorMaterial, Quad, Sprite, entity::{SpriteEntity, SpriteSheetEntity}, SpriteSheet, SpriteSheetSprite};
#[cfg(feature = "text")] #[cfg(feature = "text")]
pub use crate::text::Font; pub use crate::text::Font;
#[cfg(feature = "transform")] #[cfg(feature = "transform")]