Skip to content

Commit

Permalink
Schedule V2
Browse files Browse the repository at this point in the history
  • Loading branch information
cart committed Dec 12, 2020
1 parent 9239621 commit aecc0bb
Show file tree
Hide file tree
Showing 38 changed files with 1,833 additions and 980 deletions.
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,18 @@ path = "examples/diagnostics/print_diagnostics.rs"
name = "event"
path = "examples/ecs/event.rs"

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

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

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

[[example]]
name = "system_chaining"
path = "examples/ecs/system_chaining.rs"
Expand Down
33 changes: 3 additions & 30 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::app_builder::AppBuilder;
use bevy_ecs::{ParallelExecutor, Resources, Schedule, World};
use bevy_ecs::{Resources, Schedule, Stage, World};
#[cfg(feature = "trace")]
use bevy_utils::tracing::info_span;

Expand Down Expand Up @@ -30,9 +30,6 @@ pub struct App {
pub resources: Resources,
pub runner: Box<dyn Fn(App)>,
pub schedule: Schedule,
pub executor: ParallelExecutor,
pub startup_schedule: Schedule,
pub startup_executor: ParallelExecutor,
}

impl Default for App {
Expand All @@ -41,16 +38,12 @@ impl Default for App {
world: Default::default(),
resources: Default::default(),
schedule: Default::default(),
executor: Default::default(),
startup_schedule: Default::default(),
startup_executor: ParallelExecutor::without_tracker_clears(),
runner: Box::new(run_once),
}
}
}

fn run_once(mut app: App) {
app.initialize();
app.update();
}

Expand All @@ -60,35 +53,15 @@ impl App {
}

pub fn update(&mut self) {
self.schedule
.initialize(&mut self.world, &mut self.resources);
self.executor
.run(&mut self.schedule, &mut self.world, &mut self.resources);
}

pub fn initialize(&mut self) {
#[cfg(feature = "trace")]
let startup_schedule_span = info_span!("startup_schedule");
#[cfg(feature = "trace")]
let _startup_schedule_guard = startup_schedule_span.enter();
self.startup_schedule
.initialize(&mut self.world, &mut self.resources);
self.startup_executor.initialize(&mut self.resources);
self.startup_executor.run(
&mut self.startup_schedule,
&mut self.world,
&mut self.resources,
);
self.schedule.run(&mut self.world, &mut self.resources);
}

pub fn run(mut self) {
#[cfg(feature = "trace")]
let bevy_app_run_span = info_span!("bevy_app_run");
let bevy_app_run_span = info_span!("bevy_app");
#[cfg(feature = "trace")]
let _bevy_app_run_guard = bevy_app_run_span.enter();

self.executor.initialize(&mut self.resources);

let runner = std::mem::replace(&mut self.runner, Box::new(run_once));
(runner)(self);
}
Expand Down
186 changes: 131 additions & 55 deletions crates/bevy_app/src/app_builder.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use std::any::Any;

use crate::{
app::{App, AppExit},
event::Events,
plugin::Plugin,
stage, startup_stage, PluginGroup, PluginGroupBuilder,
};
use bevy_ecs::{FromResources, IntoSystem, Resources, System, World};
use bevy_ecs::{
clear_trackers_system, FromResources, IntoStage, IntoSystem, Resource, Resources, RunOnce,
Schedule, Stage, State, StateStage, System, SystemStage, World,
};
use bevy_utils::tracing::debug;

/// Configure [App]s using the builder pattern
Expand All @@ -18,8 +23,10 @@ impl Default for AppBuilder {
app: App::default(),
};

app_builder.add_default_stages();
app_builder.add_event::<AppExit>();
app_builder
.add_default_stages()
.add_event::<AppExit>()
.add_system_to_stage(stage::LAST, clear_trackers_system);
app_builder
}
}
Expand Down Expand Up @@ -49,55 +56,88 @@ impl AppBuilder {
self
}

pub fn add_stage(&mut self, stage_name: &'static str) -> &mut Self {
self.app.schedule.add_stage(stage_name);
pub fn add_stage<Params, S: IntoStage<Params>>(
&mut self,
name: &'static str,
stage: S,
) -> &mut Self {
self.app.schedule.add_stage(name, stage);
self
}

pub fn add_stage_after(&mut self, target: &'static str, stage_name: &'static str) -> &mut Self {
self.app.schedule.add_stage_after(target, stage_name);
pub fn add_stage_after<Params, S: IntoStage<Params>>(
&mut self,
target: &'static str,
name: &'static str,
stage: S,
) -> &mut Self {
self.app.schedule.add_stage_after(target, name, stage);
self
}

pub fn add_stage_before(
pub fn add_stage_before<Params, S: IntoStage<Params>>(
&mut self,
target: &'static str,
stage_name: &'static str,
name: &'static str,
stage: S,
) -> &mut Self {
self.app.schedule.add_stage_before(target, stage_name);
self.app.schedule.add_stage_before(target, name, stage);
self
}

pub fn add_startup_stage(&mut self, stage_name: &'static str) -> &mut Self {
self.app.startup_schedule.add_stage(stage_name);
pub fn add_startup_stage<Params, S: IntoStage<Params>>(
&mut self,
name: &'static str,
stage: S,
) -> &mut Self {
self.app
.schedule
.stage(stage::STARTUP, |schedule: &mut Schedule| {
schedule.add_stage(name, stage)
});
self
}

pub fn add_startup_stage_after(
pub fn add_startup_stage_after<Params, S: IntoStage<Params>>(
&mut self,
target: &'static str,
stage_name: &'static str,
name: &'static str,
stage: S,
) -> &mut Self {
self.app
.startup_schedule
.add_stage_after(target, stage_name);
.schedule
.stage(stage::STARTUP, |schedule: &mut Schedule| {
schedule.add_stage_after(target, name, stage)
});
self
}

pub fn add_startup_stage_before(
pub fn add_startup_stage_before<Params, S: IntoStage<Params>>(
&mut self,
target: &'static str,
stage_name: &'static str,
name: &'static str,
stage: S,
) -> &mut Self {
self.app
.startup_schedule
.add_stage_before(target, stage_name);
.schedule
.stage(stage::STARTUP, |schedule: &mut Schedule| {
schedule.add_stage_before(target, name, stage)
});
self
}

pub fn stage<T: Stage, F: FnOnce(&mut T) -> &mut T>(
&mut self,
name: &str,
func: F,
) -> &mut Self {
self.app.schedule.stage(name, func);
self
}

pub fn add_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
where
S: System<Input = (), Output = ()>,
S: System<In = (), Out = ()>,
IntoS: IntoSystem<Params, S>,
{
self.add_system_to_stage(stage::UPDATE, system)
Expand All @@ -109,37 +149,41 @@ impl AppBuilder {
system: IntoS,
) -> &mut Self
where
S: System<Input = (), Output = ()>,
S: System<In = (), Out = ()>,
IntoS: IntoSystem<Params, S>,
{
self.app
.startup_schedule
.add_system_to_stage(stage_name, system);
.schedule
.stage(stage::STARTUP, |schedule: &mut Schedule| {
schedule.add_system_to_stage(stage_name, system)
});
self
}

pub fn add_startup_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
where
S: System<Input = (), Output = ()>,
S: System<In = (), Out = ()>,
IntoS: IntoSystem<Params, S>,
{
self.app
.startup_schedule
.add_system_to_stage(startup_stage::STARTUP, system);
self
self.add_startup_system_to_stage(startup_stage::STARTUP, system)
}

pub fn add_default_stages(&mut self) -> &mut Self {
self.add_startup_stage(startup_stage::PRE_STARTUP)
.add_startup_stage(startup_stage::STARTUP)
.add_startup_stage(startup_stage::POST_STARTUP)
.add_stage(stage::FIRST)
.add_stage(stage::PRE_EVENT)
.add_stage(stage::EVENT)
.add_stage(stage::PRE_UPDATE)
.add_stage(stage::UPDATE)
.add_stage(stage::POST_UPDATE)
.add_stage(stage::LAST)
self.add_stage(
stage::STARTUP,
Schedule::default()
.with_run_criteria(RunOnce::default())
.with_stage(startup_stage::PRE_STARTUP, SystemStage::parallel())
.with_stage(startup_stage::STARTUP, SystemStage::parallel())
.with_stage(startup_stage::POST_STARTUP, SystemStage::parallel()),
)
.add_stage(stage::FIRST, SystemStage::parallel())
.add_stage(stage::PRE_EVENT, SystemStage::parallel())
.add_stage(stage::EVENT, SystemStage::parallel())
.add_stage(stage::PRE_UPDATE, SystemStage::parallel())
.add_stage(stage::UPDATE, SystemStage::parallel())
.add_stage(stage::POST_UPDATE, SystemStage::parallel())
.add_stage(stage::LAST, SystemStage::parallel())
}

pub fn add_system_to_stage<S, Params, IntoS>(
Expand All @@ -148,28 +192,13 @@ impl AppBuilder {
system: IntoS,
) -> &mut Self
where
S: System<Input = (), Output = ()>,
S: System<In = (), Out = ()>,
IntoS: IntoSystem<Params, S>,
{
self.app.schedule.add_system_to_stage(stage_name, system);
self
}

pub fn add_system_to_stage_front<S, Params, IntoS>(
&mut self,
stage_name: &'static str,
system: IntoS,
) -> &mut Self
where
S: System<Input = (), Output = ()>,
IntoS: IntoSystem<Params, S>,
{
self.app
.schedule
.add_system_to_stage_front(stage_name, system.system());
self
}

pub fn add_event<T>(&mut self) -> &mut Self
where
T: Send + Sync + 'static,
Expand All @@ -178,6 +207,53 @@ impl AppBuilder {
.add_system_to_stage(stage::EVENT, Events::<T>::update_system)
}

pub fn state_stage_name<T: Any>() -> String {
format!("state({})", std::any::type_name::<T>())
}

pub fn add_state<T: Clone + Resource>(&mut self, initial: T) -> &mut Self {
self.add_resource(State::new(initial));
self.app.schedule.add_stage_after(
stage::UPDATE,
&Self::state_stage_name::<T>(),
StateStage::<T>::default(),
);
self
}

pub fn on_state_enter<T: Clone + Resource, Params, S: IntoStage<Params>>(
&mut self,
value: T,
stage: S,
) -> &mut Self {
self.stage(
&Self::state_stage_name::<T>(),
|state_stage: &mut StateStage<T>| state_stage.on_state_enter(value, stage),
)
}

pub fn on_state_update<T: Clone + Resource, Params, S: IntoStage<Params>>(
&mut self,
value: T,
stage: S,
) -> &mut Self {
self.stage(
&Self::state_stage_name::<T>(),
|state_stage: &mut StateStage<T>| state_stage.on_state_update(value, stage),
)
}

pub fn on_state_exit<T: Clone + Resource, Params, S: IntoStage<Params>>(
&mut self,
value: T,
stage: S,
) -> &mut Self {
self.stage(
&Self::state_stage_name::<T>(),
|state_stage: &mut StateStage<T>| state_stage.on_state_exit(value, stage),
)
}

/// Adds a resource to the current [App] and overwrites any resource previously added of the same type.
pub fn add_resource<T>(&mut self, resource: T) -> &mut Self
where
Expand Down
2 changes: 0 additions & 2 deletions crates/bevy_app/src/schedule_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ impl Plugin for ScheduleRunnerPlugin {
.get_or_insert_with(ScheduleRunnerSettings::default)
.to_owned();
app.set_runner(move |mut app: App| {
app.initialize();

let mut app_exit_event_reader = EventReader::<AppExit>::default();
match settings.run_mode {
RunMode::Once => {
Expand Down
7 changes: 5 additions & 2 deletions crates/bevy_app/src/stage.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
/// Name of the app stage that runs once at the beginning of the app
pub const STARTUP: &str = "startup";

/// Name of app stage that runs before all other app stages
pub const FIRST: &str = "first";

/// Name of app stage that runs before EVENT
pub const PRE_EVENT: &str = "pre_events";
pub const PRE_EVENT: &str = "pre_event";

/// Name of app stage that updates events. Runs before UPDATE
pub const EVENT: &str = "events";
pub const EVENT: &str = "event";

/// Name of app stage responsible for performing setup before an update. Runs before UPDATE.
pub const PRE_UPDATE: &str = "pre_update";
Expand Down
Loading

0 comments on commit aecc0bb

Please sign in to comment.