From 5ae83dcdd2003377498613812a2c8c31a7d5f4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Mockers?= Date: Mon, 24 May 2021 20:43:59 +0200 Subject: [PATCH] add all `CoreStage`s to startup stages, and use `StartupStage` as an alias to matching `CoreStage` --- crates/bevy_app/src/app_builder.rs | 66 +++++++++++++++++++++++------ crates/bevy_app/src/lib.rs | 45 +++++++++++++++++++- crates/bevy_ecs/src/schedule/mod.rs | 29 ++++++++++++- 3 files changed, 123 insertions(+), 17 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 58a2dbdd87c22..c9c737578a3cd 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -84,7 +84,9 @@ impl AppBuilder { } pub fn add_stage(&mut self, label: impl StageLabel, stage: S) -> &mut Self { + let cloned_label = label.dyn_clone(); self.app.schedule.add_stage(label, stage); + self.add_startup_stage_boxed(cloned_label, SystemStage::parallel()); self } @@ -94,6 +96,7 @@ impl AppBuilder { label: impl StageLabel, stage: S, ) -> &mut Self { + self.add_startup_stage_after_boxed(&target, label.dyn_clone(), SystemStage::parallel()); self.app.schedule.add_stage_after(target, label, stage); self } @@ -104,10 +107,51 @@ impl AppBuilder { label: impl StageLabel, stage: S, ) -> &mut Self { + self.add_startup_stage_before_boxed(&target, label.dyn_clone(), SystemStage::parallel()); self.app.schedule.add_stage_before(target, label, stage); self } + pub(crate) fn add_startup_stage_boxed( + &mut self, + label: Box, + stage: S, + ) -> &mut Self { + self.app + .schedule + .stage(CoreStage::Startup, |schedule: &mut Schedule| { + schedule.add_stage_boxed(label, stage) + }); + self + } + + pub(crate) fn add_startup_stage_after_boxed( + &mut self, + target: &dyn StageLabel, + label: Box, + stage: S, + ) -> &mut Self { + self.app + .schedule + .stage(CoreStage::Startup, |schedule: &mut Schedule| { + schedule.add_stage_after_boxed(target, label, stage) + }); + self + } + + pub(crate) fn add_startup_stage_before_boxed( + &mut self, + target: &dyn StageLabel, + label: Box, + stage: S, + ) -> &mut Self { + self.app + .schedule + .stage(CoreStage::Startup, |schedule: &mut Schedule| { + schedule.add_stage_before_boxed(target, label, stage) + }); + self + } pub fn add_startup_stage(&mut self, label: impl StageLabel, stage: S) -> &mut Self { self.app .schedule @@ -271,19 +315,15 @@ impl AppBuilder { } pub fn add_default_stages(&mut self) -> &mut Self { - self.add_stage(CoreStage::First, SystemStage::parallel()) - .add_stage( - CoreStage::Startup, - Schedule::default() - .with_run_criteria(RunOnce::default()) - .with_stage(StartupStage::PreStartup, SystemStage::parallel()) - .with_stage(StartupStage::Startup, SystemStage::parallel()) - .with_stage(StartupStage::PostStartup, SystemStage::parallel()), - ) - .add_stage(CoreStage::PreUpdate, SystemStage::parallel()) - .add_stage(CoreStage::Update, SystemStage::parallel()) - .add_stage(CoreStage::PostUpdate, SystemStage::parallel()) - .add_stage(CoreStage::Last, SystemStage::parallel()) + self.add_stage( + CoreStage::Startup, + Schedule::default().with_run_criteria(RunOnce::default()), + ) + .add_stage(CoreStage::First, SystemStage::parallel()) + .add_stage(CoreStage::PreUpdate, SystemStage::parallel()) + .add_stage(CoreStage::Update, SystemStage::parallel()) + .add_stage(CoreStage::PostUpdate, SystemStage::parallel()) + .add_stage(CoreStage::Last, SystemStage::parallel()) } /// Setup the application to manage events of type `T`. diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index e5cd52fd6e7cf..4acf927922522 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -7,6 +7,8 @@ mod schedule_runner; #[cfg(feature = "bevy_ci_testing")] mod ci_testing; +use std::{any::Any, hash::Hash}; + pub use app::*; pub use app_builder::*; pub use bevy_derive::DynamicPlugin; @@ -23,7 +25,7 @@ pub mod prelude { }; } -use bevy_ecs::schedule::StageLabel; +use bevy_ecs::schedule::{DynEq, DynHash, StageLabel}; /// The names of the default App stages #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] @@ -42,8 +44,9 @@ pub enum CoreStage { /// Name of app stage that runs after all other app stages Last, } + /// The names of the default App startup stages -#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] +#[derive(Debug, PartialEq, Clone)] pub enum StartupStage { /// Name of app stage that runs once before the startup stage PreStartup, @@ -52,3 +55,41 @@ pub enum StartupStage { /// Name of app stage that runs once after the startup stage PostStartup, } + +impl StageLabel for StartupStage { + fn dyn_clone(&self) -> Box { + Box::new(Clone::clone(self)) + } +} + +impl DynEq for StartupStage { + fn as_any(&self) -> &dyn Any { + self + } + + fn dyn_eq(&self, other: &dyn DynEq) -> bool { + match self { + StartupStage::PreStartup => CoreStage::PreUpdate.dyn_eq(other), + StartupStage::Startup => CoreStage::Update.dyn_eq(other), + StartupStage::PostStartup => CoreStage::PostUpdate.dyn_eq(other), + } + } +} +impl DynHash for StartupStage { + fn as_dyn_eq(&self) -> &dyn bevy_ecs::schedule::DynEq { + match self { + StartupStage::PreStartup => &CoreStage::PreUpdate, + StartupStage::Startup => &CoreStage::Update, + StartupStage::PostStartup => &CoreStage::PostUpdate, + } + } + + fn dyn_hash(&self, mut state: &mut dyn std::hash::Hasher) { + match self { + StartupStage::PreStartup => CoreStage::PreUpdate.hash(&mut state), + StartupStage::Startup => CoreStage::Update.hash(&mut state), + StartupStage::PostStartup => CoreStage::PostUpdate.hash(&mut state), + } + CoreStage::Update.type_id().hash(&mut state); + } +} diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 75480468b0bfa..8e6c0fe086e3a 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -85,6 +85,11 @@ impl Schedule { pub fn add_stage(&mut self, label: impl StageLabel, stage: S) -> &mut Self { let label: Box = Box::new(label); + self.add_stage_boxed(label, stage) + } + + #[doc(hidden)] + pub fn add_stage_boxed(&mut self, label: Box, stage: S) -> &mut Self { self.stage_order.push(label.clone()); let prev = self.stages.insert(label.clone(), Box::new(stage)); if prev.is_some() { @@ -101,11 +106,21 @@ impl Schedule { ) -> &mut Self { let label: Box = Box::new(label); let target = &target as &dyn StageLabel; + self.add_stage_after_boxed(target, label, stage) + } + + #[doc(hidden)] + pub fn add_stage_after_boxed( + &mut self, + target: &dyn StageLabel, + label: Box, + stage: S, + ) -> &mut Self { let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_label)| &***stage_label == target) + .find(|(_i, stage_label)| target == &***stage_label) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); @@ -125,11 +140,21 @@ impl Schedule { ) -> &mut Self { let label: Box = Box::new(label); let target = &target as &dyn StageLabel; + self.add_stage_before_boxed(target, label, stage) + } + + #[doc(hidden)] + pub fn add_stage_before_boxed( + &mut self, + target: &dyn StageLabel, + label: Box, + stage: S, + ) -> &mut Self { let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_label)| &***stage_label == target) + .find(|(_i, stage_label)| target == &***stage_label) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target));