Skip to content

Commit

Permalink
Added event stages
Browse files Browse the repository at this point in the history
  • Loading branch information
alec-mccormick committed Dec 10, 2020
1 parent 9d3c625 commit 0eb4898
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ path = "examples/diagnostics/print_diagnostics.rs"
name = "event"
path = "examples/ecs/event.rs"

[[example]]
name = "event_stage"
path = "examples/ecs/event_stage.rs"

[[example]]
name = "fixed_timestep"
path = "examples/ecs/fixed_timestep.rs"
Expand Down
90 changes: 90 additions & 0 deletions crates/bevy_app/src/event_stage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use super::event::{EventReader, Events};
use bevy_ecs::{Stage, World, Resources, System, IntoSystem, Local, Res, ShouldRun, SystemStage, IntoChainSystem};
use std::marker::PhantomData;


pub struct EventStage<T> {
inner: SystemStage,
_marker: PhantomData<T>
}

impl<T> Default for EventStage<T>
where
T: Clone + Send + Sync + 'static
{
fn default() -> Self {
Self::parallel()
}
}

impl<T> EventStage<T>
where
T: Clone + Send + Sync + 'static
{
pub fn new(system_stage: SystemStage) -> Self {
let inner = system_stage
.with_run_criteria(event_stage_run_criteria::<T>);

Self {
inner,
_marker: PhantomData
}
}

pub fn serial() -> Self {
Self::new(SystemStage::serial())
}

pub fn parallel() -> Self {
Self::new(SystemStage::parallel())
}

pub fn with_system<S, Params, IntoS>(mut self, system: IntoS) -> Self
where
S: System<Input = T, Output = ()>,
IntoS: IntoSystem<Params, S>,
{
self.inner.add_system_boxed(Box::new(next_event_system.chain(system)));
self
}

pub fn add_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
where
S: System<Input = T, Output = ()>,
IntoS: IntoSystem<Params, S>,
{
self.inner.add_system_boxed(Box::new(next_event_system.chain(system)));
self
}
}

impl<T> Stage for EventStage<T>
where
T: Clone + Send + Sync + 'static
{
fn run(&mut self, world: &mut World, resources: &mut Resources) {
self.inner.run(world, resources)
}
}

/// Execute systems if there exists an event to consume.
fn event_stage_run_criteria<T: Send + Sync + 'static>(
mut reader: Local<EventReader<T>>,
events: Res<Events<T>>
) -> ShouldRun {
if reader.earliest(&events).is_some() {
ShouldRun::YesAndLoop
} else {
ShouldRun::No
}
}

/// Fetch the next event and return it. This system is chained into all systems added to EventStage.
///
/// Unwrap is okay here because this system will only be run if there exists an event to consume
fn next_event_system<T: Clone + Send + Sync + 'static>(
mut reader: Local<EventReader<T>>,
events: Res<Events<T>>
) -> T {
reader.earliest(&events).unwrap().clone()
}
3 changes: 3 additions & 0 deletions crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod startup_stage;
mod app;
mod app_builder;
mod event;
mod event_stage;
mod plugin;
mod plugin_group;
mod schedule_runner;
Expand All @@ -14,6 +15,7 @@ pub use app::*;
pub use app_builder::*;
pub use bevy_derive::DynamicPlugin;
pub use event::*;
pub use event_stage::*;
pub use plugin::*;
pub use plugin_group::*;
pub use schedule_runner::*;
Expand All @@ -23,6 +25,7 @@ pub mod prelude {
app::App,
app_builder::AppBuilder,
event::{EventReader, Events},
event_stage::EventStage,
stage, DynamicPlugin, Plugin, PluginGroup,
};
}

0 comments on commit 0eb4898

Please sign in to comment.