From 2bd15faa7001a93c39688ffa4b3df31b3dff2228 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 9 Feb 2021 23:35:06 +0300 Subject: [PATCH 01/24] Add Label type --- crates/bevy_app/src/app_builder.rs | 85 ++-- crates/bevy_app/src/lib.rs | 36 +- crates/bevy_app/src/stage.rs | 23 - crates/bevy_app/src/startup_stage.rs | 8 - crates/bevy_asset/src/assets.rs | 4 +- crates/bevy_asset/src/lib.rs | 25 +- crates/bevy_audio/src/lib.rs | 2 +- crates/bevy_core/src/label.rs | 10 +- crates/bevy_core/src/lib.rs | 8 +- .../src/log_diagnostics_plugin.rs | 4 +- crates/bevy_ecs/macros/src/lib.rs | 55 +++ crates/bevy_ecs/src/lib.rs | 5 +- crates/bevy_ecs/src/schedule/label.rs | 81 ++++ crates/bevy_ecs/src/schedule/mod.rs | 105 +++-- crates/bevy_ecs/src/schedule/stage.rs | 421 +++++++++++------- .../bevy_ecs/src/schedule/system_container.rs | 39 +- .../src/schedule/system_descriptor.rs | 61 +-- crates/bevy_ecs/src/system/into_system.rs | 22 +- crates/bevy_gilrs/src/lib.rs | 9 +- crates/bevy_input/src/lib.rs | 16 +- crates/bevy_pbr/src/lib.rs | 2 +- crates/bevy_render/src/lib.rs | 64 +-- crates/bevy_render/src/render_graph/graph.rs | 12 +- crates/bevy_scene/src/lib.rs | 15 +- crates/bevy_sprite/src/lib.rs | 4 +- crates/bevy_text/src/lib.rs | 4 +- .../hierarchy/hierarchy_maintenance_system.rs | 10 +- crates/bevy_transform/src/lib.rs | 10 +- .../src/transform_propagate_system.rs | 10 +- crates/bevy_ui/src/lib.rs | 43 +- crates/bevy_ui/src/update.rs | 9 +- crates/bevy_wgpu/src/lib.rs | 13 +- examples/2d/texture_atlas.rs | 12 +- examples/ecs/ecs_guide.rs | 35 +- examples/ecs/fixed_timestep.rs | 8 +- examples/ecs/removal_detection.rs | 4 +- examples/ecs/state.rs | 18 +- examples/game/alien_cake_addict.rs | 55 ++- examples/input/gamepad_input.rs | 2 +- examples/shader/shader_defs.rs | 2 +- examples/window/multiple_windows.rs | 14 +- 41 files changed, 895 insertions(+), 470 deletions(-) delete mode 100644 crates/bevy_app/src/stage.rs delete mode 100644 crates/bevy_app/src/startup_stage.rs create mode 100644 crates/bevy_ecs/src/schedule/label.rs diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 1d019696b673e..3f72833bfd00d 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -2,11 +2,12 @@ use crate::{ app::{App, AppExit}, event::Events, plugin::Plugin, - stage, startup_stage, PluginGroup, PluginGroupBuilder, + CoreStage, PluginGroup, PluginGroupBuilder, StartupStage, }; use bevy_ecs::{ - clear_trackers_system, FromResources, IntoExclusiveSystem, IntoSystem, Resource, Resources, - RunOnce, Schedule, Stage, StateStage, SystemDescriptor, SystemStage, World, + clear_trackers_system, FromResources, FullIntoLabel, IntoExclusiveSystem, IntoSystem, Resource, + Resources, RunOnce, Schedule, Stage, StageLabel, StateStage, SystemDescriptor, SystemStage, + World, }; use bevy_utils::tracing::debug; @@ -24,7 +25,7 @@ impl Default for AppBuilder { app_builder .add_default_stages() .add_event::() - .add_system_to_stage(stage::LAST, clear_trackers_system.exclusive_system()); + .add_system_to_stage(CoreStage::LAST, clear_trackers_system.exclusive_system()); app_builder } } @@ -54,15 +55,19 @@ impl AppBuilder { self } - pub fn add_stage(&mut self, name: &'static str, stage: S) -> &mut Self { + pub fn add_stage( + &mut self, + name: impl FullIntoLabel, + stage: S, + ) -> &mut Self { self.app.schedule.add_stage(name, stage); self } pub fn add_stage_after( &mut self, - target: &'static str, - name: &'static str, + target: impl FullIntoLabel, + name: impl FullIntoLabel, stage: S, ) -> &mut Self { self.app.schedule.add_stage_after(target, name, stage); @@ -71,18 +76,22 @@ impl AppBuilder { pub fn add_stage_before( &mut self, - target: &'static str, - name: &'static str, + target: impl FullIntoLabel, + name: impl FullIntoLabel, stage: S, ) -> &mut Self { self.app.schedule.add_stage_before(target, name, stage); self } - pub fn add_startup_stage(&mut self, name: &'static str, stage: S) -> &mut Self { + pub fn add_startup_stage( + &mut self, + name: impl FullIntoLabel, + stage: S, + ) -> &mut Self { self.app .schedule - .stage(stage::STARTUP, |schedule: &mut Schedule| { + .stage(CoreStage::Startup, |schedule: &mut Schedule| { schedule.add_stage(name, stage) }); self @@ -90,13 +99,13 @@ impl AppBuilder { pub fn add_startup_stage_after( &mut self, - target: &'static str, - name: &'static str, + target: impl FullIntoLabel, + name: impl FullIntoLabel, stage: S, ) -> &mut Self { self.app .schedule - .stage(stage::STARTUP, |schedule: &mut Schedule| { + .stage(CoreStage::Startup, |schedule: &mut Schedule| { schedule.add_stage_after(target, name, stage) }); self @@ -104,13 +113,13 @@ impl AppBuilder { pub fn add_startup_stage_before( &mut self, - target: &'static str, - name: &'static str, + target: impl FullIntoLabel, + name: impl FullIntoLabel, stage: S, ) -> &mut Self { self.app .schedule - .stage(stage::STARTUP, |schedule: &mut Schedule| { + .stage(CoreStage::Startup, |schedule: &mut Schedule| { schedule.add_stage_before(target, name, stage) }); self @@ -118,7 +127,7 @@ impl AppBuilder { pub fn stage &mut T>( &mut self, - name: &str, + name: impl FullIntoLabel, func: F, ) -> &mut Self { self.app.schedule.stage(name, func); @@ -126,12 +135,12 @@ impl AppBuilder { } pub fn add_system(&mut self, system: impl Into) -> &mut Self { - self.add_system_to_stage(stage::UPDATE, system) + self.add_system_to_stage(CoreStage::Update, system) } pub fn add_system_to_stage( &mut self, - stage_name: &'static str, + stage_name: impl FullIntoLabel, system: impl Into, ) -> &mut Self { self.app.schedule.add_system_to_stage(stage_name, system); @@ -139,17 +148,17 @@ impl AppBuilder { } pub fn add_startup_system(&mut self, system: impl Into) -> &mut Self { - self.add_startup_system_to_stage(startup_stage::STARTUP, system) + self.add_startup_system_to_stage(StartupStage::Startup, system) } pub fn add_startup_system_to_stage( &mut self, - stage_name: &'static str, + stage_name: impl FullIntoLabel, system: impl Into, ) -> &mut Self { self.app .schedule - .stage(stage::STARTUP, |schedule: &mut Schedule| { + .stage(CoreStage::Startup, |schedule: &mut Schedule| { schedule.add_system_to_stage(stage_name, system) }); self @@ -157,7 +166,7 @@ impl AppBuilder { pub fn on_state_enter( &mut self, - stage: &str, + stage: impl FullIntoLabel, state: T, system: impl Into, ) -> &mut Self { @@ -168,7 +177,7 @@ impl AppBuilder { pub fn on_state_update( &mut self, - stage: &str, + stage: impl FullIntoLabel, state: T, system: impl Into, ) -> &mut Self { @@ -179,7 +188,7 @@ impl AppBuilder { pub fn on_state_exit( &mut self, - stage: &str, + stage: impl FullIntoLabel, state: T, system: impl Into, ) -> &mut Self { @@ -190,20 +199,20 @@ impl AppBuilder { pub fn add_default_stages(&mut self) -> &mut Self { self.add_stage( - stage::STARTUP, + CoreStage::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()), + .with_stage(StartupStage::PreStartup, SystemStage::parallel()) + .with_stage(StartupStage::Startup, SystemStage::parallel()) + .with_stage(StartupStage::PostStartup, 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()) + .add_stage(CoreStage::First, SystemStage::parallel()) + .add_stage(CoreStage::PreEvent, SystemStage::parallel()) + .add_stage(CoreStage::Event, 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()) } pub fn add_event(&mut self) -> &mut Self @@ -211,7 +220,7 @@ impl AppBuilder { T: Send + Sync + 'static, { self.insert_resource(Events::::default()) - .add_system_to_stage(stage::EVENT, Events::::update_system.system()) + .add_system_to_stage(CoreStage::Event, Events::::update_system.system()) } /// Inserts a resource to the current [App] and overwrites any resource previously added of the same type. diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 3d82bab5b09ba..113480da6f5a7 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -1,7 +1,37 @@ +use bevy_ecs::{IntoLabel, StageLabel}; + /// The names of the default App stages -pub mod stage; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +pub enum CoreStage { + /// Name of the app stage that runs once at the beginning of the app + Startup, + /// Name of app stage that runs before all other app stages + First, + /// Name of app stage that runs before EVENT + PreEvent, + /// Name of app stage that updates events. Runs before UPDATE + Event, + /// Name of app stage responsible for performing setup before an update. Runs before UPDATE. + PreUpdate, + /// Name of app stage responsible for doing most app logic. Systems should be registered here by default. + Update, + /// Name of app stage responsible for processing the results of UPDATE. Runs after UPDATE. + PostUpdate, + /// Name of app stage that runs after all other app stages + LAST, +} /// The names of the default App startup stages -pub mod startup_stage; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +pub enum StartupStage { + /// Name of app stage that runs once before the startup stage + PreStartup, + /// Name of app stage that runs once when an app starts up + Startup, + /// Name of app stage that runs once after the startup stage + PostStartup, +} mod app; mod app_builder; @@ -23,6 +53,6 @@ pub mod prelude { app::App, app_builder::AppBuilder, event::{EventReader, Events}, - stage, DynamicPlugin, Plugin, PluginGroup, + CoreStage, DynamicPlugin, Plugin, PluginGroup, }; } diff --git a/crates/bevy_app/src/stage.rs b/crates/bevy_app/src/stage.rs deleted file mode 100644 index fb8eb416307ee..0000000000000 --- a/crates/bevy_app/src/stage.rs +++ /dev/null @@ -1,23 +0,0 @@ -/// 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_event"; - -/// Name of app stage that updates events. Runs before UPDATE -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"; - -/// Name of app stage responsible for doing most app logic. Systems should be registered here by default. -pub const UPDATE: &str = "update"; - -/// Name of app stage responsible for processing the results of UPDATE. Runs after UPDATE. -pub const POST_UPDATE: &str = "post_update"; - -/// Name of app stage that runs after all other app stages -pub const LAST: &str = "last"; diff --git a/crates/bevy_app/src/startup_stage.rs b/crates/bevy_app/src/startup_stage.rs deleted file mode 100644 index 54804904bdbf9..0000000000000 --- a/crates/bevy_app/src/startup_stage.rs +++ /dev/null @@ -1,8 +0,0 @@ -/// Name of app stage that runs once before the startup stage -pub const PRE_STARTUP: &str = "pre_startup"; - -/// Name of app stage that runs once when an app starts up -pub const STARTUP: &str = "startup"; - -/// Name of app stage that runs once after the startup stage -pub const POST_STARTUP: &str = "post_startup"; diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index a9a41117acec2..cdd3d93f5fc00 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -219,11 +219,11 @@ impl AddAsset for AppBuilder { self.insert_resource(assets) .add_system_to_stage( - super::stage::ASSET_EVENTS, + super::AssetStage::AssetEvents, Assets::::asset_event_system.system(), ) .add_system_to_stage( - crate::stage::LOAD_ASSETS, + crate::AssetStage::LoadAssets, update_asset_storage_system::.system(), ) .register_type::>() diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index b8f4adbc371ef..5a4b771fc550f 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -24,11 +24,13 @@ pub use loader::*; pub use path::*; /// The names of asset stages in an App Schedule -pub mod stage { - pub const LOAD_ASSETS: &str = "load_assets"; - pub const ASSET_EVENTS: &str = "asset_events"; +use bevy_ecs::{IntoLabel, StageLabel}; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +pub enum AssetStage { + LoadAssets, + AssetEvents, } - pub mod prelude { pub use crate::{AddAsset, AssetEvent, AssetServer, Assets, Handle, HandleUntyped}; } @@ -89,18 +91,18 @@ impl Plugin for AssetPlugin { } app.add_stage_before( - bevy_app::stage::PRE_UPDATE, - stage::LOAD_ASSETS, + bevy_app::CoreStage::PreUpdate, + AssetStage::LoadAssets, SystemStage::parallel(), ) .add_stage_after( - bevy_app::stage::POST_UPDATE, - stage::ASSET_EVENTS, + bevy_app::CoreStage::PostUpdate, + AssetStage::AssetEvents, SystemStage::parallel(), ) .register_type::() .add_system_to_stage( - bevy_app::stage::PRE_UPDATE, + bevy_app::CoreStage::PreUpdate, asset_server::free_unused_assets_system.system(), ); @@ -108,6 +110,9 @@ impl Plugin for AssetPlugin { feature = "filesystem_watcher", all(not(target_arch = "wasm32"), not(target_os = "android")) ))] - app.add_system_to_stage(stage::LOAD_ASSETS, io::filesystem_watcher_system.system()); + app.add_system_to_stage( + AssetStage::LoadAssets, + io::filesystem_watcher_system.system(), + ); } } diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index 594c2c78b65ab..951a40afa5b00 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -25,7 +25,7 @@ impl Plugin for AudioPlugin { .init_asset_loader::() .init_resource::>() .add_system_to_stage( - stage::POST_UPDATE, + CoreStage::PostUpdate, play_queued_audio_system::.exclusive_system(), ); } diff --git a/crates/bevy_core/src/label.rs b/crates/bevy_core/src/label.rs index 1a70d3220bd3d..8129aea527faf 100644 --- a/crates/bevy_core/src/label.rs +++ b/crates/bevy_core/src/label.rs @@ -115,15 +115,19 @@ pub(crate) fn entity_labels_system( #[cfg(test)] mod tests { use super::*; - use bevy_ecs::Stage; + use bevy_ecs::{IntoLabel, Stage, StageLabel}; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] + #[label_type(StageLabel)] + struct Test; fn setup() -> (World, Resources, bevy_ecs::Schedule) { let world = World::new(); let mut resources = Resources::default(); resources.insert(EntityLabels::default()); let mut schedule = bevy_ecs::Schedule::default(); - schedule.add_stage("test", SystemStage::single_threaded()); - schedule.add_system_to_stage("test", entity_labels_system.system()); + schedule.add_stage(Test, SystemStage::single_threaded()); + schedule.add_system_to_stage(Test, entity_labels_system.system()); (world, resources, schedule) } diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 368889cb6c3b4..e03b5720f9906 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -20,7 +20,7 @@ pub mod prelude { pub use crate::{DefaultTaskPoolOptions, EntityLabels, Labels, Name, Time, Timer}; } -use bevy_app::{prelude::*, startup_stage}; +use bevy_app::{prelude::*, StartupStage}; /// Adds core functionality to Apps. #[derive(Default)] @@ -42,8 +42,8 @@ impl Plugin for CorePlugin { .register_type::() .register_type::>() .register_type::() - .add_system_to_stage(stage::FIRST, time_system.system()) - .add_startup_system_to_stage(startup_stage::POST_STARTUP, entity_labels_system.system()) - .add_system_to_stage(stage::POST_UPDATE, entity_labels_system.system()); + .add_system_to_stage(CoreStage::First, time_system.system()) + .add_startup_system_to_stage(StartupStage::PostStartup, entity_labels_system.system()) + .add_system_to_stage(CoreStage::PostUpdate, entity_labels_system.system()); } } diff --git a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs index aa09229d03d1b..7b3b3b91757f1 100644 --- a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs @@ -37,11 +37,11 @@ impl Plugin for LogDiagnosticsPlugin { if self.debug { app.add_system_to_stage( - stage::POST_UPDATE, + CoreStage::PostUpdate, Self::log_diagnostics_debug_system.system(), ); } else { - app.add_system_to_stage(stage::POST_UPDATE, Self::log_diagnostics_system.system()); + app.add_system_to_stage(CoreStage::PostUpdate, Self::log_diagnostics_system.system()); } } } diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index b6984d2a101ba..82f34fe1ecc2a 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -466,3 +466,58 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { } }) } + +#[proc_macro_derive(IntoLabel, attributes(label_type))] +pub fn derive_into_label(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + derive_into_label_(input).into() +} + +fn derive_into_label_(input: DeriveInput) -> TokenStream2 { + let ident = input.ident; + + let manifest = Manifest::new().unwrap(); + let path_str = if let Some(package) = manifest.find(|name| name == "bevy") { + format!("{}::ecs", package.name) + } else if let Some(package) = manifest.find(|name| name == "bevy_internal") { + format!("{}::ecs", package.name) + } else if let Some(package) = manifest.find(|name| name == "bevy_ecs") { + package.name + } else if manifest.crate_package().unwrap().name == "bevy_ecs" { + "crate".to_string() + } else { + "bevy_ecs".to_string() + }; + let crate_path: Path = syn::parse(path_str.parse::().unwrap()).unwrap(); + + let name = ident.to_string(); + let name = syn::LitStr::new(&name, Span::call_site()); + + let path = input + .attrs + .iter() + .find(|a| *a.path.get_ident().as_ref().unwrap() == "label_type") + .and_then(|a| a.parse_args::().ok()) + .unwrap_or_else(|| panic!("You must specify label kind")); + + quote! { + impl #crate_path::IntoLabel<#path> for #ident { + fn name(&self) -> std::borrow::Cow<'static, str> { + std::borrow::Cow::Borrowed(#name) + } + + fn downcast_eq(&self, other: &dyn IntoLabel<#path>) -> bool { + self.assert_receiver_is_total_eq(); + match other.downcast_ref::() { + Some(val) => val == self, + None => false, + } + } + + fn dyn_hash(&self, mut hasher: &mut dyn ::std::hash::Hasher) { + use ::std::hash::Hash; + self.hash(&mut hasher) + } + } + } +} diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index a2aa0aa2d278d..699431e6342c8 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -20,7 +20,8 @@ pub mod prelude { SystemSet, SystemStage, }, system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Mut, Mutated, Or, - QuerySet, Ref, RefMut, ShouldRun, With, Without, World, + Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, IntoLabel, Mut, + Mutated, Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, + World, }; } diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs new file mode 100644 index 0000000000000..85e3384ef0ee8 --- /dev/null +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -0,0 +1,81 @@ +use downcast_rs::Downcast; +use std::{ + borrow::Cow, + fmt::{Debug, Display}, + hash::{Hash, Hasher}, + marker::PhantomData, + sync::Arc, +}; + +use crate::{StageLabel, SystemLabel}; + +pub struct Label(Arc>, PhantomData); + +impl Clone for Label { + fn clone(&self) -> Self { + Label(self.0.clone(), Default::default()) + } +} + +impl Hash for Label { + fn hash(&self, state: &mut H) { + self.0.dyn_hash(state); + } +} + +impl PartialEq for Label { + fn eq(&self, other: &Self) -> bool { + // Consider using pointer comparison like https://github.com/rust-lang/rust/issues/46139#issuecomment-416101127 + self.0.downcast_eq(&*other.0.as_ref()) + } +} + +impl Eq for Label {} + +impl Display for Label { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.to_str()) + } +} + +impl Debug for Label { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.to_str()) + } +} + +impl Label { + pub fn name(&self) -> Cow<'static, str> { + self.0.name() + } +} + +pub trait IntoLabel: Downcast + Send + Sync + 'static { + fn name(&self) -> Cow<'static, str>; + fn downcast_eq(&self, other: &dyn IntoLabel) -> bool; + fn dyn_hash(&self, hasher: &mut dyn Hasher); +} + +impl + Eq + Hash + Clone> From for Label { + fn from(t: T) -> Self { + Label(Arc::new(t), Default::default()) + } +} + +impl + Eq + Hash + Clone> From for Label { + fn from(t: T) -> Self { + Label(Arc::new(t), Default::default()) + } +} + +pub trait FullIntoLabel: IntoLabel + Eq + Hash + Clone {} + +impl + Eq + Hash + Clone> FullIntoLabel for T {} + +downcast_rs::impl_downcast!(IntoLabel); + +impl Label { + pub fn to_str(&self) -> Cow<'static, str> { + self.0.name() + } +} diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 5532c0f4d5c14..88b15cd187cc3 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -1,5 +1,6 @@ mod executor; mod executor_parallel; +mod label; mod stage; mod state; mod system_container; @@ -8,6 +9,7 @@ mod system_set; pub use executor::*; pub use executor_parallel::*; +pub use label::*; pub use stage::*; pub use state::*; pub use system_container::*; @@ -22,23 +24,35 @@ use std::{any::TypeId, borrow::Cow}; #[derive(Default)] pub struct Schedule { - stages: HashMap>, - stage_order: Vec, + stages: HashMap, Box>, + stage_order: Vec>, run_criteria: RunCriteria, } +pub struct StageLabel; + impl Schedule { - pub fn with_stage(mut self, name: &str, stage: S) -> Self { + pub fn with_stage(mut self, name: impl FullIntoLabel, stage: S) -> Self { self.add_stage(name, stage); self } - pub fn with_stage_after(mut self, target: &str, name: &str, stage: S) -> Self { + pub fn with_stage_after( + mut self, + target: impl FullIntoLabel, + name: impl FullIntoLabel, + stage: S, + ) -> Self { self.add_stage_after(target, name, stage); self } - pub fn with_stage_before(mut self, target: &str, name: &str, stage: S) -> Self { + pub fn with_stage_before( + mut self, + target: impl FullIntoLabel, + name: impl FullIntoLabel, + stage: S, + ) -> Self { self.add_stage_before(target, name, stage); self } @@ -50,7 +64,7 @@ impl Schedule { pub fn with_system_in_stage( mut self, - stage_name: &'static str, + stage_name: impl FullIntoLabel, system: impl Into, ) -> Self { self.add_system_to_stage(stage_name, system); @@ -65,94 +79,109 @@ impl Schedule { self } - pub fn add_stage(&mut self, name: &str, stage: S) -> &mut Self { - self.stage_order.push(name.to_string()); - let prev = self.stages.insert(name.to_string(), Box::new(stage)); + pub fn add_stage( + &mut self, + name: impl FullIntoLabel, + stage: S, + ) -> &mut Self { + self.stage_order.push(name.clone().into()); + let prev = self.stages.insert(name.clone().into(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {}.", name); + panic!("Stage already exists: {}.", name.name()); } self } - pub fn add_stage_after(&mut self, target: &str, name: &str, stage: S) -> &mut Self { + pub fn add_stage_after( + &mut self, + target: impl FullIntoLabel, + name: impl FullIntoLabel, + stage: S, + ) -> &mut Self { let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_name)| *stage_name == target) + .find(|(_i, stage_name)| **stage_name == target.clone().into()) .map(|(i, _)| i) - .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target)); + .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); - self.stage_order.insert(target_index + 1, name.to_string()); - let prev = self.stages.insert(name.to_string(), Box::new(stage)); + self.stage_order + .insert(target_index + 1, name.clone().into()); + let prev = self.stages.insert(name.clone().into(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {}.", name); + panic!("Stage already exists: {}.", name.name()); } self } - pub fn add_stage_before(&mut self, target: &str, name: &str, stage: S) -> &mut Self { + pub fn add_stage_before( + &mut self, + target: impl FullIntoLabel, + name: impl FullIntoLabel, + stage: S, + ) -> &mut Self { let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_name)| *stage_name == target) + .find(|(_i, stage_name)| **stage_name == target.clone().into()) .map(|(i, _)| i) - .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target)); + .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); - self.stage_order.insert(target_index, name.to_string()); - let prev = self.stages.insert(name.to_string(), Box::new(stage)); + self.stage_order.insert(target_index, name.clone().into()); + let prev = self.stages.insert(name.clone().into(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {}.", name); + panic!("Stage already exists: {}.", name.name()); } self } pub fn add_system_to_stage( &mut self, - stage_name: &'static str, + stage_name: impl FullIntoLabel, system: impl Into, ) -> &mut Self { + let name = stage_name.name().to_owned(); let stage = self - .get_stage_mut::(stage_name) - .unwrap_or_else(|| { - panic!( - "Stage '{}' does not exist or is not a SystemStage", - stage_name - ) - }); + .get_stage_mut::(stage_name) + .unwrap_or_else(|| panic!("Stage '{}' does not exist or is not a SystemStage", name)); stage.add_system(system); self } pub fn stage &mut T>( &mut self, - name: &str, + name: impl FullIntoLabel, func: F, ) -> &mut Self { + let str_name = name.name().to_owned(); let stage = self - .get_stage_mut::(name) - .unwrap_or_else(|| panic!("stage '{}' does not exist or is the wrong type", name)); + .get_stage_mut::(name) + .unwrap_or_else(|| panic!("stage '{}' does not exist or is the wrong type", str_name)); func(stage); self } - pub fn get_stage(&self, name: &str) -> Option<&T> { + pub fn get_stage(&self, name: impl FullIntoLabel) -> Option<&T> { self.stages - .get(name) + .get(&name.into()) .and_then(|stage| stage.downcast_ref::()) } - pub fn get_stage_mut(&mut self, name: &str) -> Option<&mut T> { + pub fn get_stage_mut>( + &mut self, + name: L, + ) -> Option<&mut T> { self.stages - .get_mut(name) + .get_mut(&name.into()) .and_then(|stage| stage.downcast_mut::()) } pub fn run_once(&mut self, world: &mut World, resources: &mut Resources) { for name in self.stage_order.iter() { #[cfg(feature = "trace")] - let stage_span = bevy_utils::tracing::info_span!("stage", name = name.as_str()); + let stage_span = bevy_utils::tracing::info_span!("stage", name = &*name.to_str()); #[cfg(feature = "trace")] let _stage_guard = stage_span.enter(); let stage = self.stages.get_mut(name).unwrap(); diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 1bcee3a201b75..18ef9bd9ebd6e 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -8,9 +8,9 @@ use super::{ SingleThreadedExecutor, SystemContainer, }; use crate::{ - InsertionPoint, Resources, RunCriteria, + InsertionPoint, Label, Resources, RunCriteria, ShouldRun::{self, *}, - System, SystemDescriptor, SystemSet, World, + System, SystemDescriptor, SystemLabel, SystemSet, World, }; pub trait Stage: Downcast + Send + Sync { @@ -350,8 +350,8 @@ impl SystemStage { } enum DependencyGraphError { - LabelNotFound(Cow<'static, str>), - DuplicateLabel(Cow<'static, str>), + LabelNotFound(Label), + DuplicateLabel(Label), GraphCycles(Vec>), } @@ -381,7 +381,7 @@ fn sort_systems(systems: &mut Vec) -> Result<(), Dependenc fn build_dependency_graph( systems: &[impl SystemContainer], ) -> Result>, DependencyGraphError> { - let mut labels = HashMap::, usize>::default(); + let mut labels = HashMap::, usize>::default(); for (label, index) in systems.iter().enumerate().filter_map(|(index, container)| { container .label() @@ -503,17 +503,17 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> { .collect::>(); let mut ambiguities = Vec::new(); let full_bitset: FixedBitSet = (0..systems.len()).collect(); - let mut processed = FixedBitSet::with_capacity(systems.len()); for (index_a, relations) in all_relations.drain(..).enumerate() { // TODO: prove that `.take(index_a)` would be correct here, and uncomment it if so. for index_b in full_bitset.difference(&relations) /*.take(index_a)*/ { - if !processed.contains(index_b) && !systems[index_a].is_compatible(&systems[index_b]) { + if !systems[index_a].is_compatible(&systems[index_b]) + && !ambiguities.contains(&(index_b, index_a)) + { ambiguities.push((index_a, index_b)); } } - processed.insert(index_a); } ambiguities } @@ -610,7 +610,7 @@ impl Stage for SystemStage { #[cfg(test)] mod tests { - use crate::{prelude::*, SingleThreadedExecutor}; + use crate::{prelude::*, SingleThreadedExecutor, SystemLabel}; fn make_exclusive(tag: usize) -> impl FnMut(&mut Resources) { move |resources| resources.get_mut::>().unwrap().push(tag) @@ -626,6 +626,11 @@ mod tests { }}; } + // string based label for tests + #[derive(IntoLabel, PartialEq, Eq, Hash, Clone)] + #[label_type(SystemLabel)] + struct L(&'static str); + fn empty() {} fn resettable_run_once(mut has_ran: ResMut) -> ShouldRun { @@ -694,8 +699,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().at_end().label("empty")) - .with_system(empty.exclusive_system().after("empty")); + .with_system(empty.exclusive_system().at_end().label(L("empty"))) + .with_system(empty.exclusive_system().after(L("empty"))); stage.run(&mut world, &mut resources); } @@ -708,12 +713,12 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().at_end().label("empty")) - .with_system(empty.exclusive_system().before_commands().label("empty")); + .with_system(empty.exclusive_system().at_end().label(L("empty"))) + .with_system(empty.exclusive_system().before_commands().label(L("empty"))); stage.run(&mut world, &mut resources); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().label("empty")) - .with_system(empty.exclusive_system().label("empty")); + .with_system(empty.exclusive_system().label(L("empty"))) + .with_system(empty.exclusive_system().label(L("empty"))); stage.run(&mut world, &mut resources); } @@ -723,9 +728,14 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(1).exclusive_system().label("1").after("0")) - .with_system(make_exclusive(2).exclusive_system().after("1")) - .with_system(make_exclusive(0).exclusive_system().label("0")); + .with_system( + make_exclusive(1) + .exclusive_system() + .label(L("1")) + .after(L("0")), + ) + .with_system(make_exclusive(2).exclusive_system().after(L("1"))) + .with_system(make_exclusive(0).exclusive_system().label(L("0"))); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -741,9 +751,14 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(1).exclusive_system().label("1").before("2")) - .with_system(make_exclusive(2).exclusive_system().label("2")) - .with_system(make_exclusive(0).exclusive_system().before("1")); + .with_system( + make_exclusive(1) + .exclusive_system() + .label(L("1")) + .before(L("2")), + ) + .with_system(make_exclusive(2).exclusive_system().label(L("2"))) + .with_system(make_exclusive(0).exclusive_system().before(L("1"))); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -759,11 +774,21 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().label("2")) - .with_system(make_exclusive(1).exclusive_system().after("0").before("2")) - .with_system(make_exclusive(0).exclusive_system().label("0")) - .with_system(make_exclusive(4).exclusive_system().label("4")) - .with_system(make_exclusive(3).exclusive_system().after("2").before("4")); + .with_system(make_exclusive(2).exclusive_system().label(L("2"))) + .with_system( + make_exclusive(1) + .exclusive_system() + .after(L("0")) + .before(L("2")), + ) + .with_system(make_exclusive(0).exclusive_system().label(L("0"))) + .with_system(make_exclusive(4).exclusive_system().label(L("4"))) + .with_system( + make_exclusive(3) + .exclusive_system() + .after(L("2")) + .before(L("4")), + ); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -782,27 +807,37 @@ mod tests { .with_system( make_exclusive(2) .exclusive_system() - .label("2") - .after("1") - .before("3") - .before("3"), + .label(L("2")) + .after(L("1")) + .before(L("3")) + .before(L("3")), ) .with_system( make_exclusive(1) .exclusive_system() - .label("1") - .after("0") - .after("0") - .before("2"), + .label(L("1")) + .after(L("0")) + .after(L("0")) + .before(L("2")), + ) + .with_system( + make_exclusive(0) + .exclusive_system() + .label(L("0")) + .before(L("1")), + ) + .with_system( + make_exclusive(4) + .exclusive_system() + .label(L("4")) + .after(L("3")), ) - .with_system(make_exclusive(0).exclusive_system().label("0").before("1")) - .with_system(make_exclusive(4).exclusive_system().label("4").after("3")) .with_system( make_exclusive(3) .exclusive_system() - .label("3") - .after("2") - .before("4"), + .label(L("3")) + .after(L("2")) + .before(L("4")), ); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); @@ -819,14 +854,24 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().label("2")) + .with_system(make_exclusive(2).exclusive_system().label(L("2"))) .with_system_set( SystemSet::new() - .with_system(make_exclusive(0).exclusive_system().label("0")) - .with_system(make_exclusive(4).exclusive_system().label("4")) - .with_system(make_exclusive(3).exclusive_system().after("2").before("4")), + .with_system(make_exclusive(0).exclusive_system().label(L("0"))) + .with_system(make_exclusive(4).exclusive_system().label(L("4"))) + .with_system( + make_exclusive(3) + .exclusive_system() + .after(L("2")) + .before(L("4")), + ), ) - .with_system(make_exclusive(1).exclusive_system().after("0").before("2")); + .with_system( + make_exclusive(1) + .exclusive_system() + .after(L("0")) + .before(L("2")), + ); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -843,13 +888,13 @@ mod tests { resources.insert(Vec::::new()); resources.insert(false); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().before("1")) + .with_system(make_exclusive(0).exclusive_system().before(L("1"))) .with_system_set( SystemSet::new() .with_run_criteria(resettable_run_once.system()) - .with_system(make_exclusive(1).exclusive_system().label("1")), + .with_system(make_exclusive(1).exclusive_system().label(L("1"))), ) - .with_system(make_exclusive(2).exclusive_system().after("1")); + .with_system(make_exclusive(2).exclusive_system().after(L("1"))); stage.run(&mut world, &mut resources); stage.run(&mut world, &mut resources); *resources.get_mut::().unwrap() = false; @@ -868,8 +913,12 @@ mod tests { let mut world = World::new(); let mut resources = Resources::default(); resources.insert(Vec::::new()); - let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().label("0").after("0")); + let mut stage = SystemStage::parallel().with_system( + make_exclusive(0) + .exclusive_system() + .label(L("0")) + .after(L("0")), + ); stage.run(&mut world, &mut resources); } @@ -880,8 +929,18 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().label("0").after("1")) - .with_system(make_exclusive(1).exclusive_system().label("1").after("0")); + .with_system( + make_exclusive(0) + .exclusive_system() + .label(L("0")) + .after(L("1")), + ) + .with_system( + make_exclusive(1) + .exclusive_system() + .label(L("1")) + .after(L("0")), + ); stage.run(&mut world, &mut resources); } @@ -892,9 +951,19 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().label("0")) - .with_system(make_exclusive(1).exclusive_system().after("0").before("2")) - .with_system(make_exclusive(2).exclusive_system().label("2").before("0")); + .with_system(make_exclusive(0).exclusive_system().label(L("0"))) + .with_system( + make_exclusive(1) + .exclusive_system() + .after(L("0")) + .before(L("2")), + ) + .with_system( + make_exclusive(2) + .exclusive_system() + .label(L("2")) + .before(L("0")), + ); stage.run(&mut world, &mut resources); } @@ -906,7 +975,7 @@ mod tests { resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() .with_system(empty.system()) - .with_system(empty.system().after("empty")); + .with_system(empty.system().after(L("empty"))); stage.run(&mut world, &mut resources); } @@ -917,8 +986,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(empty.system().label("empty")) - .with_system(empty.system().label("empty")); + .with_system(empty.system().label(L("empty"))) + .with_system(empty.system().label(L("empty"))); stage.run(&mut world, &mut resources); } @@ -928,9 +997,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(1).system().after("0").label("1")) - .with_system(make_parallel!(2).system().after("1")) - .with_system(make_parallel!(0).system().label("0")); + .with_system(make_parallel!(1).system().after(L("0")).label(L("1"))) + .with_system(make_parallel!(2).system().after(L("1"))) + .with_system(make_parallel!(0).system().label(L("0"))); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -946,9 +1015,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(1).system().label("1").before("2")) - .with_system(make_parallel!(2).system().label("2")) - .with_system(make_parallel!(0).system().before("1")); + .with_system(make_parallel!(1).system().label(L("1")).before(L("2"))) + .with_system(make_parallel!(2).system().label(L("2"))) + .with_system(make_parallel!(0).system().before(L("1"))); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -964,11 +1033,11 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(2).system().label("2")) - .with_system(make_parallel!(1).system().after("0").before("2")) - .with_system(make_parallel!(0).system().label("0")) - .with_system(make_parallel!(4).system().label("4")) - .with_system(make_parallel!(3).system().after("2").before("4")); + .with_system(make_parallel!(2).system().label(L("2"))) + .with_system(make_parallel!(1).system().after(L("0")).before(L("2"))) + .with_system(make_parallel!(0).system().label(L("0"))) + .with_system(make_parallel!(4).system().label(L("4"))) + .with_system(make_parallel!(3).system().after(L("2")).before(L("4"))); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -987,22 +1056,28 @@ mod tests { .with_system( make_parallel!(2) .system() - .label("2") - .after("1") - .before("3") - .before("3"), + .label(L("2")) + .after(L("1")) + .before(L("3")) + .before(L("3")), ) .with_system( make_parallel!(1) .system() - .label("1") - .after("0") - .after("0") - .before("2"), + .label(L("1")) + .after(L("0")) + .after(L("0")) + .before(L("2")), ) - .with_system(make_parallel!(0).system().label("0").before("1")) - .with_system(make_parallel!(4).system().label("4").after("3")) - .with_system(make_parallel!(3).system().label("3").after("2").before("4")); + .with_system(make_parallel!(0).system().label(L("0")).before(L("1"))) + .with_system(make_parallel!(4).system().label(L("4")).after(L("3"))) + .with_system( + make_parallel!(3) + .system() + .label(L("3")) + .after(L("2")) + .before(L("4")), + ); stage.run(&mut world, &mut resources); for container in stage.parallel.iter() { assert!(container.dependencies().len() <= 1); @@ -1021,14 +1096,14 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(2).system().label("2")) + .with_system(make_parallel!(2).system().label(L("2"))) .with_system_set( SystemSet::new() - .with_system(make_parallel!(0).system().label("0")) - .with_system(make_parallel!(4).system().label("4")) - .with_system(make_parallel!(3).system().after("2").before("4")), + .with_system(make_parallel!(0).system().label(L("0"))) + .with_system(make_parallel!(4).system().label(L("4"))) + .with_system(make_parallel!(3).system().after(L("2")).before(L("4"))), ) - .with_system(make_parallel!(1).system().after("0").before("2")); + .with_system(make_parallel!(1).system().after(L("0")).before(L("2"))); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -1045,13 +1120,13 @@ mod tests { resources.insert(Vec::::new()); resources.insert(false); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().before("1")) + .with_system(make_parallel!(0).system().before(L("1"))) .with_system_set( SystemSet::new() .with_run_criteria(resettable_run_once.system()) - .with_system(make_parallel!(1).system().label("1")), + .with_system(make_parallel!(1).system().label(L("1"))), ) - .with_system(make_parallel!(2).system().after("1")); + .with_system(make_parallel!(2).system().after(L("1"))); stage.run(&mut world, &mut resources); stage.run(&mut world, &mut resources); *resources.get_mut::().unwrap() = false; @@ -1070,8 +1145,8 @@ mod tests { let mut world = World::new(); let mut resources = Resources::default(); resources.insert(Vec::::new()); - let mut stage = - SystemStage::parallel().with_system(make_parallel!(0).system().label("0").after("0")); + let mut stage = SystemStage::parallel() + .with_system(make_parallel!(0).system().label(L("0")).after(L("0"))); stage.run(&mut world, &mut resources); } @@ -1082,8 +1157,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().label("0").after("1")) - .with_system(make_parallel!(1).system().label("1").after("0")); + .with_system(make_parallel!(0).system().label(L("0")).after(L("1"))) + .with_system(make_parallel!(1).system().label(L("1")).after(L("0"))); stage.run(&mut world, &mut resources); } @@ -1094,9 +1169,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().label("0")) - .with_system(make_parallel!(1).system().after("0").before("2")) - .with_system(make_parallel!(2).system().label("2").before("0")); + .with_system(make_parallel!(0).system().label(L("0"))) + .with_system(make_parallel!(1).system().after(L("0")).before(L("2"))) + .with_system(make_parallel!(2).system().label(L("2")).before(L("0"))); stage.run(&mut world, &mut resources); } @@ -1127,21 +1202,21 @@ mod tests { let mut resources = Resources::default(); let mut stage = SystemStage::parallel() - .with_system(empty.system().label("0")) - .with_system(empty.system().label("1").after("0")) - .with_system(empty.system().label("2")) - .with_system(empty.system().label("3").after("2").before("4")) - .with_system(empty.system().label("4")); + .with_system(empty.system().label(L("0"))) + .with_system(empty.system().label(L("1")).after(L("0"))) + .with_system(empty.system().label(L("2"))) + .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) + .with_system(empty.system().label(L("4"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); assert_eq!(find_ambiguities(&stage.parallel).len(), 0); let mut stage = SystemStage::parallel() - .with_system(empty.system().label("0")) - .with_system(component.system().label("1").after("0")) - .with_system(empty.system().label("2")) - .with_system(empty.system().label("3").after("2").before("4")) - .with_system(component.system().label("4")); + .with_system(empty.system().label(L("0"))) + .with_system(component.system().label(L("1")).after(L("0"))) + .with_system(empty.system().label(L("2"))) + .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) + .with_system(component.system().label(L("4"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1152,11 +1227,11 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(empty.system().label("0")) - .with_system(resource.system().label("1").after("0")) - .with_system(empty.system().label("2")) - .with_system(empty.system().label("3").after("2").before("4")) - .with_system(resource.system().label("4")); + .with_system(empty.system().label(L("0"))) + .with_system(resource.system().label(L("1")).after(L("0"))) + .with_system(empty.system().label(L("2"))) + .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) + .with_system(resource.system().label(L("4"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1167,21 +1242,27 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(empty.system().label("0")) - .with_system(resource.system().label("1").after("0")) - .with_system(empty.system().label("2")) - .with_system(empty.system().label("3").after("2").before("4")) - .with_system(component.system().label("4")); + .with_system(empty.system().label(L("0"))) + .with_system(resource.system().label(L("1")).after(L("0"))) + .with_system(empty.system().label(L("2"))) + .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) + .with_system(component.system().label(L("4"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); assert_eq!(find_ambiguities(&stage.parallel).len(), 0); let mut stage = SystemStage::parallel() - .with_system(component.system().label("0")) - .with_system(resource.system().label("1").after("0")) - .with_system(empty.system().label("2")) - .with_system(component.system().label("3").after("2").before("4")) - .with_system(resource.system().label("4")); + .with_system(component.system().label(L("0"))) + .with_system(resource.system().label(L("1")).after(L("0"))) + .with_system(empty.system().label(L("2"))) + .with_system( + component + .system() + .label(L("3")) + .after(L("2")) + .before(L("4")), + ) + .with_system(resource.system().label(L("4"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1196,9 +1277,9 @@ mod tests { assert_eq!(ambiguities.len(), 2); let mut stage = SystemStage::parallel() - .with_system(component.system().label("0").before("2")) - .with_system(component.system().label("1").before("2")) - .with_system(component.system().label("2")); + .with_system(component.system().label(L("0")).before(L("2"))) + .with_system(component.system().label(L("1")).before(L("2"))) + .with_system(component.system().label(L("2"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1209,9 +1290,9 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(component.system().label("0")) - .with_system(component.system().label("1").after("0")) - .with_system(component.system().label("2").after("0")); + .with_system(component.system().label(L("0"))) + .with_system(component.system().label(L("1")).after(L("0"))) + .with_system(component.system().label(L("2")).after(L("0"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1222,10 +1303,16 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(component.system().label("0").before("1").before("2")) - .with_system(component.system().label("1")) - .with_system(component.system().label("2")) - .with_system(component.system().label("3").after("1").after("2")); + .with_system( + component + .system() + .label(L("0")) + .before(L("1")) + .before(L("2")), + ) + .with_system(component.system().label(L("1"))) + .with_system(component.system().label(L("2"))) + .with_system(component.system().label(L("3")).after(L("1")).after(L("2"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1239,24 +1326,24 @@ mod tests { .with_system( component .system() - .label("0") - .before("1") - .before("2") - .before("3") - .before("4"), + .label(L("0")) + .before(L("1")) + .before(L("2")) + .before(L("3")) + .before(L("4")), ) - .with_system(component.system().label("1")) - .with_system(component.system().label("2")) - .with_system(component.system().label("3")) - .with_system(component.system().label("4")) + .with_system(component.system().label(L("1"))) + .with_system(component.system().label(L("2"))) + .with_system(component.system().label(L("3"))) + .with_system(component.system().label(L("4"))) .with_system( component .system() - .label("5") - .after("1") - .after("2") - .after("3") - .after("4"), + .label(L("5")) + .after(L("1")) + .after(L("2")) + .after(L("3")) + .after(L("4")), ); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); @@ -1288,26 +1375,44 @@ mod tests { assert_eq!(ambiguities.len(), 6); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().label("0")) - .with_system(empty.exclusive_system().label("1").after("0")) - .with_system(empty.exclusive_system().label("2").after("1")) - .with_system(empty.exclusive_system().label("3").after("2")) - .with_system(empty.exclusive_system().label("4").after("3")) - .with_system(empty.exclusive_system().label("5").after("4")) - .with_system(empty.exclusive_system().label("6").after("5")) - .with_system(empty.exclusive_system().label("7").after("6")); + .with_system(empty.exclusive_system().label(L("0"))) + .with_system(empty.exclusive_system().label(L("1")).after(L("0"))) + .with_system(empty.exclusive_system().label(L("2")).after(L("1"))) + .with_system(empty.exclusive_system().label(L("3")).after(L("2"))) + .with_system(empty.exclusive_system().label(L("4")).after(L("3"))) + .with_system(empty.exclusive_system().label(L("5")).after(L("4"))) + .with_system(empty.exclusive_system().label(L("6")).after(L("5"))) + .with_system(empty.exclusive_system().label(L("7")).after(L("6"))); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); assert_eq!(find_ambiguities(&stage.exclusive_at_start).len(), 0); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().label("0").before("1").before("3")) - .with_system(empty.exclusive_system().label("1")) - .with_system(empty.exclusive_system().label("2").after("1")) - .with_system(empty.exclusive_system().label("3")) - .with_system(empty.exclusive_system().label("4").after("3").before("5")) - .with_system(empty.exclusive_system().label("5")) - .with_system(empty.exclusive_system().label("6").after("2").after("5")); + .with_system( + empty + .exclusive_system() + .label(L("0")) + .before(L("1")) + .before(L("3")), + ) + .with_system(empty.exclusive_system().label(L("1"))) + .with_system(empty.exclusive_system().label(L("2")).after(L("1"))) + .with_system(empty.exclusive_system().label(L("3"))) + .with_system( + empty + .exclusive_system() + .label(L("4")) + .after(L("3")) + .before(L("5")), + ) + .with_system(empty.exclusive_system().label(L("5"))) + .with_system( + empty + .exclusive_system() + .label(L("6")) + .after(L("2")) + .after(L("5")), + ); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start); diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index 32618c287f7df..e36e2f822037d 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,15 +1,18 @@ use std::{borrow::Cow, ptr::NonNull}; -use crate::{ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System}; +use crate::{ + ExclusiveSystem, ExclusiveSystemDescriptor, Label, ParallelSystemDescriptor, System, + SystemLabel, +}; pub(super) trait SystemContainer { fn display_name(&self) -> Cow<'static, str>; fn dependencies(&self) -> &[usize]; fn set_dependencies(&mut self, dependencies: impl IntoIterator); fn system_set(&self) -> usize; - fn label(&self) -> &Option>; - fn before(&self) -> &[Cow<'static, str>]; - fn after(&self) -> &[Cow<'static, str>]; + fn label(&self) -> &Option>; + fn before(&self) -> &[Label]; + fn after(&self) -> &[Label]; fn is_compatible(&self, other: &Self) -> bool; } @@ -17,9 +20,9 @@ pub(super) struct ExclusiveSystemContainer { system: Box, dependencies: Vec, set: usize, - label: Option>, - before: Vec>, - after: Vec>, + label: Option>, + before: Vec>, + after: Vec>, } impl ExclusiveSystemContainer { @@ -43,7 +46,7 @@ impl SystemContainer for ExclusiveSystemContainer { fn display_name(&self) -> Cow<'static, str> { self.label .as_ref() - .cloned() + .map(|l| l.name()) .unwrap_or_else(|| self.system.name()) } @@ -60,15 +63,15 @@ impl SystemContainer for ExclusiveSystemContainer { self.set } - fn label(&self) -> &Option> { + fn label(&self) -> &Option> { &self.label } - fn before(&self) -> &[Cow<'static, str>] { + fn before(&self) -> &[Label] { &self.before } - fn after(&self) -> &[Cow<'static, str>] { + fn after(&self) -> &[Label] { &self.after } @@ -82,16 +85,16 @@ pub struct ParallelSystemContainer { pub(crate) should_run: bool, dependencies: Vec, set: usize, - label: Option>, - before: Vec>, - after: Vec>, + label: Option>, + before: Vec>, + after: Vec>, } impl SystemContainer for ParallelSystemContainer { fn display_name(&self) -> Cow<'static, str> { self.label .as_ref() - .cloned() + .map(|l| l.name()) .unwrap_or_else(|| self.system().name()) } @@ -108,15 +111,15 @@ impl SystemContainer for ParallelSystemContainer { self.set } - fn label(&self) -> &Option> { + fn label(&self) -> &Option> { &self.label } - fn before(&self) -> &[Cow<'static, str>] { + fn before(&self) -> &[Label] { &self.before } - fn after(&self) -> &[Cow<'static, str>] { + fn after(&self) -> &[Label] { &self.after } diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index 60d65508e8d78..e68cae5ff7b6a 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -1,5 +1,6 @@ -use crate::{BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, System}; -use std::borrow::Cow; +use crate::{ + BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, Label, System, +}; /// Encapsulates a system and information on when it run in a `SystemStage`. /// @@ -30,6 +31,8 @@ pub enum SystemDescriptor { Exclusive(ExclusiveSystemDescriptor), } +pub struct SystemLabel; + impl From for SystemDescriptor { fn from(descriptor: ParallelSystemDescriptor) -> Self { SystemDescriptor::Parallel(descriptor) @@ -72,9 +75,9 @@ impl From for SystemDescriptor { /// Encapsulates a parallel system and information on when it run in a `SystemStage`. pub struct ParallelSystemDescriptor { pub(crate) system: BoxedSystem<(), ()>, - pub(crate) label: Option>, - pub(crate) before: Vec>, - pub(crate) after: Vec>, + pub(crate) label: Option>, + pub(crate) before: Vec>, + pub(crate) after: Vec>, } fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor { @@ -88,27 +91,27 @@ fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescrip pub trait ParallelSystemDescriptorCoercion { /// Assigns a label to the system. - fn label(self, label: impl Into>) -> ParallelSystemDescriptor; + fn label(self, label: impl Into>) -> ParallelSystemDescriptor; /// Specifies that the system should run before the system with given label. - fn before(self, label: impl Into>) -> ParallelSystemDescriptor; + fn before(self, label: impl Into>) -> ParallelSystemDescriptor; /// Specifies that the system should run after the system with given label. - fn after(self, label: impl Into>) -> ParallelSystemDescriptor; + fn after(self, label: impl Into>) -> ParallelSystemDescriptor; } impl ParallelSystemDescriptorCoercion for ParallelSystemDescriptor { - fn label(mut self, label: impl Into>) -> ParallelSystemDescriptor { + fn label(mut self, label: impl Into>) -> ParallelSystemDescriptor { self.label = Some(label.into()); self } - fn before(mut self, label: impl Into>) -> ParallelSystemDescriptor { + fn before(mut self, label: impl Into>) -> ParallelSystemDescriptor { self.before.push(label.into()); self } - fn after(mut self, label: impl Into>) -> ParallelSystemDescriptor { + fn after(mut self, label: impl Into>) -> ParallelSystemDescriptor { self.after.push(label.into()); self } @@ -118,29 +121,29 @@ impl ParallelSystemDescriptorCoercion for S where S: System, { - fn label(self, label: impl Into>) -> ParallelSystemDescriptor { + fn label(self, label: impl Into>) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).label(label) } - fn before(self, label: impl Into>) -> ParallelSystemDescriptor { + fn before(self, label: impl Into>) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).before(label) } - fn after(self, label: impl Into>) -> ParallelSystemDescriptor { + fn after(self, label: impl Into>) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).after(label) } } impl ParallelSystemDescriptorCoercion for BoxedSystem<(), ()> { - fn label(self, label: impl Into>) -> ParallelSystemDescriptor { + fn label(self, label: impl Into>) -> ParallelSystemDescriptor { new_parallel_descriptor(self).label(label) } - fn before(self, label: impl Into>) -> ParallelSystemDescriptor { + fn before(self, label: impl Into>) -> ParallelSystemDescriptor { new_parallel_descriptor(self).before(label) } - fn after(self, label: impl Into>) -> ParallelSystemDescriptor { + fn after(self, label: impl Into>) -> ParallelSystemDescriptor { new_parallel_descriptor(self).after(label) } } @@ -155,9 +158,9 @@ pub(crate) enum InsertionPoint { /// Encapsulates an exclusive system and information on when it run in a `SystemStage`. pub struct ExclusiveSystemDescriptor { pub(crate) system: Box, - pub(crate) label: Option>, - pub(crate) before: Vec>, - pub(crate) after: Vec>, + pub(crate) label: Option>, + pub(crate) before: Vec>, + pub(crate) after: Vec>, pub(crate) insertion_point: InsertionPoint, } @@ -173,13 +176,13 @@ fn new_exclusive_descriptor(system: Box) -> ExclusiveSystem pub trait ExclusiveSystemDescriptorCoercion { /// Assigns a label to the system. - fn label(self, label: impl Into>) -> ExclusiveSystemDescriptor; + fn label(self, label: impl Into>) -> ExclusiveSystemDescriptor; /// Specifies that the system should run before the system with given label. - fn before(self, label: impl Into>) -> ExclusiveSystemDescriptor; + fn before(self, label: impl Into>) -> ExclusiveSystemDescriptor; /// Specifies that the system should run after the system with given label. - fn after(self, label: impl Into>) -> ExclusiveSystemDescriptor; + fn after(self, label: impl Into>) -> ExclusiveSystemDescriptor; /// Specifies that the system should run with other exclusive systems at the start of stage. fn at_start(self) -> ExclusiveSystemDescriptor; @@ -193,17 +196,17 @@ pub trait ExclusiveSystemDescriptorCoercion { } impl ExclusiveSystemDescriptorCoercion for ExclusiveSystemDescriptor { - fn label(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn label(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { self.label = Some(label.into()); self } - fn before(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn before(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { self.before.push(label.into()); self } - fn after(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn after(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { self.after.push(label.into()); self } @@ -228,15 +231,15 @@ impl ExclusiveSystemDescriptorCoercion for T where T: ExclusiveSystem + 'static, { - fn label(self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn label(self, label: impl Into>) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).label(label) } - fn before(self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn before(self, label: impl Into>) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).before(label) } - fn after(self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn after(self, label: impl Into>) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).after(label) } diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index a97903e8f06ab..0d893ef97dbc8 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -340,8 +340,8 @@ mod tests { clear_trackers_system, resource::{Res, ResMut, Resources}, schedule::Schedule, - ChangedRes, Entity, IntoExclusiveSystem, Local, Or, Query, QuerySet, Stage, System, - SystemStage, With, World, + ChangedRes, Entity, IntoExclusiveSystem, Local, Or, Query, QuerySet, Stage, StageLabel, + System, SystemStage, With, World, }; #[derive(Debug, Eq, PartialEq, Default)] @@ -442,6 +442,14 @@ mod tests { assert!(*resources.get::().unwrap(), "system ran"); } + use crate::IntoLabel; + #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] + #[label_type(StageLabel)] + enum TestLabels { + CleanTrackers, + Update, + } + #[test] fn changed_resource_system() { fn incr_e_on_flip(_run_on_flip: ChangedRes, mut query: Query<&mut i32>) { @@ -458,9 +466,9 @@ mod tests { let mut schedule = Schedule::default(); let mut update = SystemStage::parallel(); update.add_system(incr_e_on_flip.system()); - schedule.add_stage("update", update); + schedule.add_stage(TestLabels::Update, update); schedule.add_stage( - "clear_trackers", + TestLabels::CleanTrackers, SystemStage::single(clear_trackers_system.exclusive_system()), ); @@ -495,9 +503,9 @@ mod tests { let mut schedule = Schedule::default(); let mut update = SystemStage::parallel(); update.add_system(incr_e_on_flip.system()); - schedule.add_stage("update", update); + schedule.add_stage(TestLabels::Update, update); schedule.add_stage( - "clear_trackers", + TestLabels::CleanTrackers, SystemStage::single(clear_trackers_system.exclusive_system()), ); @@ -585,7 +593,7 @@ mod tests { let mut schedule = Schedule::default(); let mut update = SystemStage::parallel(); update.add_system(system); - schedule.add_stage("update", update); + schedule.add_stage(TestLabels::Update, update); schedule.run(world, resources); } diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 6391cfd071f5d..c3a63300e9e4f 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -1,7 +1,7 @@ mod converter; mod gilrs_system; -use bevy_app::{prelude::*, startup_stage::PRE_STARTUP}; +use bevy_app::{prelude::*, StartupStage}; use bevy_ecs::IntoExclusiveSystem; use bevy_utils::tracing::error; use gilrs::GilrsBuilder; @@ -20,10 +20,13 @@ impl Plugin for GilrsPlugin { Ok(gilrs) => { app.insert_non_send_resource(gilrs) .add_startup_system_to_stage( - PRE_STARTUP, + StartupStage::PreStartup, gilrs_event_startup_system.exclusive_system(), ) - .add_system_to_stage(stage::PRE_EVENT, gilrs_event_system.exclusive_system()); + .add_system_to_stage( + CoreStage::PreEvent, + gilrs_event_system.exclusive_system(), + ); } Err(err) => error!("Failed to start Gilrs. {}", err), } diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index 776aff8bd168f..9ed240d8bff22 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -44,23 +44,29 @@ impl Plugin for InputPlugin { .add_event::() .add_event::() .init_resource::>() - .add_system_to_stage(bevy_app::stage::EVENT, keyboard_input_system.system()) + .add_system_to_stage(bevy_app::CoreStage::Event, keyboard_input_system.system()) .init_resource::>() - .add_system_to_stage(bevy_app::stage::EVENT, mouse_button_input_system.system()) + .add_system_to_stage( + bevy_app::CoreStage::Event, + mouse_button_input_system.system(), + ) .add_event::() .add_event::() .init_resource::() .init_resource::>() .init_resource::>() .init_resource::>() - .add_system_to_stage(bevy_app::stage::EVENT, gamepad_event_system.system()) + .add_system_to_stage(bevy_app::CoreStage::Event, gamepad_event_system.system()) .add_startup_system_to_stage( - bevy_app::startup_stage::STARTUP, + bevy_app::StartupStage::Startup, gamepad_event_system.system(), ) .add_event::() .init_resource::() - .add_system_to_stage(bevy_app::stage::EVENT, touch_screen_input_system.system()); + .add_system_to_stage( + bevy_app::CoreStage::Event, + touch_screen_input_system.system(), + ); } } diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 4d217367b7a00..060761b71c102 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -29,7 +29,7 @@ impl Plugin for PbrPlugin { app.add_asset::() .register_type::() .add_system_to_stage( - stage::POST_UPDATE, + CoreStage::PostUpdate, shader::asset_shader_defs_system::.system(), ) .init_resource::(); diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 9248b5358302f..fbc86664ca683 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -52,16 +52,19 @@ use texture::HdrTextureLoader; #[cfg(feature = "png")] use texture::ImageTextureLoader; +use bevy_ecs::{IntoLabel, StageLabel}; /// The names of "render" App stages -pub mod stage { +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +pub enum RenderStage { /// Stage where render resources are set up - pub const RENDER_RESOURCE: &str = "render_resource"; + RenderResource, /// Stage where Render Graph systems are run. In general you shouldn't add systems to this stage manually. - pub const RENDER_GRAPH_SYSTEMS: &str = "render_graph_systems"; + RenderGraphSystems, // Stage where draw systems are executed. This is generally where Draw components are setup - pub const DRAW: &str = "draw"; - pub const RENDER: &str = "render"; - pub const POST_RENDER: &str = "post_render"; + Draw, + Render, + PostRender, } /// Adds core render types and systems to an App @@ -96,22 +99,30 @@ impl Plugin for RenderPlugin { } app.add_stage_after( - bevy_asset::stage::ASSET_EVENTS, - stage::RENDER_RESOURCE, + bevy_asset::AssetStage::AssetEvents, + RenderStage::RenderResource, SystemStage::parallel(), ) .add_stage_after( - stage::RENDER_RESOURCE, - stage::RENDER_GRAPH_SYSTEMS, + RenderStage::RenderResource, + RenderStage::RenderGraphSystems, SystemStage::parallel(), ) .add_stage_after( - stage::RENDER_GRAPH_SYSTEMS, - stage::DRAW, + RenderStage::RenderGraphSystems, + RenderStage::Draw, + SystemStage::parallel(), + ) + .add_stage_after( + RenderStage::Draw, + RenderStage::Render, + SystemStage::parallel(), + ) + .add_stage_after( + RenderStage::Render, + RenderStage::PostRender, SystemStage::parallel(), ) - .add_stage_after(stage::DRAW, stage::RENDER, SystemStage::parallel()) - .add_stage_after(stage::RENDER, stage::POST_RENDER, SystemStage::parallel()) .add_asset::() .add_asset::() .add_asset::() @@ -135,45 +146,48 @@ impl Plugin for RenderPlugin { .init_resource::() .init_resource::() .add_system_to_stage( - bevy_app::stage::PRE_UPDATE, + bevy_app::CoreStage::PreUpdate, draw::clear_draw_system.system(), ) .add_system_to_stage( - bevy_app::stage::POST_UPDATE, + bevy_app::CoreStage::PostUpdate, camera::active_cameras_system.system(), ) .add_system_to_stage( - bevy_app::stage::POST_UPDATE, + bevy_app::CoreStage::PostUpdate, camera::camera_system::.system(), ) .add_system_to_stage( - bevy_app::stage::POST_UPDATE, + bevy_app::CoreStage::PostUpdate, camera::camera_system::.system(), ) // registration order matters here. this must come after all camera_system:: systems .add_system_to_stage( - bevy_app::stage::POST_UPDATE, + bevy_app::CoreStage::PostUpdate, camera::visible_entities_system.system(), ) .add_system_to_stage( - stage::RENDER_RESOURCE, + RenderStage::RenderResource, shader::shader_update_system.system(), ) .add_system_to_stage( - stage::RENDER_RESOURCE, + RenderStage::RenderResource, mesh::mesh_resource_provider_system.system(), ) .add_system_to_stage( - stage::RENDER_RESOURCE, + RenderStage::RenderResource, Texture::texture_resource_system.system(), ) .add_system_to_stage( - stage::RENDER_GRAPH_SYSTEMS, + RenderStage::RenderGraphSystems, render_graph::render_graph_schedule_executor_system.exclusive_system(), ) - .add_system_to_stage(stage::DRAW, pipeline::draw_render_pipelines_system.system()) .add_system_to_stage( - stage::POST_RENDER, + RenderStage::Draw, + pipeline::draw_render_pipelines_system.system(), + ) + .add_system_to_stage( + RenderStage::PostRender, shader::clear_shader_defs_system.system(), ); diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 49317c77df243..6ea03138969e4 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -1,5 +1,5 @@ use super::{Edge, Node, NodeId, NodeLabel, NodeState, RenderGraphError, SlotLabel, SystemNode}; -use bevy_ecs::{Commands, Schedule, SystemStage}; +use bevy_ecs::{Commands, IntoLabel, Schedule, StageLabel, SystemStage}; use bevy_utils::HashMap; use std::{borrow::Cow, fmt::Debug}; pub struct RenderGraph { @@ -9,10 +9,14 @@ pub struct RenderGraph { commands: Commands, } +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +struct RenderGraphUpdate; + impl Default for RenderGraph { fn default() -> Self { let mut schedule = Schedule::default(); - schedule.add_stage("update", SystemStage::parallel()); + schedule.add_stage(RenderGraphUpdate, SystemStage::parallel()); Self { nodes: Default::default(), node_names: Default::default(), @@ -41,7 +45,9 @@ impl RenderGraph { T: SystemNode + 'static, { let schedule = self.system_node_schedule.as_mut().unwrap(); - let stage = schedule.get_stage_mut::("update").unwrap(); + let stage = schedule + .get_stage_mut::(RenderGraphUpdate) + .unwrap(); stage.add_system(node.get_system(&mut self.commands)); self.add_node(name, node) } diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index c80b0e4ddd6d0..393e11307d47e 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -24,7 +24,12 @@ use bevy_asset::AddAsset; #[derive(Default)] pub struct ScenePlugin; -pub const SCENE_STAGE: &str = "scene"; +use bevy_ecs::{IntoLabel, StageLabel}; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +enum Stages { + SceneStage, +} impl Plugin for ScenePlugin { fn build(&self, app: &mut AppBuilder) { @@ -32,7 +37,11 @@ impl Plugin for ScenePlugin { .add_asset::() .init_asset_loader::() .init_resource::() - .add_stage_after(stage::EVENT, SCENE_STAGE, SystemStage::parallel()) - .add_system_to_stage(SCENE_STAGE, scene_spawner_system.exclusive_system()); + .add_stage_after( + bevy_app::CoreStage::Event, + Stages::SceneStage, + SystemStage::parallel(), + ) + .add_system_to_stage(Stages::SceneStage, scene_spawner_system.exclusive_system()); } } diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index bc574243a4bf5..cc1f3819e65aa 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -47,9 +47,9 @@ impl Plugin for SpritePlugin { app.add_asset::() .add_asset::() .register_type::() - .add_system_to_stage(stage::POST_UPDATE, sprite_system.system()) + .add_system_to_stage(CoreStage::PostUpdate, sprite_system.system()) .add_system_to_stage( - stage::POST_UPDATE, + CoreStage::PostUpdate, asset_shader_defs_system::.system(), ); diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index 6a9f2e09a227c..a1d44e6906ae0 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -40,9 +40,9 @@ impl Plugin for TextPlugin { .add_asset::() .init_asset_loader::() .insert_resource(DefaultTextPipeline::default()) - .add_system_to_stage(bevy_app::stage::POST_UPDATE, text2d_system.system()) + .add_system_to_stage(bevy_app::CoreStage::PostUpdate, text2d_system.system()) .add_system_to_stage( - bevy_render::stage::DRAW, + bevy_render::RenderStage::Draw, text2d::draw_text2d_system.system(), ); } diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs index 468e624046bad..6366b639c2ff6 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs @@ -71,7 +71,13 @@ pub fn parent_update_system( mod test { use super::*; use crate::{hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system}; - use bevy_ecs::{IntoSystem, Resources, Schedule, Stage, SystemStage, World}; + use bevy_ecs::{ + IntoLabel, IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World, + }; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] + #[label_type(StageLabel)] + struct Update; #[test] fn correct_children() { @@ -83,7 +89,7 @@ mod test { update_stage.add_system(transform_propagate_system.system()); let mut schedule = Schedule::default(); - schedule.add_stage("update", update_stage); + schedule.add_stage(Update, update_stage); // Add parent entities let mut commands = Commands::default(); diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 97dd09ed24bd2..1022d50be67dc 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -6,7 +6,7 @@ pub mod prelude { pub use crate::{components::*, hierarchy::*, TransformPlugin}; } -use bevy_app::{prelude::*, startup_stage}; +use bevy_app::{prelude::*, StartupStage}; use bevy_ecs::IntoSystem; use bevy_reflect::RegisterTypeBuilder; use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousParent, Transform}; @@ -22,14 +22,14 @@ impl Plugin for TransformPlugin { .register_type::() .register_type::() // add transform systems to startup so the first update is "correct" - .add_startup_system_to_stage(startup_stage::POST_STARTUP, parent_update_system.system()) + .add_startup_system_to_stage(StartupStage::PostStartup, parent_update_system.system()) .add_startup_system_to_stage( - startup_stage::POST_STARTUP, + StartupStage::PostStartup, transform_propagate_system::transform_propagate_system.system(), ) - .add_system_to_stage(stage::POST_UPDATE, parent_update_system.system()) + .add_system_to_stage(CoreStage::PostUpdate, parent_update_system.system()) .add_system_to_stage( - stage::POST_UPDATE, + CoreStage::PostUpdate, transform_propagate_system::transform_propagate_system.system(), ); } diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 219f2e6c59ee9..9edda49109203 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -71,7 +71,11 @@ fn propagate_recursive( mod test { use super::*; use crate::hierarchy::{parent_update_system, BuildChildren, BuildWorldChildren}; - use bevy_ecs::{Resources, Schedule, Stage, SystemStage, World}; + use bevy_ecs::{IntoLabel, Resources, Schedule, Stage, StageLabel, SystemStage, World}; + + #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] + #[label_type(StageLabel)] + struct Update; #[test] fn did_propagate() { @@ -83,7 +87,7 @@ mod test { update_stage.add_system(transform_propagate_system.system()); let mut schedule = Schedule::default(); - schedule.add_stage("update", update_stage); + schedule.add_stage(Update, update_stage); // Root entity world.spawn(( @@ -134,7 +138,7 @@ mod test { update_stage.add_system(transform_propagate_system.system()); let mut schedule = Schedule::default(); - schedule.add_stage("update", update_stage); + schedule.add_stage(Update, update_stage); // Root entity let mut commands = Commands::default(); diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index b066e1d29ea7b..bec3af09c550f 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -20,15 +20,23 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::{IntoSystem, ParallelSystemDescriptorCoercion, SystemStage}; +use bevy_ecs::{ + IntoLabel, IntoSystem, ParallelSystemDescriptorCoercion, StageLabel, SystemLabel, SystemStage, +}; use bevy_render::render_graph::RenderGraph; use update::ui_z_system; #[derive(Default)] pub struct UiPlugin; - -pub mod stage { - pub const UI: &str = "ui"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +pub enum UiStages { + Ui, +} +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(SystemLabel)] +pub enum UiSystems { + Flex, } pub mod system { @@ -39,20 +47,29 @@ impl Plugin for UiPlugin { fn build(&self, app: &mut AppBuilder) { app.init_resource::() .add_stage_before( - bevy_app::stage::POST_UPDATE, - stage::UI, + bevy_app::CoreStage::PostUpdate, + UiStages::Ui, SystemStage::parallel(), ) - .add_system_to_stage(bevy_app::stage::PRE_UPDATE, ui_focus_system.system()) + .add_system_to_stage(bevy_app::CoreStage::PreUpdate, ui_focus_system.system()) // add these stages to front because these must run before transform update systems - .add_system_to_stage(stage::UI, widget::text_system.system().before(system::FLEX)) .add_system_to_stage( - stage::UI, - widget::image_node_system.system().before(system::FLEX), + UiStages::Ui, + widget::text_system.system().before(UiSystems::Flex), + ) + .add_system_to_stage( + UiStages::Ui, + widget::image_node_system.system().before(UiSystems::Flex), ) - .add_system_to_stage(stage::UI, flex_node_system.system().label(system::FLEX)) - .add_system_to_stage(stage::UI, ui_z_system.system()) - .add_system_to_stage(bevy_render::stage::DRAW, widget::draw_text_system.system()); + .add_system_to_stage( + UiStages::Ui, + flex_node_system.system().label(UiSystems::Flex), + ) + .add_system_to_stage(UiStages::Ui, ui_z_system.system()) + .add_system_to_stage( + bevy_render::RenderStage::Draw, + widget::draw_text_system.system(), + ); let resources = app.resources(); let mut render_graph = resources.get_mut::().unwrap(); diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 1d3df0972b743..500c93ad01f4d 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -48,10 +48,15 @@ fn update_hierarchy( } #[cfg(test)] mod tests { - use bevy_ecs::{Commands, IntoSystem, Resources, Schedule, Stage, SystemStage, World}; + use bevy_ecs::{ + Commands, IntoLabel, IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World, + }; use bevy_transform::{components::Transform, hierarchy::BuildChildren}; use crate::Node; + #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] + #[label_type(StageLabel)] + struct Update; use super::{ui_z_system, UI_Z_STEP}; @@ -117,7 +122,7 @@ mod tests { let mut schedule = Schedule::default(); let mut update_stage = SystemStage::parallel(); update_stage.add_system(ui_z_system.system()); - schedule.add_stage("update", update_stage); + schedule.add_stage(Update, update_stage); schedule.run(&mut world, &mut resources); let mut actual_result = world diff --git a/crates/bevy_wgpu/src/lib.rs b/crates/bevy_wgpu/src/lib.rs index 25e6ff7e54133..4b0d15792664d 100644 --- a/crates/bevy_wgpu/src/lib.rs +++ b/crates/bevy_wgpu/src/lib.rs @@ -21,11 +21,14 @@ pub struct WgpuPlugin; impl Plugin for WgpuPlugin { fn build(&self, app: &mut AppBuilder) { let render_system = get_wgpu_render_system(app.resources_mut()); - app.add_system_to_stage(bevy_render::stage::RENDER, render_system.exclusive_system()) - .add_system_to_stage( - bevy_render::stage::POST_RENDER, - shared_buffers_update_system.system(), - ); + app.add_system_to_stage( + bevy_render::RenderStage::Render, + render_system.exclusive_system(), + ) + .add_system_to_stage( + bevy_render::RenderStage::PostRender, + shared_buffers_update_system.system(), + ); } } diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 3a3ef5c3cdf2a..7484892c7abcb 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -6,14 +6,16 @@ fn main() { .init_resource::() .add_plugins(DefaultPlugins) .insert_resource(State::new(AppState::Setup)) - .add_stage_after(stage::UPDATE, STAGE, StateStage::::default()) - .on_state_enter(STAGE, AppState::Setup, load_textures.system()) - .on_state_update(STAGE, AppState::Setup, check_textures.system()) - .on_state_enter(STAGE, AppState::Finished, setup.system()) + .add_stage_after(CoreStage::Update, Stage, StateStage::::default()) + .on_state_enter(Stage, AppState::Setup, load_textures.system()) + .on_state_update(Stage, AppState::Setup, check_textures.system()) + .on_state_enter(Stage, AppState::Finished, setup.system()) .run(); } -const STAGE: &str = "app_state"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +struct Stage; #[derive(Clone)] enum AppState { diff --git a/examples/ecs/ecs_guide.rs b/examples/ecs/ecs_guide.rs index 4697b994d7702..0ab25f2471557 100644 --- a/examples/ecs/ecs_guide.rs +++ b/examples/ecs/ecs_guide.rs @@ -239,6 +239,13 @@ fn local_state_system(mut state: Local, query: Query<(&Player, &Score)>) state.counter += 1; } +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +enum MyStages { + BeforeRound, + AfterRound, +} + // Our Bevy app's entry point fn main() { // Bevy apps are created using the builder pattern. We use the builder to add systems, resources, and plugins to our app @@ -276,17 +283,25 @@ fn main() { // and the next stage won't start until all systems in the current stage have finished. // add_system(system) adds systems to the UPDATE stage by default // However we can manually specify the stage if we want to. The following is equivalent to add_system(score_system) - .add_system_to_stage(stage::UPDATE, score_system.system()) + .add_system_to_stage(CoreStage::Update, score_system.system()) // We can also create new stages. Here is what our games stage order will look like: - // "before_round": new_player_system, new_round_system - // "update": print_message_system, score_system - // "after_round": score_check_system, game_over_system - .add_stage_before(stage::UPDATE, "before_round", SystemStage::parallel()) - .add_stage_after(stage::UPDATE, "after_round", SystemStage::parallel()) - .add_system_to_stage("before_round", new_round_system.system()) - .add_system_to_stage("before_round", new_player_system.system()) - .add_system_to_stage("after_round", score_check_system.system()) - .add_system_to_stage("after_round", game_over_system.system()) + // `BeforeRound`: new_player_system, new_round_system + // `Update`: print_message_system, score_system + // `AfterRound`: score_check_system, game_over_system + .add_stage_before( + CoreStage::Update, + MyStages::BeforeRound, + SystemStage::parallel(), + ) + .add_stage_after( + CoreStage::Update, + MyStages::AfterRound, + SystemStage::parallel(), + ) + .add_system_to_stage(MyStages::BeforeRound, new_round_system.system()) + .add_system_to_stage(MyStages::BeforeRound, new_player_system.system()) + .add_system_to_stage(MyStages::AfterRound, score_check_system.system()) + .add_system_to_stage(MyStages::AfterRound, game_over_system.system()) // score_check_system will run before game_over_system because score_check_system modifies GameState and game_over_system // reads GameState. This works, but it's a bit confusing. In practice, it would be clearer to create a new stage that runs // before "after_round" diff --git a/examples/ecs/fixed_timestep.rs b/examples/ecs/fixed_timestep.rs index cd97079d0d790..5d5c271e08ae8 100644 --- a/examples/ecs/fixed_timestep.rs +++ b/examples/ecs/fixed_timestep.rs @@ -5,6 +5,10 @@ use bevy::{ const LABEL: &str = "my_fixed_timestep"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +struct FixedUpdateStage; + fn main() { App::build() .add_plugins(DefaultPlugins) @@ -12,8 +16,8 @@ fn main() { .add_system(update.system()) // add a new stage that runs every two seconds .add_stage_after( - stage::UPDATE, - "fixed_update", + CoreStage::Update, + FixedUpdateStage, SystemStage::parallel() .with_run_criteria( FixedTimestep::step(2.0) diff --git a/examples/ecs/removal_detection.rs b/examples/ecs/removal_detection.rs index 80c430ff833d4..424fbf3baecb9 100644 --- a/examples/ecs/removal_detection.rs +++ b/examples/ecs/removal_detection.rs @@ -16,8 +16,8 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .add_startup_system(setup.system()) - .add_system_to_stage(stage::UPDATE, remove_component.system()) - .add_system_to_stage(stage::POST_UPDATE, react_on_removal.system()) + .add_system_to_stage(CoreStage::Update, remove_component.system()) + .add_system_to_stage(CoreStage::PostUpdate, react_on_removal.system()) .run(); } diff --git a/examples/ecs/state.rs b/examples/ecs/state.rs index c446a60f37971..96b060b8981e9 100644 --- a/examples/ecs/state.rs +++ b/examples/ecs/state.rs @@ -6,17 +6,19 @@ fn main() { .add_plugins(DefaultPlugins) .init_resource::() .insert_resource(State::new(AppState::Menu)) - .add_stage_after(stage::UPDATE, STAGE, StateStage::::default()) - .on_state_enter(STAGE, AppState::Menu, setup_menu.system()) - .on_state_update(STAGE, AppState::Menu, menu.system()) - .on_state_exit(STAGE, AppState::Menu, cleanup_menu.system()) - .on_state_enter(STAGE, AppState::InGame, setup_game.system()) - .on_state_update(STAGE, AppState::InGame, movement.system()) - .on_state_update(STAGE, AppState::InGame, change_color.system()) + .add_stage_after(CoreStage::Update, Stage, StateStage::::default()) + .on_state_enter(Stage, AppState::Menu, setup_menu.system()) + .on_state_update(Stage, AppState::Menu, menu.system()) + .on_state_exit(Stage, AppState::Menu, cleanup_menu.system()) + .on_state_enter(Stage, AppState::InGame, setup_game.system()) + .on_state_update(Stage, AppState::InGame, movement.system()) + .on_state_update(Stage, AppState::InGame, change_color.system()) .run(); } -const STAGE: &str = "app_state"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +struct Stage; #[derive(Clone)] enum AppState { diff --git a/examples/game/alien_cake_addict.rs b/examples/game/alien_cake_addict.rs index a9077f1b77503..acfeda522a24a 100644 --- a/examples/game/alien_cake_addict.rs +++ b/examples/game/alien_cake_addict.rs @@ -5,7 +5,12 @@ use bevy::{ }; use rand::Rng; -const STAGE: &str = "game"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +enum GameStages { + InGame, + BonusUpdate, +} #[derive(Clone, PartialEq, Debug)] enum GameState { @@ -20,19 +25,43 @@ fn main() { .add_plugins(DefaultPlugins) .insert_resource(State::new(GameState::Playing)) .add_startup_system(setup_cameras.system()) - .add_stage_after(stage::UPDATE, STAGE, StateStage::::default()) - .on_state_enter(STAGE, GameState::Playing, setup.system()) - .on_state_update(STAGE, GameState::Playing, move_player.system()) - .on_state_update(STAGE, GameState::Playing, focus_camera.system()) - .on_state_update(STAGE, GameState::Playing, rotate_bonus.system()) - .on_state_update(STAGE, GameState::Playing, scoreboard_system.system()) - .on_state_exit(STAGE, GameState::Playing, teardown.system()) - .on_state_enter(STAGE, GameState::GameOver, display_score.system()) - .on_state_update(STAGE, GameState::GameOver, gameover_keyboard.system()) - .on_state_exit(STAGE, GameState::GameOver, teardown.system()) .add_stage_after( - stage::UPDATE, - "bonus_update", + CoreStage::Update, + GameStages::InGame, + StateStage::::default(), + ) + .on_state_enter(GameStages::InGame, GameState::Playing, setup.system()) + .on_state_update(GameStages::InGame, GameState::Playing, move_player.system()) + .on_state_update( + GameStages::InGame, + GameState::Playing, + focus_camera.system(), + ) + .on_state_update( + GameStages::InGame, + GameState::Playing, + rotate_bonus.system(), + ) + .on_state_update( + GameStages::InGame, + GameState::Playing, + scoreboard_system.system(), + ) + .on_state_exit(GameStages::InGame, GameState::Playing, teardown.system()) + .on_state_enter( + GameStages::InGame, + GameState::GameOver, + display_score.system(), + ) + .on_state_update( + GameStages::InGame, + GameState::GameOver, + gameover_keyboard.system(), + ) + .on_state_exit(GameStages::InGame, GameState::GameOver, teardown.system()) + .add_stage_after( + CoreStage::Update, + GameStages::BonusUpdate, SystemStage::parallel() .with_run_criteria(FixedTimestep::step(5.0)) .with_system(spawn_bonus.system()), diff --git a/examples/input/gamepad_input.rs b/examples/input/gamepad_input.rs index 7b3c9d4b07e30..b712c82032f77 100644 --- a/examples/input/gamepad_input.rs +++ b/examples/input/gamepad_input.rs @@ -8,7 +8,7 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .init_resource::() - .add_system_to_stage(stage::PRE_UPDATE, connection_system.system()) + .add_system_to_stage(CoreStage::PreUpdate, connection_system.system()) .add_system(gamepad_system.system()) .run(); } diff --git a/examples/shader/shader_defs.rs b/examples/shader/shader_defs.rs index 552db2f9b9c54..383ffd04e2229 100644 --- a/examples/shader/shader_defs.rs +++ b/examples/shader/shader_defs.rs @@ -18,7 +18,7 @@ fn main() { .add_asset::() .add_startup_system(setup.system()) .add_system_to_stage( - stage::POST_UPDATE, + CoreStage::PostUpdate, asset_shader_defs_system::.system(), ) .run(); diff --git a/examples/window/multiple_windows.rs b/examples/window/multiple_windows.rs index 6ea12ceab43a5..4a1dbc5d391c9 100644 --- a/examples/window/multiple_windows.rs +++ b/examples/window/multiple_windows.rs @@ -18,17 +18,15 @@ fn main() { .insert_resource(Msaa { samples: 4 }) .insert_resource(State::new(AppState::CreateWindow)) .add_plugins(DefaultPlugins) - .add_stage_after( - stage::UPDATE, - STATE_STAGE, - StateStage::::default(), - ) - .on_state_update(STATE_STAGE, AppState::CreateWindow, setup_window.system()) - .on_state_enter(STATE_STAGE, AppState::Setup, setup_pipeline.system()) + .add_stage_after(CoreStage::Update, Stage, StateStage::::default()) + .on_state_update(Stage, AppState::CreateWindow, setup_window.system()) + .on_state_enter(Stage, AppState::Setup, setup_pipeline.system()) .run(); } -const STATE_STAGE: &str = "state"; +#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] +#[label_type(StageLabel)] +pub struct Stage; // NOTE: this "state based" approach to multiple windows is a short term workaround. // Future Bevy releases shouldn't require such a strict order of operations. From f41d7ebefb2e51cc1583b1da58a977c799220610 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Wed, 10 Feb 2021 00:36:12 +0300 Subject: [PATCH 02/24] General improvement --- crates/bevy_ecs/macros/src/lib.rs | 21 +++++++++++---- crates/bevy_ecs/src/schedule/label.rs | 37 ++++++++++++++++++++++++++- crates/bevy_ecs/src/schedule/stage.rs | 1 + 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 82f34fe1ecc2a..2fd83c94306bc 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -467,7 +467,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { }) } -#[proc_macro_derive(IntoLabel, attributes(label_type))] +#[proc_macro_derive(IntoLabel, attributes(label_type, name_expr))] pub fn derive_into_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); derive_into_label_(input).into() @@ -490,15 +490,25 @@ fn derive_into_label_(input: DeriveInput) -> TokenStream2 { }; let crate_path: Path = syn::parse(path_str.parse::().unwrap()).unwrap(); - let name = ident.to_string(); - let name = syn::LitStr::new(&name, Span::call_site()); - let path = input .attrs .iter() .find(|a| *a.path.get_ident().as_ref().unwrap() == "label_type") .and_then(|a| a.parse_args::().ok()) - .unwrap_or_else(|| panic!("You must specify label kind")); + .unwrap_or_else(|| panic!("You must specify `label_type`")); + + let name = input + .attrs + .iter() + .find(|a| *a.path.get_ident().as_ref().unwrap() == "name_expr") + .map(|a| a.parse_args::().expect("Expected expression")) + .unwrap_or_else(|| { + let name = ident.to_string(); + syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(syn::LitStr::new(&name, Span::call_site())), + attrs: Default::default(), + }) + }); quote! { impl #crate_path::IntoLabel<#path> for #ident { @@ -516,6 +526,7 @@ fn derive_into_label_(input: DeriveInput) -> TokenStream2 { fn dyn_hash(&self, mut hasher: &mut dyn ::std::hash::Hasher) { use ::std::hash::Hash; + std::any::TypeId::of::().hash(&mut hasher); self.hash(&mut hasher) } } diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 85e3384ef0ee8..345b1b8aa06d8 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -40,7 +40,10 @@ impl Display for Label { impl Debug for Label { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.to_str()) + f.write_str("\"")?; + f.write_str(&self.to_str())?; + f.write_str("\"")?; + Ok(()) } } @@ -79,3 +82,35 @@ impl Label { self.0.name() } } + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn label_eq_test() { + #[derive(PartialEq, Eq, Hash, Debug)] + struct L(&'static str); + + impl IntoLabel<()> for L { + fn name(&self) -> Cow<'static, str> { + Cow::Borrowed(self.0) + } + + fn downcast_eq(&self, other: &dyn IntoLabel<()>) -> bool { + match other.downcast_ref::() { + Some(val) => val == self, + None => false, + } + } + + fn dyn_hash(&self, mut hasher: &mut dyn Hasher) { + std::any::TypeId::of::().hash(&mut hasher); + self.hash(&mut hasher) + } + } + + let label_1 = L("A"); + let label_2 = L("A"); + assert_eq!(label_1, label_2); + } +} diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 18ef9bd9ebd6e..8cc868a287d71 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -629,6 +629,7 @@ mod tests { // string based label for tests #[derive(IntoLabel, PartialEq, Eq, Hash, Clone)] #[label_type(SystemLabel)] + #[name_expr(self.0)] struct L(&'static str); fn empty() {} From 85eebf20e9d44f9b66ef2a2d92f99c1cb479dffb Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Wed, 10 Feb 2021 01:24:13 +0300 Subject: [PATCH 03/24] Fix stuff --- crates/bevy_ecs/src/schedule/label.rs | 26 ++++--------------- .../src/schedule/system_descriptor.rs | 11 +++++--- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 345b1b8aa06d8..659bc6e1cdfaa 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -86,29 +86,13 @@ impl Label { #[cfg(test)] mod test { use super::*; + use crate::IntoLabel; + struct LabelT; + #[derive(IntoLabel, PartialEq, Eq, Hash, Debug)] + #[label_type(LabelT)] + struct L(&'static str); #[test] fn label_eq_test() { - #[derive(PartialEq, Eq, Hash, Debug)] - struct L(&'static str); - - impl IntoLabel<()> for L { - fn name(&self) -> Cow<'static, str> { - Cow::Borrowed(self.0) - } - - fn downcast_eq(&self, other: &dyn IntoLabel<()>) -> bool { - match other.downcast_ref::() { - Some(val) => val == self, - None => false, - } - } - - fn dyn_hash(&self, mut hasher: &mut dyn Hasher) { - std::any::TypeId::of::().hash(&mut hasher); - self.hash(&mut hasher) - } - } - let label_1 = L("A"); let label_2 = L("A"); assert_eq!(label_1, label_2); diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index e68cae5ff7b6a..e9d9b1f45f0f5 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -16,14 +16,19 @@ use crate::{ /// that they have to run before or after the system with that label. /// /// # Example -/// ```rust +/// ```no_run +/// # // This is no_run because the macro doesn't like the doctest environment /// # use bevy_ecs::prelude::*; /// # fn do_something() {} /// # fn do_the_other_thing() {} /// # fn do_something_else() {} +/// #[derive(IntoLabel, PartialEq, Eq, Hash)] +/// #[label_type(SystemLabel)] +/// struct Something; +/// /// SystemStage::parallel() -/// .with_system(do_something.system().label("something")) -/// .with_system(do_the_other_thing.system().after("something")) +/// .with_system(do_something.system().label(Something)) +/// .with_system(do_the_other_thing.system().after(Something)) /// .with_system(do_something_else.exclusive_system().at_end()); /// ``` pub enum SystemDescriptor { From 857fa8387a0d99dcea1433c444a2fa92b47a1cf9 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Wed, 10 Feb 2021 01:24:51 +0300 Subject: [PATCH 04/24] hotfix --- crates/bevy_ecs/src/schedule/system_descriptor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index e9d9b1f45f0f5..7bd7e7853aba3 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -16,7 +16,7 @@ use crate::{ /// that they have to run before or after the system with that label. /// /// # Example -/// ```no_run +/// ```ignore /// # // This is no_run because the macro doesn't like the doctest environment /// # use bevy_ecs::prelude::*; /// # fn do_something() {} From d0cc27022196b9e18ecab7f2fbf719f601f2ae12 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Mon, 15 Feb 2021 23:20:19 +0300 Subject: [PATCH 05/24] rework to implement suggestions --- crates/bevy_app/src/app_builder.rs | 34 +- crates/bevy_app/src/lib.rs | 8 +- crates/bevy_asset/src/lib.rs | 5 +- crates/bevy_core/src/label.rs | 5 +- crates/bevy_ecs/macros/src/lib.rs | 37 +- crates/bevy_ecs/src/lib.rs | 2 +- crates/bevy_ecs/src/schedule/label.rs | 147 ++++--- crates/bevy_ecs/src/schedule/mod.rs | 71 +-- crates/bevy_ecs/src/schedule/stage.rs | 414 +++++++----------- .../bevy_ecs/src/schedule/system_container.rs | 32 +- .../src/schedule/system_descriptor.rs | 62 ++- crates/bevy_ecs/src/system/into_system.rs | 4 +- crates/bevy_render/src/lib.rs | 5 +- crates/bevy_render/src/render_graph/graph.rs | 5 +- crates/bevy_scene/src/lib.rs | 5 +- .../hierarchy/hierarchy_maintenance_system.rs | 7 +- .../src/transform_propagate_system.rs | 5 +- crates/bevy_ui/src/lib.rs | 8 +- crates/bevy_ui/src/update.rs | 5 +- examples/2d/texture_atlas.rs | 3 +- examples/ecs/ecs_guide.rs | 3 +- examples/ecs/fixed_timestep.rs | 3 +- examples/ecs/state.rs | 3 +- examples/game/alien_cake_addict.rs | 3 +- examples/window/multiple_windows.rs | 3 +- 25 files changed, 385 insertions(+), 494 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 3f72833bfd00d..dd94c91a83f4e 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -5,7 +5,7 @@ use crate::{ CoreStage, PluginGroup, PluginGroupBuilder, StartupStage, }; use bevy_ecs::{ - clear_trackers_system, FromResources, FullIntoLabel, IntoExclusiveSystem, IntoSystem, Resource, + clear_trackers_system, FromResources, IntoExclusiveSystem, IntoSystem, Resource, Resources, RunOnce, Schedule, Stage, StageLabel, StateStage, SystemDescriptor, SystemStage, World, }; @@ -57,7 +57,7 @@ impl AppBuilder { pub fn add_stage( &mut self, - name: impl FullIntoLabel, + name: impl Into, stage: S, ) -> &mut Self { self.app.schedule.add_stage(name, stage); @@ -66,8 +66,8 @@ impl AppBuilder { pub fn add_stage_after( &mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> &mut Self { self.app.schedule.add_stage_after(target, name, stage); @@ -76,8 +76,8 @@ impl AppBuilder { pub fn add_stage_before( &mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> &mut Self { self.app.schedule.add_stage_before(target, name, stage); @@ -86,7 +86,7 @@ impl AppBuilder { pub fn add_startup_stage( &mut self, - name: impl FullIntoLabel, + name: impl Into, stage: S, ) -> &mut Self { self.app @@ -99,8 +99,8 @@ impl AppBuilder { pub fn add_startup_stage_after( &mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> &mut Self { self.app @@ -113,8 +113,8 @@ impl AppBuilder { pub fn add_startup_stage_before( &mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> &mut Self { self.app @@ -127,7 +127,7 @@ impl AppBuilder { pub fn stage &mut T>( &mut self, - name: impl FullIntoLabel, + name: impl Into, func: F, ) -> &mut Self { self.app.schedule.stage(name, func); @@ -140,7 +140,7 @@ impl AppBuilder { pub fn add_system_to_stage( &mut self, - stage_name: impl FullIntoLabel, + stage_name: impl Into, system: impl Into, ) -> &mut Self { self.app.schedule.add_system_to_stage(stage_name, system); @@ -153,7 +153,7 @@ impl AppBuilder { pub fn add_startup_system_to_stage( &mut self, - stage_name: impl FullIntoLabel, + stage_name: impl Into, system: impl Into, ) -> &mut Self { self.app @@ -166,7 +166,7 @@ impl AppBuilder { pub fn on_state_enter( &mut self, - stage: impl FullIntoLabel, + stage: impl Into, state: T, system: impl Into, ) -> &mut Self { @@ -177,7 +177,7 @@ impl AppBuilder { pub fn on_state_update( &mut self, - stage: impl FullIntoLabel, + stage: impl Into, state: T, system: impl Into, ) -> &mut Self { @@ -188,7 +188,7 @@ impl AppBuilder { pub fn on_state_exit( &mut self, - stage: impl FullIntoLabel, + stage: impl Into, state: T, system: impl Into, ) -> &mut Self { diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 113480da6f5a7..577e109bdd5a3 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -1,8 +1,7 @@ -use bevy_ecs::{IntoLabel, StageLabel}; +use bevy_ecs::StageLabel; /// The names of the default App stages -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum CoreStage { /// Name of the app stage that runs once at the beginning of the app Startup, @@ -22,8 +21,7 @@ pub enum CoreStage { LAST, } /// The names of the default App startup stages -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum StartupStage { /// Name of app stage that runs once before the startup stage PreStartup, diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 5a4b771fc550f..4786931668208 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -24,9 +24,8 @@ pub use loader::*; pub use path::*; /// The names of asset stages in an App Schedule -use bevy_ecs::{IntoLabel, StageLabel}; -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +use bevy_ecs::StageLabel; +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum AssetStage { LoadAssets, AssetEvents, diff --git a/crates/bevy_core/src/label.rs b/crates/bevy_core/src/label.rs index 8129aea527faf..3ae49ad2f54e3 100644 --- a/crates/bevy_core/src/label.rs +++ b/crates/bevy_core/src/label.rs @@ -115,10 +115,9 @@ pub(crate) fn entity_labels_system( #[cfg(test)] mod tests { use super::*; - use bevy_ecs::{IntoLabel, Stage, StageLabel}; + use bevy_ecs::{Stage, StageLabel}; - #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] - #[label_type(StageLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct Test; fn setup() -> (World, Resources, bevy_ecs::Schedule) { diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 2fd83c94306bc..ff32ed1a85160 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -467,13 +467,19 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { }) } -#[proc_macro_derive(IntoLabel, attributes(label_type, name_expr))] -pub fn derive_into_label(input: TokenStream) -> TokenStream { +#[proc_macro_derive(SystemLabel, attributes(name_expr))] +pub fn derive_system_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - derive_into_label_(input).into() + derive_label(input, Ident::new("SystemLabelMarker", Span::call_site())).into() } -fn derive_into_label_(input: DeriveInput) -> TokenStream2 { +#[proc_macro_derive(StageLabel, attributes(name_expr))] +pub fn derive_stage_label(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + derive_label(input, Ident::new("StageLabelMarker", Span::call_site())).into() +} + +fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { let ident = input.ident; let manifest = Manifest::new().unwrap(); @@ -490,13 +496,6 @@ fn derive_into_label_(input: DeriveInput) -> TokenStream2 { }; let crate_path: Path = syn::parse(path_str.parse::().unwrap()).unwrap(); - let path = input - .attrs - .iter() - .find(|a| *a.path.get_ident().as_ref().unwrap() == "label_type") - .and_then(|a| a.parse_args::().ok()) - .unwrap_or_else(|| panic!("You must specify `label_type`")); - let name = input .attrs .iter() @@ -511,24 +510,10 @@ fn derive_into_label_(input: DeriveInput) -> TokenStream2 { }); quote! { - impl #crate_path::IntoLabel<#path> for #ident { + impl #crate_path::Label<#crate_path::#label_type> for #ident { fn name(&self) -> std::borrow::Cow<'static, str> { std::borrow::Cow::Borrowed(#name) } - - fn downcast_eq(&self, other: &dyn IntoLabel<#path>) -> bool { - self.assert_receiver_is_total_eq(); - match other.downcast_ref::() { - Some(val) => val == self, - None => false, - } - } - - fn dyn_hash(&self, mut hasher: &mut dyn ::std::hash::Hasher) { - use ::std::hash::Hash; - std::any::TypeId::of::().hash(&mut hasher); - self.hash(&mut hasher) - } } } } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 699431e6342c8..1607e4b6ca3c9 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -20,7 +20,7 @@ pub mod prelude { SystemSet, SystemStage, }, system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, IntoLabel, Mut, + Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Label, Mut, Mutated, Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World, }; diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 659bc6e1cdfaa..479ac3dc74d09 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -1,100 +1,131 @@ -use downcast_rs::Downcast; use std::{ + any::Any, borrow::Cow, - fmt::{Debug, Display}, + fmt::Debug, hash::{Hash, Hasher}, - marker::PhantomData, - sync::Arc, }; -use crate::{StageLabel, SystemLabel}; +use crate::{StageLabelMarker, SystemLabelMarker}; -pub struct Label(Arc>, PhantomData); +pub trait Label: DynHash + DynClone + Send + Sync + 'static { + fn name(&self) -> Cow<'static, str>; +} -impl Clone for Label { - fn clone(&self) -> Self { - Label(self.0.clone(), Default::default()) +impl Debug for dyn Label { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.name()) } } -impl Hash for Label { - fn hash(&self, state: &mut H) { - self.0.dyn_hash(state); +pub type SystemLabel = Box>; +pub type StageLabel = Box>; + +pub trait DynEq: Any { + fn as_any(&self) -> &dyn Any; + + fn dyn_eq(&self, other: &dyn DynEq) -> bool; +} + +impl DynEq for T +where + T: Any + Eq, +{ + fn as_any(&self) -> &dyn Any { + self + } + + fn dyn_eq(&self, other: &dyn DynEq) -> bool { + if let Some(other) = other.as_any().downcast_ref::() { + return self == other; + } + false } } -impl PartialEq for Label { - fn eq(&self, other: &Self) -> bool { - // Consider using pointer comparison like https://github.com/rust-lang/rust/issues/46139#issuecomment-416101127 - self.0.downcast_eq(&*other.0.as_ref()) +pub trait DynHash: DynEq { + fn as_dyn_eq(&self) -> &dyn DynEq; + + fn dyn_hash(&self, state: &mut dyn Hasher); +} + +impl DynHash for T +where + T: DynEq + Hash, +{ + fn as_dyn_eq(&self) -> &dyn DynEq { + self + } + + fn dyn_hash(&self, mut state: &mut dyn Hasher) { + T::hash(self, &mut state); + self.type_id().hash(&mut state); } } -impl Eq for Label {} +pub trait DynClone { + fn dyn_clone(&self) -> Box>; +} -impl Display for Label { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.to_str()) +impl DynClone for T +where + T: Label + Clone + 'static, +{ + fn dyn_clone(&self) -> Box> { + Box::new(self.clone()) } } -impl Debug for Label { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("\"")?; - f.write_str(&self.to_str())?; - f.write_str("\"")?; - Ok(()) +impl PartialEq for dyn Label { + fn eq(&self, other: &Self) -> bool { + self.dyn_eq(other.as_dyn_eq()) } } -impl Label { - pub fn name(&self) -> Cow<'static, str> { - self.0.name() +impl Eq for dyn Label {} + +impl Hash for dyn Label { + fn hash(&self, state: &mut H) { + self.dyn_hash(state); } } -pub trait IntoLabel: Downcast + Send + Sync + 'static { - fn name(&self) -> Cow<'static, str>; - fn downcast_eq(&self, other: &dyn IntoLabel) -> bool; - fn dyn_hash(&self, hasher: &mut dyn Hasher); +impl Clone for Box> { + fn clone(&self) -> Self { + self.dyn_clone() + } } -impl + Eq + Hash + Clone> From for Label { +impl> From for Box> { fn from(t: T) -> Self { - Label(Arc::new(t), Default::default()) + Box::new(t) } } -impl + Eq + Hash + Clone> From for Label { +impl> From for Box> { fn from(t: T) -> Self { - Label(Arc::new(t), Default::default()) + Box::new(t) } } -pub trait FullIntoLabel: IntoLabel + Eq + Hash + Clone {} - -impl + Eq + Hash + Clone> FullIntoLabel for T {} - -downcast_rs::impl_downcast!(IntoLabel); +impl Label for Cow<'static, str> { + fn name(&self) -> Cow<'static, str> { + self.clone() + } +} -impl Label { - pub fn to_str(&self) -> Cow<'static, str> { - self.0.name() +impl Label for &'static str { + fn name(&self) -> Cow<'static, str> { + Cow::Borrowed(self) + } +} +impl Label for Cow<'static, str> { + fn name(&self) -> Cow<'static, str> { + self.clone() } } -#[cfg(test)] -mod test { - use super::*; - use crate::IntoLabel; - struct LabelT; - #[derive(IntoLabel, PartialEq, Eq, Hash, Debug)] - #[label_type(LabelT)] - struct L(&'static str); - #[test] - fn label_eq_test() { - let label_1 = L("A"); - let label_2 = L("A"); - assert_eq!(label_1, label_2); +impl Label for &'static str { + fn name(&self) -> Cow<'static, str> { + Cow::Borrowed(self) } } diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 88b15cd187cc3..e3df47ddc7eef 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -24,23 +24,23 @@ use std::{any::TypeId, borrow::Cow}; #[derive(Default)] pub struct Schedule { - stages: HashMap, Box>, - stage_order: Vec>, + stages: HashMap>, + stage_order: Vec, run_criteria: RunCriteria, } -pub struct StageLabel; +pub struct StageLabelMarker; impl Schedule { - pub fn with_stage(mut self, name: impl FullIntoLabel, stage: S) -> Self { + pub fn with_stage(mut self, name: impl Into, stage: S) -> Self { self.add_stage(name, stage); self } pub fn with_stage_after( mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> Self { self.add_stage_after(target, name, stage); @@ -49,8 +49,8 @@ impl Schedule { pub fn with_stage_before( mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> Self { self.add_stage_before(target, name, stage); @@ -64,7 +64,7 @@ impl Schedule { pub fn with_system_in_stage( mut self, - stage_name: impl FullIntoLabel, + stage_name: impl Into, system: impl Into, ) -> Self { self.add_system_to_stage(stage_name, system); @@ -81,11 +81,12 @@ impl Schedule { pub fn add_stage( &mut self, - name: impl FullIntoLabel, + name: impl Into, stage: S, ) -> &mut Self { - self.stage_order.push(name.clone().into()); - let prev = self.stages.insert(name.clone().into(), Box::new(stage)); + let name = name.into(); + self.stage_order.push(name.clone()); + let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { panic!("Stage already exists: {}.", name.name()); } @@ -94,21 +95,23 @@ impl Schedule { pub fn add_stage_after( &mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> &mut Self { + let name = name.into(); + let target = target.into(); let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_name)| **stage_name == target.clone().into()) + .find(|(_i, stage_name)| **stage_name == target.clone()) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); self.stage_order - .insert(target_index + 1, name.clone().into()); - let prev = self.stages.insert(name.clone().into(), Box::new(stage)); + .insert(target_index + 1, name.clone()); + let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { panic!("Stage already exists: {}.", name.name()); } @@ -117,20 +120,22 @@ impl Schedule { pub fn add_stage_before( &mut self, - target: impl FullIntoLabel, - name: impl FullIntoLabel, + target: impl Into, + name: impl Into, stage: S, ) -> &mut Self { + let name = name.into(); + let target = target.into(); let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_name)| **stage_name == target.clone().into()) + .find(|(_i, stage_name)| **stage_name == target.clone()) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); - self.stage_order.insert(target_index, name.clone().into()); - let prev = self.stages.insert(name.clone().into(), Box::new(stage)); + self.stage_order.insert(target_index, name.clone()); + let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { panic!("Stage already exists: {}.", name.name()); } @@ -139,37 +144,37 @@ impl Schedule { pub fn add_system_to_stage( &mut self, - stage_name: impl FullIntoLabel, + stage_name: impl Into, system: impl Into, ) -> &mut Self { - let name = stage_name.name().to_owned(); + let name = stage_name.into(); let stage = self - .get_stage_mut::(stage_name) - .unwrap_or_else(|| panic!("Stage '{}' does not exist or is not a SystemStage", name)); + .get_stage_mut::(name.clone()) + .unwrap_or_else(move || panic!("Stage '{}' does not exist or is not a SystemStage", name.name())); stage.add_system(system); self } pub fn stage &mut T>( &mut self, - name: impl FullIntoLabel, + name: impl Into, func: F, ) -> &mut Self { - let str_name = name.name().to_owned(); + let name = name.into(); let stage = self - .get_stage_mut::(name) - .unwrap_or_else(|| panic!("stage '{}' does not exist or is the wrong type", str_name)); + .get_stage_mut::(name.clone()) + .unwrap_or_else(move || panic!("stage '{}' does not exist or is the wrong type", name.name())); func(stage); self } - pub fn get_stage(&self, name: impl FullIntoLabel) -> Option<&T> { + pub fn get_stage(&self, name: impl Into) -> Option<&T> { self.stages .get(&name.into()) .and_then(|stage| stage.downcast_ref::()) } - pub fn get_stage_mut>( + pub fn get_stage_mut>( &mut self, name: L, ) -> Option<&mut T> { @@ -181,7 +186,7 @@ impl Schedule { pub fn run_once(&mut self, world: &mut World, resources: &mut Resources) { for name in self.stage_order.iter() { #[cfg(feature = "trace")] - let stage_span = bevy_utils::tracing::info_span!("stage", name = &*name.to_str()); + let stage_span = bevy_utils::tracing::info_span!("stage", name = &*name.name()); #[cfg(feature = "trace")] let _stage_guard = stage_span.enter(); let stage = self.stages.get_mut(name).unwrap(); diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 8cc868a287d71..59a4ec0f01b90 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -8,7 +8,7 @@ use super::{ SingleThreadedExecutor, SystemContainer, }; use crate::{ - InsertionPoint, Label, Resources, RunCriteria, + InsertionPoint, Resources, RunCriteria, ShouldRun::{self, *}, System, SystemDescriptor, SystemLabel, SystemSet, World, }; @@ -350,8 +350,8 @@ impl SystemStage { } enum DependencyGraphError { - LabelNotFound(Label), - DuplicateLabel(Label), + LabelNotFound(SystemLabel), + DuplicateLabel(SystemLabel), GraphCycles(Vec>), } @@ -381,7 +381,7 @@ fn sort_systems(systems: &mut Vec) -> Result<(), Dependenc fn build_dependency_graph( systems: &[impl SystemContainer], ) -> Result>, DependencyGraphError> { - let mut labels = HashMap::, usize>::default(); + let mut labels = HashMap::::default(); for (label, index) in systems.iter().enumerate().filter_map(|(index, container)| { container .label() @@ -610,7 +610,7 @@ impl Stage for SystemStage { #[cfg(test)] mod tests { - use crate::{prelude::*, SingleThreadedExecutor, SystemLabel}; + use crate::{prelude::*, SingleThreadedExecutor}; fn make_exclusive(tag: usize) -> impl FnMut(&mut Resources) { move |resources| resources.get_mut::>().unwrap().push(tag) @@ -626,12 +626,6 @@ mod tests { }}; } - // string based label for tests - #[derive(IntoLabel, PartialEq, Eq, Hash, Clone)] - #[label_type(SystemLabel)] - #[name_expr(self.0)] - struct L(&'static str); - fn empty() {} fn resettable_run_once(mut has_ran: ResMut) -> ShouldRun { @@ -700,8 +694,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().at_end().label(L("empty"))) - .with_system(empty.exclusive_system().after(L("empty"))); + .with_system(empty.exclusive_system().at_end().label("empty")) + .with_system(empty.exclusive_system().after("empty")); stage.run(&mut world, &mut resources); } @@ -714,12 +708,12 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().at_end().label(L("empty"))) - .with_system(empty.exclusive_system().before_commands().label(L("empty"))); + .with_system(empty.exclusive_system().at_end().label("empty")) + .with_system(empty.exclusive_system().before_commands().label("empty")); stage.run(&mut world, &mut resources); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().label(L("empty"))) - .with_system(empty.exclusive_system().label(L("empty"))); + .with_system(empty.exclusive_system().label("empty")) + .with_system(empty.exclusive_system().label("empty")); stage.run(&mut world, &mut resources); } @@ -729,14 +723,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system( - make_exclusive(1) - .exclusive_system() - .label(L("1")) - .after(L("0")), - ) - .with_system(make_exclusive(2).exclusive_system().after(L("1"))) - .with_system(make_exclusive(0).exclusive_system().label(L("0"))); + .with_system(make_exclusive(1).exclusive_system().label("1").after("0")) + .with_system(make_exclusive(2).exclusive_system().after("1")) + .with_system(make_exclusive(0).exclusive_system().label("0")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -752,14 +741,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system( - make_exclusive(1) - .exclusive_system() - .label(L("1")) - .before(L("2")), - ) - .with_system(make_exclusive(2).exclusive_system().label(L("2"))) - .with_system(make_exclusive(0).exclusive_system().before(L("1"))); + .with_system(make_exclusive(1).exclusive_system().label("1").before("2")) + .with_system(make_exclusive(2).exclusive_system().label("2")) + .with_system(make_exclusive(0).exclusive_system().before("1")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -775,21 +759,11 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().label(L("2"))) - .with_system( - make_exclusive(1) - .exclusive_system() - .after(L("0")) - .before(L("2")), - ) - .with_system(make_exclusive(0).exclusive_system().label(L("0"))) - .with_system(make_exclusive(4).exclusive_system().label(L("4"))) - .with_system( - make_exclusive(3) - .exclusive_system() - .after(L("2")) - .before(L("4")), - ); + .with_system(make_exclusive(2).exclusive_system().label("2")) + .with_system(make_exclusive(1).exclusive_system().after("0").before("2")) + .with_system(make_exclusive(0).exclusive_system().label("0")) + .with_system(make_exclusive(4).exclusive_system().label("4")) + .with_system(make_exclusive(3).exclusive_system().after("2").before("4")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -808,37 +782,27 @@ mod tests { .with_system( make_exclusive(2) .exclusive_system() - .label(L("2")) - .after(L("1")) - .before(L("3")) - .before(L("3")), + .label("2") + .after("1") + .before("3") + .before("3"), ) .with_system( make_exclusive(1) .exclusive_system() - .label(L("1")) - .after(L("0")) - .after(L("0")) - .before(L("2")), - ) - .with_system( - make_exclusive(0) - .exclusive_system() - .label(L("0")) - .before(L("1")), - ) - .with_system( - make_exclusive(4) - .exclusive_system() - .label(L("4")) - .after(L("3")), + .label("1") + .after("0") + .after("0") + .before("2"), ) + .with_system(make_exclusive(0).exclusive_system().label("0").before("1")) + .with_system(make_exclusive(4).exclusive_system().label("4").after("3")) .with_system( make_exclusive(3) .exclusive_system() - .label(L("3")) - .after(L("2")) - .before(L("4")), + .label("3") + .after("2") + .before("4"), ); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); @@ -855,24 +819,14 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().label(L("2"))) + .with_system(make_exclusive(2).exclusive_system().label("2")) .with_system_set( SystemSet::new() - .with_system(make_exclusive(0).exclusive_system().label(L("0"))) - .with_system(make_exclusive(4).exclusive_system().label(L("4"))) - .with_system( - make_exclusive(3) - .exclusive_system() - .after(L("2")) - .before(L("4")), - ), + .with_system(make_exclusive(0).exclusive_system().label("0")) + .with_system(make_exclusive(4).exclusive_system().label("4")) + .with_system(make_exclusive(3).exclusive_system().after("2").before("4")), ) - .with_system( - make_exclusive(1) - .exclusive_system() - .after(L("0")) - .before(L("2")), - ); + .with_system(make_exclusive(1).exclusive_system().after("0").before("2")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -889,13 +843,13 @@ mod tests { resources.insert(Vec::::new()); resources.insert(false); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().before(L("1"))) + .with_system(make_exclusive(0).exclusive_system().before("1")) .with_system_set( SystemSet::new() .with_run_criteria(resettable_run_once.system()) - .with_system(make_exclusive(1).exclusive_system().label(L("1"))), + .with_system(make_exclusive(1).exclusive_system().label("1")), ) - .with_system(make_exclusive(2).exclusive_system().after(L("1"))); + .with_system(make_exclusive(2).exclusive_system().after("1")); stage.run(&mut world, &mut resources); stage.run(&mut world, &mut resources); *resources.get_mut::().unwrap() = false; @@ -914,12 +868,8 @@ mod tests { let mut world = World::new(); let mut resources = Resources::default(); resources.insert(Vec::::new()); - let mut stage = SystemStage::parallel().with_system( - make_exclusive(0) - .exclusive_system() - .label(L("0")) - .after(L("0")), - ); + let mut stage = SystemStage::parallel() + .with_system(make_exclusive(0).exclusive_system().label("0").after("0")); stage.run(&mut world, &mut resources); } @@ -930,18 +880,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system( - make_exclusive(0) - .exclusive_system() - .label(L("0")) - .after(L("1")), - ) - .with_system( - make_exclusive(1) - .exclusive_system() - .label(L("1")) - .after(L("0")), - ); + .with_system(make_exclusive(0).exclusive_system().label("0").after("1")) + .with_system(make_exclusive(1).exclusive_system().label("1").after("0")); stage.run(&mut world, &mut resources); } @@ -952,19 +892,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().label(L("0"))) - .with_system( - make_exclusive(1) - .exclusive_system() - .after(L("0")) - .before(L("2")), - ) - .with_system( - make_exclusive(2) - .exclusive_system() - .label(L("2")) - .before(L("0")), - ); + .with_system(make_exclusive(0).exclusive_system().label("0")) + .with_system(make_exclusive(1).exclusive_system().after("0").before("2")) + .with_system(make_exclusive(2).exclusive_system().label("2").before("0")); stage.run(&mut world, &mut resources); } @@ -976,7 +906,7 @@ mod tests { resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() .with_system(empty.system()) - .with_system(empty.system().after(L("empty"))); + .with_system(empty.system().after("empty")); stage.run(&mut world, &mut resources); } @@ -987,8 +917,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(empty.system().label(L("empty"))) - .with_system(empty.system().label(L("empty"))); + .with_system(empty.system().label("empty")) + .with_system(empty.system().label("empty")); stage.run(&mut world, &mut resources); } @@ -998,9 +928,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(1).system().after(L("0")).label(L("1"))) - .with_system(make_parallel!(2).system().after(L("1"))) - .with_system(make_parallel!(0).system().label(L("0"))); + .with_system(make_parallel!(1).system().after("0").label("1")) + .with_system(make_parallel!(2).system().after("1")) + .with_system(make_parallel!(0).system().label("0")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -1016,9 +946,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(1).system().label(L("1")).before(L("2"))) - .with_system(make_parallel!(2).system().label(L("2"))) - .with_system(make_parallel!(0).system().before(L("1"))); + .with_system(make_parallel!(1).system().label("1").before("2")) + .with_system(make_parallel!(2).system().label("2")) + .with_system(make_parallel!(0).system().before("1")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -1034,11 +964,11 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(2).system().label(L("2"))) - .with_system(make_parallel!(1).system().after(L("0")).before(L("2"))) - .with_system(make_parallel!(0).system().label(L("0"))) - .with_system(make_parallel!(4).system().label(L("4"))) - .with_system(make_parallel!(3).system().after(L("2")).before(L("4"))); + .with_system(make_parallel!(2).system().label("2")) + .with_system(make_parallel!(1).system().after("0").before("2")) + .with_system(make_parallel!(0).system().label("0")) + .with_system(make_parallel!(4).system().label("4")) + .with_system(make_parallel!(3).system().after("2").before("4")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -1057,28 +987,22 @@ mod tests { .with_system( make_parallel!(2) .system() - .label(L("2")) - .after(L("1")) - .before(L("3")) - .before(L("3")), + .label("2") + .after("1") + .before("3") + .before("3"), ) .with_system( make_parallel!(1) .system() - .label(L("1")) - .after(L("0")) - .after(L("0")) - .before(L("2")), + .label("1") + .after("0") + .after("0") + .before("2"), ) - .with_system(make_parallel!(0).system().label(L("0")).before(L("1"))) - .with_system(make_parallel!(4).system().label(L("4")).after(L("3"))) - .with_system( - make_parallel!(3) - .system() - .label(L("3")) - .after(L("2")) - .before(L("4")), - ); + .with_system(make_parallel!(0).system().label("0").before("1")) + .with_system(make_parallel!(4).system().label("4").after("3")) + .with_system(make_parallel!(3).system().label("3").after("2").before("4")); stage.run(&mut world, &mut resources); for container in stage.parallel.iter() { assert!(container.dependencies().len() <= 1); @@ -1097,14 +1021,14 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(2).system().label(L("2"))) + .with_system(make_parallel!(2).system().label("2")) .with_system_set( SystemSet::new() - .with_system(make_parallel!(0).system().label(L("0"))) - .with_system(make_parallel!(4).system().label(L("4"))) - .with_system(make_parallel!(3).system().after(L("2")).before(L("4"))), + .with_system(make_parallel!(0).system().label("0")) + .with_system(make_parallel!(4).system().label("4")) + .with_system(make_parallel!(3).system().after("2").before("4")), ) - .with_system(make_parallel!(1).system().after(L("0")).before(L("2"))); + .with_system(make_parallel!(1).system().after("0").before("2")); stage.run(&mut world, &mut resources); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world, &mut resources); @@ -1121,13 +1045,13 @@ mod tests { resources.insert(Vec::::new()); resources.insert(false); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().before(L("1"))) + .with_system(make_parallel!(0).system().before("1")) .with_system_set( SystemSet::new() .with_run_criteria(resettable_run_once.system()) - .with_system(make_parallel!(1).system().label(L("1"))), + .with_system(make_parallel!(1).system().label("1")), ) - .with_system(make_parallel!(2).system().after(L("1"))); + .with_system(make_parallel!(2).system().after("1")); stage.run(&mut world, &mut resources); stage.run(&mut world, &mut resources); *resources.get_mut::().unwrap() = false; @@ -1146,8 +1070,8 @@ mod tests { let mut world = World::new(); let mut resources = Resources::default(); resources.insert(Vec::::new()); - let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().label(L("0")).after(L("0"))); + let mut stage = + SystemStage::parallel().with_system(make_parallel!(0).system().label("0").after("0")); stage.run(&mut world, &mut resources); } @@ -1158,8 +1082,8 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().label(L("0")).after(L("1"))) - .with_system(make_parallel!(1).system().label(L("1")).after(L("0"))); + .with_system(make_parallel!(0).system().label("0").after("1")) + .with_system(make_parallel!(1).system().label("1").after("0")); stage.run(&mut world, &mut resources); } @@ -1170,9 +1094,9 @@ mod tests { let mut resources = Resources::default(); resources.insert(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_parallel!(0).system().label(L("0"))) - .with_system(make_parallel!(1).system().after(L("0")).before(L("2"))) - .with_system(make_parallel!(2).system().label(L("2")).before(L("0"))); + .with_system(make_parallel!(0).system().label("0")) + .with_system(make_parallel!(1).system().after("0").before("2")) + .with_system(make_parallel!(2).system().label("2").before("0")); stage.run(&mut world, &mut resources); } @@ -1203,21 +1127,21 @@ mod tests { let mut resources = Resources::default(); let mut stage = SystemStage::parallel() - .with_system(empty.system().label(L("0"))) - .with_system(empty.system().label(L("1")).after(L("0"))) - .with_system(empty.system().label(L("2"))) - .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) - .with_system(empty.system().label(L("4"))); + .with_system(empty.system().label("0")) + .with_system(empty.system().label("1").after("0")) + .with_system(empty.system().label("2")) + .with_system(empty.system().label("3").after("2").before("4")) + .with_system(empty.system().label("4")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); assert_eq!(find_ambiguities(&stage.parallel).len(), 0); let mut stage = SystemStage::parallel() - .with_system(empty.system().label(L("0"))) - .with_system(component.system().label(L("1")).after(L("0"))) - .with_system(empty.system().label(L("2"))) - .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) - .with_system(component.system().label(L("4"))); + .with_system(empty.system().label("0")) + .with_system(component.system().label("1").after("0")) + .with_system(empty.system().label("2")) + .with_system(empty.system().label("3").after("2").before("4")) + .with_system(component.system().label("4")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1228,11 +1152,11 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(empty.system().label(L("0"))) - .with_system(resource.system().label(L("1")).after(L("0"))) - .with_system(empty.system().label(L("2"))) - .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) - .with_system(resource.system().label(L("4"))); + .with_system(empty.system().label("0")) + .with_system(resource.system().label("1").after("0")) + .with_system(empty.system().label("2")) + .with_system(empty.system().label("3").after("2").before("4")) + .with_system(resource.system().label("4")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1243,27 +1167,21 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(empty.system().label(L("0"))) - .with_system(resource.system().label(L("1")).after(L("0"))) - .with_system(empty.system().label(L("2"))) - .with_system(empty.system().label(L("3")).after(L("2")).before(L("4"))) - .with_system(component.system().label(L("4"))); + .with_system(empty.system().label("0")) + .with_system(resource.system().label("1").after("0")) + .with_system(empty.system().label("2")) + .with_system(empty.system().label("3").after("2").before("4")) + .with_system(component.system().label("4")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); assert_eq!(find_ambiguities(&stage.parallel).len(), 0); let mut stage = SystemStage::parallel() - .with_system(component.system().label(L("0"))) - .with_system(resource.system().label(L("1")).after(L("0"))) - .with_system(empty.system().label(L("2"))) - .with_system( - component - .system() - .label(L("3")) - .after(L("2")) - .before(L("4")), - ) - .with_system(resource.system().label(L("4"))); + .with_system(component.system().label("0")) + .with_system(resource.system().label("1").after("0")) + .with_system(empty.system().label("2")) + .with_system(component.system().label("3").after("2").before("4")) + .with_system(resource.system().label("4")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1278,9 +1196,9 @@ mod tests { assert_eq!(ambiguities.len(), 2); let mut stage = SystemStage::parallel() - .with_system(component.system().label(L("0")).before(L("2"))) - .with_system(component.system().label(L("1")).before(L("2"))) - .with_system(component.system().label(L("2"))); + .with_system(component.system().label("0").before("2")) + .with_system(component.system().label("1").before("2")) + .with_system(component.system().label("2")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1291,9 +1209,9 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system(component.system().label(L("0"))) - .with_system(component.system().label(L("1")).after(L("0"))) - .with_system(component.system().label(L("2")).after(L("0"))); + .with_system(component.system().label("0")) + .with_system(component.system().label("1").after("0")) + .with_system(component.system().label("2").after("0")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1304,16 +1222,10 @@ mod tests { assert_eq!(ambiguities.len(), 1); let mut stage = SystemStage::parallel() - .with_system( - component - .system() - .label(L("0")) - .before(L("1")) - .before(L("2")), - ) - .with_system(component.system().label(L("1"))) - .with_system(component.system().label(L("2"))) - .with_system(component.system().label(L("3")).after(L("1")).after(L("2"))); + .with_system(component.system().label("0").before("1").before("2")) + .with_system(component.system().label("1")) + .with_system(component.system().label("2")) + .with_system(component.system().label("3").after("1").after("2")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); @@ -1327,24 +1239,24 @@ mod tests { .with_system( component .system() - .label(L("0")) - .before(L("1")) - .before(L("2")) - .before(L("3")) - .before(L("4")), + .label("0") + .before("1") + .before("2") + .before("3") + .before("4"), ) - .with_system(component.system().label(L("1"))) - .with_system(component.system().label(L("2"))) - .with_system(component.system().label(L("3"))) - .with_system(component.system().label(L("4"))) + .with_system(component.system().label("1")) + .with_system(component.system().label("2")) + .with_system(component.system().label("3")) + .with_system(component.system().label("4")) .with_system( component .system() - .label(L("5")) - .after(L("1")) - .after(L("2")) - .after(L("3")) - .after(L("4")), + .label("5") + .after("1") + .after("2") + .after("3") + .after("4"), ); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); @@ -1376,44 +1288,26 @@ mod tests { assert_eq!(ambiguities.len(), 6); let mut stage = SystemStage::parallel() - .with_system(empty.exclusive_system().label(L("0"))) - .with_system(empty.exclusive_system().label(L("1")).after(L("0"))) - .with_system(empty.exclusive_system().label(L("2")).after(L("1"))) - .with_system(empty.exclusive_system().label(L("3")).after(L("2"))) - .with_system(empty.exclusive_system().label(L("4")).after(L("3"))) - .with_system(empty.exclusive_system().label(L("5")).after(L("4"))) - .with_system(empty.exclusive_system().label(L("6")).after(L("5"))) - .with_system(empty.exclusive_system().label(L("7")).after(L("6"))); + .with_system(empty.exclusive_system().label("0")) + .with_system(empty.exclusive_system().label("1").after("0")) + .with_system(empty.exclusive_system().label("2").after("1")) + .with_system(empty.exclusive_system().label("3").after("2")) + .with_system(empty.exclusive_system().label("4").after("3")) + .with_system(empty.exclusive_system().label("5").after("4")) + .with_system(empty.exclusive_system().label("6").after("5")) + .with_system(empty.exclusive_system().label("7").after("6")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); assert_eq!(find_ambiguities(&stage.exclusive_at_start).len(), 0); let mut stage = SystemStage::parallel() - .with_system( - empty - .exclusive_system() - .label(L("0")) - .before(L("1")) - .before(L("3")), - ) - .with_system(empty.exclusive_system().label(L("1"))) - .with_system(empty.exclusive_system().label(L("2")).after(L("1"))) - .with_system(empty.exclusive_system().label(L("3"))) - .with_system( - empty - .exclusive_system() - .label(L("4")) - .after(L("3")) - .before(L("5")), - ) - .with_system(empty.exclusive_system().label(L("5"))) - .with_system( - empty - .exclusive_system() - .label(L("6")) - .after(L("2")) - .after(L("5")), - ); + .with_system(empty.exclusive_system().label("0").before("1").before("3")) + .with_system(empty.exclusive_system().label("1")) + .with_system(empty.exclusive_system().label("2").after("1")) + .with_system(empty.exclusive_system().label("3")) + .with_system(empty.exclusive_system().label("4").after("3").before("5")) + .with_system(empty.exclusive_system().label("5")) + .with_system(empty.exclusive_system().label("6").after("2").after("5")); stage.initialize_systems(&mut world, &mut resources); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start); diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index e36e2f822037d..80824c6d45725 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, ptr::NonNull}; use crate::{ - ExclusiveSystem, ExclusiveSystemDescriptor, Label, ParallelSystemDescriptor, System, + ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System, SystemLabel, }; @@ -10,9 +10,9 @@ pub(super) trait SystemContainer { fn dependencies(&self) -> &[usize]; fn set_dependencies(&mut self, dependencies: impl IntoIterator); fn system_set(&self) -> usize; - fn label(&self) -> &Option>; - fn before(&self) -> &[Label]; - fn after(&self) -> &[Label]; + fn label(&self) -> &Option; + fn before(&self) -> &[SystemLabel]; + fn after(&self) -> &[SystemLabel]; fn is_compatible(&self, other: &Self) -> bool; } @@ -20,9 +20,9 @@ pub(super) struct ExclusiveSystemContainer { system: Box, dependencies: Vec, set: usize, - label: Option>, - before: Vec>, - after: Vec>, + label: Option, + before: Vec, + after: Vec, } impl ExclusiveSystemContainer { @@ -63,15 +63,15 @@ impl SystemContainer for ExclusiveSystemContainer { self.set } - fn label(&self) -> &Option> { + fn label(&self) -> &Option { &self.label } - fn before(&self) -> &[Label] { + fn before(&self) -> &[SystemLabel] { &self.before } - fn after(&self) -> &[Label] { + fn after(&self) -> &[SystemLabel] { &self.after } @@ -85,9 +85,9 @@ pub struct ParallelSystemContainer { pub(crate) should_run: bool, dependencies: Vec, set: usize, - label: Option>, - before: Vec>, - after: Vec>, + label: Option, + before: Vec, + after: Vec, } impl SystemContainer for ParallelSystemContainer { @@ -111,15 +111,15 @@ impl SystemContainer for ParallelSystemContainer { self.set } - fn label(&self) -> &Option> { + fn label(&self) -> &Option { &self.label } - fn before(&self) -> &[Label] { + fn before(&self) -> &[SystemLabel] { &self.before } - fn after(&self) -> &[Label] { + fn after(&self) -> &[SystemLabel] { &self.after } diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index 7bd7e7853aba3..55f189dc2ad6a 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -1,6 +1,4 @@ -use crate::{ - BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, Label, System, -}; +use crate::{BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, System, SystemLabel}; /// Encapsulates a system and information on when it run in a `SystemStage`. /// @@ -22,7 +20,7 @@ use crate::{ /// # fn do_something() {} /// # fn do_the_other_thing() {} /// # fn do_something_else() {} -/// #[derive(IntoLabel, PartialEq, Eq, Hash)] +/// #[derive(Label, PartialEq, Eq, Hash)] /// #[label_type(SystemLabel)] /// struct Something; /// @@ -36,7 +34,7 @@ pub enum SystemDescriptor { Exclusive(ExclusiveSystemDescriptor), } -pub struct SystemLabel; +pub struct SystemLabelMarker; impl From for SystemDescriptor { fn from(descriptor: ParallelSystemDescriptor) -> Self { @@ -80,9 +78,9 @@ impl From for SystemDescriptor { /// Encapsulates a parallel system and information on when it run in a `SystemStage`. pub struct ParallelSystemDescriptor { pub(crate) system: BoxedSystem<(), ()>, - pub(crate) label: Option>, - pub(crate) before: Vec>, - pub(crate) after: Vec>, + pub(crate) label: Option, + pub(crate) before: Vec, + pub(crate) after: Vec, } fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor { @@ -96,27 +94,27 @@ fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescrip pub trait ParallelSystemDescriptorCoercion { /// Assigns a label to the system. - fn label(self, label: impl Into>) -> ParallelSystemDescriptor; + fn label(self, label: impl Into) -> ParallelSystemDescriptor; /// Specifies that the system should run before the system with given label. - fn before(self, label: impl Into>) -> ParallelSystemDescriptor; + fn before(self, label: impl Into) -> ParallelSystemDescriptor; /// Specifies that the system should run after the system with given label. - fn after(self, label: impl Into>) -> ParallelSystemDescriptor; + fn after(self, label: impl Into) -> ParallelSystemDescriptor; } impl ParallelSystemDescriptorCoercion for ParallelSystemDescriptor { - fn label(mut self, label: impl Into>) -> ParallelSystemDescriptor { + fn label(mut self, label: impl Into) -> ParallelSystemDescriptor { self.label = Some(label.into()); self } - fn before(mut self, label: impl Into>) -> ParallelSystemDescriptor { + fn before(mut self, label: impl Into) -> ParallelSystemDescriptor { self.before.push(label.into()); self } - fn after(mut self, label: impl Into>) -> ParallelSystemDescriptor { + fn after(mut self, label: impl Into) -> ParallelSystemDescriptor { self.after.push(label.into()); self } @@ -126,29 +124,29 @@ impl ParallelSystemDescriptorCoercion for S where S: System, { - fn label(self, label: impl Into>) -> ParallelSystemDescriptor { + fn label(self, label: impl Into) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).label(label) } - fn before(self, label: impl Into>) -> ParallelSystemDescriptor { + fn before(self, label: impl Into) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).before(label) } - fn after(self, label: impl Into>) -> ParallelSystemDescriptor { + fn after(self, label: impl Into) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).after(label) } } impl ParallelSystemDescriptorCoercion for BoxedSystem<(), ()> { - fn label(self, label: impl Into>) -> ParallelSystemDescriptor { + fn label(self, label: impl Into) -> ParallelSystemDescriptor { new_parallel_descriptor(self).label(label) } - fn before(self, label: impl Into>) -> ParallelSystemDescriptor { + fn before(self, label: impl Into) -> ParallelSystemDescriptor { new_parallel_descriptor(self).before(label) } - fn after(self, label: impl Into>) -> ParallelSystemDescriptor { + fn after(self, label: impl Into) -> ParallelSystemDescriptor { new_parallel_descriptor(self).after(label) } } @@ -163,9 +161,9 @@ pub(crate) enum InsertionPoint { /// Encapsulates an exclusive system and information on when it run in a `SystemStage`. pub struct ExclusiveSystemDescriptor { pub(crate) system: Box, - pub(crate) label: Option>, - pub(crate) before: Vec>, - pub(crate) after: Vec>, + pub(crate) label: Option, + pub(crate) before: Vec, + pub(crate) after: Vec, pub(crate) insertion_point: InsertionPoint, } @@ -181,13 +179,13 @@ fn new_exclusive_descriptor(system: Box) -> ExclusiveSystem pub trait ExclusiveSystemDescriptorCoercion { /// Assigns a label to the system. - fn label(self, label: impl Into>) -> ExclusiveSystemDescriptor; + fn label(self, label: impl Into) -> ExclusiveSystemDescriptor; /// Specifies that the system should run before the system with given label. - fn before(self, label: impl Into>) -> ExclusiveSystemDescriptor; + fn before(self, label: impl Into) -> ExclusiveSystemDescriptor; /// Specifies that the system should run after the system with given label. - fn after(self, label: impl Into>) -> ExclusiveSystemDescriptor; + fn after(self, label: impl Into) -> ExclusiveSystemDescriptor; /// Specifies that the system should run with other exclusive systems at the start of stage. fn at_start(self) -> ExclusiveSystemDescriptor; @@ -201,17 +199,17 @@ pub trait ExclusiveSystemDescriptorCoercion { } impl ExclusiveSystemDescriptorCoercion for ExclusiveSystemDescriptor { - fn label(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn label(mut self, label: impl Into) -> ExclusiveSystemDescriptor { self.label = Some(label.into()); self } - fn before(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn before(mut self, label: impl Into) -> ExclusiveSystemDescriptor { self.before.push(label.into()); self } - fn after(mut self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn after(mut self, label: impl Into) -> ExclusiveSystemDescriptor { self.after.push(label.into()); self } @@ -236,15 +234,15 @@ impl ExclusiveSystemDescriptorCoercion for T where T: ExclusiveSystem + 'static, { - fn label(self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn label(self, label: impl Into) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).label(label) } - fn before(self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn before(self, label: impl Into) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).before(label) } - fn after(self, label: impl Into>) -> ExclusiveSystemDescriptor { + fn after(self, label: impl Into) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).after(label) } diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index 0d893ef97dbc8..b944099a849a6 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -442,9 +442,7 @@ mod tests { assert!(*resources.get::().unwrap(), "system ran"); } - use crate::IntoLabel; - #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] - #[label_type(StageLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] enum TestLabels { CleanTrackers, Update, diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index fbc86664ca683..05df8133e99f8 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -52,10 +52,9 @@ use texture::HdrTextureLoader; #[cfg(feature = "png")] use texture::ImageTextureLoader; -use bevy_ecs::{IntoLabel, StageLabel}; +use bevy_ecs::StageLabel; /// The names of "render" App stages -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum RenderStage { /// Stage where render resources are set up RenderResource, diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 6ea03138969e4..d00562f9bbfe1 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -1,5 +1,5 @@ use super::{Edge, Node, NodeId, NodeLabel, NodeState, RenderGraphError, SlotLabel, SystemNode}; -use bevy_ecs::{Commands, IntoLabel, Schedule, StageLabel, SystemStage}; +use bevy_ecs::{Commands, Schedule, StageLabel, SystemStage}; use bevy_utils::HashMap; use std::{borrow::Cow, fmt::Debug}; pub struct RenderGraph { @@ -9,8 +9,7 @@ pub struct RenderGraph { commands: Commands, } -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct RenderGraphUpdate; impl Default for RenderGraph { diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index 393e11307d47e..143da56eb9757 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -24,9 +24,8 @@ use bevy_asset::AddAsset; #[derive(Default)] pub struct ScenePlugin; -use bevy_ecs::{IntoLabel, StageLabel}; -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +use bevy_ecs::{StageLabel}; +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] enum Stages { SceneStage, } diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs index 6366b639c2ff6..47f2066ed6b9c 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs @@ -71,12 +71,9 @@ pub fn parent_update_system( mod test { use super::*; use crate::{hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system}; - use bevy_ecs::{ - IntoLabel, IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World, - }; + use bevy_ecs::{IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World}; - #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] - #[label_type(StageLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct Update; #[test] diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index 9edda49109203..d26b6482af5f3 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -71,10 +71,9 @@ fn propagate_recursive( mod test { use super::*; use crate::hierarchy::{parent_update_system, BuildChildren, BuildWorldChildren}; - use bevy_ecs::{IntoLabel, Resources, Schedule, Stage, StageLabel, SystemStage, World}; + use bevy_ecs::{Resources, Schedule, Stage, StageLabel, SystemStage, World}; - #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] - #[label_type(StageLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct Update; #[test] diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index bec3af09c550f..74f2c4665ca4e 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -21,20 +21,18 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_ecs::{ - IntoLabel, IntoSystem, ParallelSystemDescriptorCoercion, StageLabel, SystemLabel, SystemStage, + IntoSystem, ParallelSystemDescriptorCoercion, StageLabel, SystemLabel, SystemStage, }; use bevy_render::render_graph::RenderGraph; use update::ui_z_system; #[derive(Default)] pub struct UiPlugin; -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum UiStages { Ui, } -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(SystemLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] pub enum UiSystems { Flex, } diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 500c93ad01f4d..183f1f94c1042 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -49,13 +49,12 @@ fn update_hierarchy( #[cfg(test)] mod tests { use bevy_ecs::{ - Commands, IntoLabel, IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World, + Commands, IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World, }; use bevy_transform::{components::Transform, hierarchy::BuildChildren}; use crate::Node; - #[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] - #[label_type(StageLabel)] + #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct Update; use super::{ui_z_system, UI_Z_STEP}; diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 7484892c7abcb..ed5bdd1ea00fa 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -13,8 +13,7 @@ fn main() { .run(); } -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct Stage; #[derive(Clone)] diff --git a/examples/ecs/ecs_guide.rs b/examples/ecs/ecs_guide.rs index 0ab25f2471557..e9ca12c158f54 100644 --- a/examples/ecs/ecs_guide.rs +++ b/examples/ecs/ecs_guide.rs @@ -239,8 +239,7 @@ fn local_state_system(mut state: Local, query: Query<(&Player, &Score)>) state.counter += 1; } -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] enum MyStages { BeforeRound, AfterRound, diff --git a/examples/ecs/fixed_timestep.rs b/examples/ecs/fixed_timestep.rs index 5d5c271e08ae8..beef7ad70ab76 100644 --- a/examples/ecs/fixed_timestep.rs +++ b/examples/ecs/fixed_timestep.rs @@ -5,8 +5,7 @@ use bevy::{ const LABEL: &str = "my_fixed_timestep"; -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct FixedUpdateStage; fn main() { diff --git a/examples/ecs/state.rs b/examples/ecs/state.rs index 96b060b8981e9..e3124f7b5dbf9 100644 --- a/examples/ecs/state.rs +++ b/examples/ecs/state.rs @@ -16,8 +16,7 @@ fn main() { .run(); } -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] struct Stage; #[derive(Clone)] diff --git a/examples/game/alien_cake_addict.rs b/examples/game/alien_cake_addict.rs index acfeda522a24a..eaae9f0515695 100644 --- a/examples/game/alien_cake_addict.rs +++ b/examples/game/alien_cake_addict.rs @@ -5,8 +5,7 @@ use bevy::{ }; use rand::Rng; -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] enum GameStages { InGame, BonusUpdate, diff --git a/examples/window/multiple_windows.rs b/examples/window/multiple_windows.rs index 4a1dbc5d391c9..34c868f128734 100644 --- a/examples/window/multiple_windows.rs +++ b/examples/window/multiple_windows.rs @@ -24,8 +24,7 @@ fn main() { .run(); } -#[derive(Debug, Hash, PartialEq, Eq, Clone, IntoLabel)] -#[label_type(StageLabel)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub struct Stage; // NOTE: this "state based" approach to multiple windows is a short term workaround. From 52567f56df8af6b15f57098513b63d93d5707a3d Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Mon, 15 Feb 2021 23:26:27 +0300 Subject: [PATCH 06/24] cargo fmt --- crates/bevy_app/src/app_builder.rs | 11 ++------ crates/bevy_ecs/src/lib.rs | 5 ++-- crates/bevy_ecs/src/schedule/mod.rs | 28 ++++++++++--------- .../bevy_ecs/src/schedule/system_container.rs | 3 +- .../src/schedule/system_descriptor.rs | 4 ++- crates/bevy_scene/src/lib.rs | 2 +- 6 files changed, 25 insertions(+), 28 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index dd94c91a83f4e..6c9b42734bcf4 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -5,9 +5,8 @@ use crate::{ CoreStage, PluginGroup, PluginGroupBuilder, StartupStage, }; use bevy_ecs::{ - clear_trackers_system, FromResources, IntoExclusiveSystem, IntoSystem, Resource, - Resources, RunOnce, Schedule, Stage, StageLabel, StateStage, SystemDescriptor, SystemStage, - World, + clear_trackers_system, FromResources, IntoExclusiveSystem, IntoSystem, Resource, Resources, + RunOnce, Schedule, Stage, StageLabel, StateStage, SystemDescriptor, SystemStage, World, }; use bevy_utils::tracing::debug; @@ -55,11 +54,7 @@ impl AppBuilder { self } - pub fn add_stage( - &mut self, - name: impl Into, - stage: S, - ) -> &mut Self { + pub fn add_stage(&mut self, name: impl Into, stage: S) -> &mut Self { self.app.schedule.add_stage(name, stage); self } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 1607e4b6ca3c9..2a2fc0a08fe30 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -20,8 +20,7 @@ pub mod prelude { SystemSet, SystemStage, }, system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Label, Mut, - Mutated, Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, - World, + Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Label, Mut, Mutated, + Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World, }; } diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index e3df47ddc7eef..4341c28c4227b 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -79,11 +79,7 @@ impl Schedule { self } - pub fn add_stage( - &mut self, - name: impl Into, - stage: S, - ) -> &mut Self { + pub fn add_stage(&mut self, name: impl Into, stage: S) -> &mut Self { let name = name.into(); self.stage_order.push(name.clone()); let prev = self.stages.insert(name.clone(), Box::new(stage)); @@ -109,8 +105,7 @@ impl Schedule { .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); - self.stage_order - .insert(target_index + 1, name.clone()); + self.stage_order.insert(target_index + 1, name.clone()); let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { panic!("Stage already exists: {}.", name.name()); @@ -150,7 +145,12 @@ impl Schedule { let name = stage_name.into(); let stage = self .get_stage_mut::(name.clone()) - .unwrap_or_else(move || panic!("Stage '{}' does not exist or is not a SystemStage", name.name())); + .unwrap_or_else(move || { + panic!( + "Stage '{}' does not exist or is not a SystemStage", + name.name() + ) + }); stage.add_system(system); self } @@ -163,7 +163,12 @@ impl Schedule { let name = name.into(); let stage = self .get_stage_mut::(name.clone()) - .unwrap_or_else(move || panic!("stage '{}' does not exist or is the wrong type", name.name())); + .unwrap_or_else(move || { + panic!( + "stage '{}' does not exist or is the wrong type", + name.name() + ) + }); func(stage); self } @@ -174,10 +179,7 @@ impl Schedule { .and_then(|stage| stage.downcast_ref::()) } - pub fn get_stage_mut>( - &mut self, - name: L, - ) -> Option<&mut T> { + pub fn get_stage_mut>(&mut self, name: L) -> Option<&mut T> { self.stages .get_mut(&name.into()) .and_then(|stage| stage.downcast_mut::()) diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index 80824c6d45725..351ac84194584 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,8 +1,7 @@ use std::{borrow::Cow, ptr::NonNull}; use crate::{ - ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System, - SystemLabel, + ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System, SystemLabel, }; pub(super) trait SystemContainer { diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index 55f189dc2ad6a..bb4c245fa59c1 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -1,4 +1,6 @@ -use crate::{BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, System, SystemLabel}; +use crate::{ + BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, System, SystemLabel, +}; /// Encapsulates a system and information on when it run in a `SystemStage`. /// diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index 143da56eb9757..3a571b51410c8 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -24,7 +24,7 @@ use bevy_asset::AddAsset; #[derive(Default)] pub struct ScenePlugin; -use bevy_ecs::{StageLabel}; +use bevy_ecs::StageLabel; #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] enum Stages { SceneStage, From 37941badb9581e1eb212ffbe6907c23ca2e011af Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Mon, 15 Feb 2021 23:55:51 +0300 Subject: [PATCH 07/24] cargo test --- crates/bevy_ecs/src/schedule/label.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 479ac3dc74d09..2d0d5e16b2f9c 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -13,7 +13,7 @@ pub trait Label: DynHash + DynClone + Send + Sync + 'static { impl Debug for dyn Label { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&self.name()) + f.write_str(&format!("\"{}\"", &self.name())) } } From fd3747c93235b2850f8d2b3a0b9ec9df7b5fca81 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 13:46:47 +0300 Subject: [PATCH 08/24] Improve Debug impl on dyn Label Co-authored-by: bjorn3 --- crates/bevy_ecs/src/schedule/label.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 2d0d5e16b2f9c..9e8bd0701c042 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -13,7 +13,7 @@ pub trait Label: DynHash + DynClone + Send + Sync + 'static { impl Debug for dyn Label { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(&format!("\"{}\"", &self.name())) + write!(f, "{:?}", self.name()) } } From 4b90fb0b281fa7c5596e01143c3b4b9eec6911cd Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 13:50:14 +0300 Subject: [PATCH 09/24] Apply suggestions from code review Co-authored-by: Alexander Sepity --- crates/bevy_app/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 577e109bdd5a3..8cacfa94ead33 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -3,7 +3,7 @@ use bevy_ecs::StageLabel; /// The names of the default App stages #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum CoreStage { - /// Name of the app stage that runs once at the beginning of the app + /// Runs once at the beginning of the app. Startup, /// Name of app stage that runs before all other app stages First, @@ -18,7 +18,7 @@ pub enum CoreStage { /// Name of app stage responsible for processing the results of UPDATE. Runs after UPDATE. PostUpdate, /// Name of app stage that runs after all other app stages - LAST, + Last, } /// The names of the default App startup stages #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] From b8af0924138041515ea4355cd00c770378219ef2 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 13:51:28 +0300 Subject: [PATCH 10/24] hotfix --- crates/bevy_app/src/app_builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 6c9b42734bcf4..1235738636f2e 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -24,7 +24,7 @@ impl Default for AppBuilder { app_builder .add_default_stages() .add_event::() - .add_system_to_stage(CoreStage::LAST, clear_trackers_system.exclusive_system()); + .add_system_to_stage(CoreStage::Last, clear_trackers_system.exclusive_system()); app_builder } } @@ -207,7 +207,7 @@ impl AppBuilder { .add_stage(CoreStage::PreUpdate, SystemStage::parallel()) .add_stage(CoreStage::Update, SystemStage::parallel()) .add_stage(CoreStage::PostUpdate, SystemStage::parallel()) - .add_stage(CoreStage::LAST, SystemStage::parallel()) + .add_stage(CoreStage::Last, SystemStage::parallel()) } pub fn add_event(&mut self) -> &mut Self From c28f3fd72d8cfd712fff7169d57803fb73d11db2 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 13:54:56 +0300 Subject: [PATCH 11/24] Implement minor suggestion --- crates/bevy_app/src/lib.rs | 2 +- crates/bevy_core/src/lib.rs | 2 +- crates/bevy_gilrs/src/lib.rs | 2 +- crates/bevy_transform/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 8cacfa94ead33..1be6615ec7efc 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -51,6 +51,6 @@ pub mod prelude { app::App, app_builder::AppBuilder, event::{EventReader, Events}, - CoreStage, DynamicPlugin, Plugin, PluginGroup, + CoreStage, StartupStage, DynamicPlugin, Plugin, PluginGroup, }; } diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index e03b5720f9906..2299136ba9bd2 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -20,7 +20,7 @@ pub mod prelude { pub use crate::{DefaultTaskPoolOptions, EntityLabels, Labels, Name, Time, Timer}; } -use bevy_app::{prelude::*, StartupStage}; +use bevy_app::prelude::*; /// Adds core functionality to Apps. #[derive(Default)] diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index c3a63300e9e4f..5cf74c9d28516 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -1,7 +1,7 @@ mod converter; mod gilrs_system; -use bevy_app::{prelude::*, StartupStage}; +use bevy_app::prelude::*; use bevy_ecs::IntoExclusiveSystem; use bevy_utils::tracing::error; use gilrs::GilrsBuilder; diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 1022d50be67dc..fb5b4221cb5ea 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -6,7 +6,7 @@ pub mod prelude { pub use crate::{components::*, hierarchy::*, TransformPlugin}; } -use bevy_app::{prelude::*, StartupStage}; +use bevy_app::prelude::*; use bevy_ecs::IntoSystem; use bevy_reflect::RegisterTypeBuilder; use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousParent, Transform}; From 099f8a6e1f194d3dff3e8d2d721a01f18c3c14f2 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 14:04:17 +0300 Subject: [PATCH 12/24] Revert changes in tests --- crates/bevy_app/src/lib.rs | 2 +- crates/bevy_core/src/label.rs | 9 +++------ .../src/schedule/system_descriptor.rs | 3 +-- crates/bevy_ecs/src/system/into_system.rs | 20 +++++++------------ .../hierarchy/hierarchy_maintenance_system.rs | 7 ++----- .../src/transform_propagate_system.rs | 9 +++------ crates/bevy_ui/src/update.rs | 8 ++------ 7 files changed, 19 insertions(+), 39 deletions(-) diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 1be6615ec7efc..24c52a78b471c 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -51,6 +51,6 @@ pub mod prelude { app::App, app_builder::AppBuilder, event::{EventReader, Events}, - CoreStage, StartupStage, DynamicPlugin, Plugin, PluginGroup, + CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage, }; } diff --git a/crates/bevy_core/src/label.rs b/crates/bevy_core/src/label.rs index 3ae49ad2f54e3..1a70d3220bd3d 100644 --- a/crates/bevy_core/src/label.rs +++ b/crates/bevy_core/src/label.rs @@ -115,18 +115,15 @@ pub(crate) fn entity_labels_system( #[cfg(test)] mod tests { use super::*; - use bevy_ecs::{Stage, StageLabel}; - - #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] - struct Test; + use bevy_ecs::Stage; fn setup() -> (World, Resources, bevy_ecs::Schedule) { let world = World::new(); let mut resources = Resources::default(); resources.insert(EntityLabels::default()); let mut schedule = bevy_ecs::Schedule::default(); - schedule.add_stage(Test, SystemStage::single_threaded()); - schedule.add_system_to_stage(Test, entity_labels_system.system()); + schedule.add_stage("test", SystemStage::single_threaded()); + schedule.add_system_to_stage("test", entity_labels_system.system()); (world, resources, schedule) } diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index bb4c245fa59c1..cb852df964c2e 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -22,8 +22,7 @@ use crate::{ /// # fn do_something() {} /// # fn do_the_other_thing() {} /// # fn do_something_else() {} -/// #[derive(Label, PartialEq, Eq, Hash)] -/// #[label_type(SystemLabel)] +/// #[derive(SystemLabel, PartialEq, Eq, Hash)] /// struct Something; /// /// SystemStage::parallel() diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index b944099a849a6..a97903e8f06ab 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -340,8 +340,8 @@ mod tests { clear_trackers_system, resource::{Res, ResMut, Resources}, schedule::Schedule, - ChangedRes, Entity, IntoExclusiveSystem, Local, Or, Query, QuerySet, Stage, StageLabel, - System, SystemStage, With, World, + ChangedRes, Entity, IntoExclusiveSystem, Local, Or, Query, QuerySet, Stage, System, + SystemStage, With, World, }; #[derive(Debug, Eq, PartialEq, Default)] @@ -442,12 +442,6 @@ mod tests { assert!(*resources.get::().unwrap(), "system ran"); } - #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] - enum TestLabels { - CleanTrackers, - Update, - } - #[test] fn changed_resource_system() { fn incr_e_on_flip(_run_on_flip: ChangedRes, mut query: Query<&mut i32>) { @@ -464,9 +458,9 @@ mod tests { let mut schedule = Schedule::default(); let mut update = SystemStage::parallel(); update.add_system(incr_e_on_flip.system()); - schedule.add_stage(TestLabels::Update, update); + schedule.add_stage("update", update); schedule.add_stage( - TestLabels::CleanTrackers, + "clear_trackers", SystemStage::single(clear_trackers_system.exclusive_system()), ); @@ -501,9 +495,9 @@ mod tests { let mut schedule = Schedule::default(); let mut update = SystemStage::parallel(); update.add_system(incr_e_on_flip.system()); - schedule.add_stage(TestLabels::Update, update); + schedule.add_stage("update", update); schedule.add_stage( - TestLabels::CleanTrackers, + "clear_trackers", SystemStage::single(clear_trackers_system.exclusive_system()), ); @@ -591,7 +585,7 @@ mod tests { let mut schedule = Schedule::default(); let mut update = SystemStage::parallel(); update.add_system(system); - schedule.add_stage(TestLabels::Update, update); + schedule.add_stage("update", update); schedule.run(world, resources); } diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs index 47f2066ed6b9c..468e624046bad 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs @@ -71,10 +71,7 @@ pub fn parent_update_system( mod test { use super::*; use crate::{hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system}; - use bevy_ecs::{IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World}; - - #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] - struct Update; + use bevy_ecs::{IntoSystem, Resources, Schedule, Stage, SystemStage, World}; #[test] fn correct_children() { @@ -86,7 +83,7 @@ mod test { update_stage.add_system(transform_propagate_system.system()); let mut schedule = Schedule::default(); - schedule.add_stage(Update, update_stage); + schedule.add_stage("update", update_stage); // Add parent entities let mut commands = Commands::default(); diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index d26b6482af5f3..219f2e6c59ee9 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -71,10 +71,7 @@ fn propagate_recursive( mod test { use super::*; use crate::hierarchy::{parent_update_system, BuildChildren, BuildWorldChildren}; - use bevy_ecs::{Resources, Schedule, Stage, StageLabel, SystemStage, World}; - - #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] - struct Update; + use bevy_ecs::{Resources, Schedule, Stage, SystemStage, World}; #[test] fn did_propagate() { @@ -86,7 +83,7 @@ mod test { update_stage.add_system(transform_propagate_system.system()); let mut schedule = Schedule::default(); - schedule.add_stage(Update, update_stage); + schedule.add_stage("update", update_stage); // Root entity world.spawn(( @@ -137,7 +134,7 @@ mod test { update_stage.add_system(transform_propagate_system.system()); let mut schedule = Schedule::default(); - schedule.add_stage(Update, update_stage); + schedule.add_stage("update", update_stage); // Root entity let mut commands = Commands::default(); diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 183f1f94c1042..1d3df0972b743 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -48,14 +48,10 @@ fn update_hierarchy( } #[cfg(test)] mod tests { - use bevy_ecs::{ - Commands, IntoSystem, Resources, Schedule, Stage, StageLabel, SystemStage, World, - }; + use bevy_ecs::{Commands, IntoSystem, Resources, Schedule, Stage, SystemStage, World}; use bevy_transform::{components::Transform, hierarchy::BuildChildren}; use crate::Node; - #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] - struct Update; use super::{ui_z_system, UI_Z_STEP}; @@ -121,7 +117,7 @@ mod tests { let mut schedule = Schedule::default(); let mut update_stage = SystemStage::parallel(); update_stage.add_system(ui_z_system.system()); - schedule.add_stage(Update, update_stage); + schedule.add_stage("update", update_stage); schedule.run(&mut world, &mut resources); let mut actual_result = world From e70a8c1050c46cd13ef2b567102d74a4ad89cefc Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 14:24:09 +0300 Subject: [PATCH 13/24] Fix doctest --- crates/bevy_ecs/macros/src/lib.rs | 2 -- crates/bevy_ecs/src/schedule/system_descriptor.rs | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index ff32ed1a85160..ebc82e158c5ab 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -489,8 +489,6 @@ fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { format!("{}::ecs", package.name) } else if let Some(package) = manifest.find(|name| name == "bevy_ecs") { package.name - } else if manifest.crate_package().unwrap().name == "bevy_ecs" { - "crate".to_string() } else { "bevy_ecs".to_string() }; diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index cb852df964c2e..1ff3782db86c0 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -16,13 +16,12 @@ use crate::{ /// that they have to run before or after the system with that label. /// /// # Example -/// ```ignore -/// # // This is no_run because the macro doesn't like the doctest environment +/// ``` /// # use bevy_ecs::prelude::*; /// # fn do_something() {} /// # fn do_the_other_thing() {} /// # fn do_something_else() {} -/// #[derive(SystemLabel, PartialEq, Eq, Hash)] +/// #[derive(SystemLabel, Clone, PartialEq, Eq, Hash)] /// struct Something; /// /// SystemStage::parallel() From c002ba2c2f3e44e922c9650dcdb072768963be5e Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 15:05:22 +0300 Subject: [PATCH 14/24] Fix inconsistencies --- crates/bevy_ecs/src/schedule/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 4341c28c4227b..83853c8a6835e 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -173,7 +173,7 @@ impl Schedule { self } - pub fn get_stage(&self, name: impl Into) -> Option<&T> { + pub fn get_stage>(&self, name: L) -> Option<&T> { self.stages .get(&name.into()) .and_then(|stage| stage.downcast_ref::()) From c5724f67e03f4bc1194faf7a206997591b966f5a Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 15:11:01 +0300 Subject: [PATCH 15/24] Revert accidental changes --- crates/bevy_ecs/src/schedule/stage.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 59a4ec0f01b90..be70be9af261b 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -503,17 +503,17 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> { .collect::>(); let mut ambiguities = Vec::new(); let full_bitset: FixedBitSet = (0..systems.len()).collect(); + let mut processed = FixedBitSet::with_capacity(systems.len()); for (index_a, relations) in all_relations.drain(..).enumerate() { // TODO: prove that `.take(index_a)` would be correct here, and uncomment it if so. for index_b in full_bitset.difference(&relations) /*.take(index_a)*/ { - if !systems[index_a].is_compatible(&systems[index_b]) - && !ambiguities.contains(&(index_b, index_a)) - { + if !processed.contains(index_b) && !systems[index_a].is_compatible(&systems[index_b]) { ambiguities.push((index_a, index_b)); } } + processed.insert(index_a); } ambiguities } From 9c70a5df7df2a88977fe69166af332e46efacc5e Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 16:06:22 +0300 Subject: [PATCH 16/24] Switch to requirig Debug impl --- crates/bevy_ecs/macros/src/lib.rs | 23 ++---------- crates/bevy_ecs/src/schedule/label.rs | 36 +++---------------- crates/bevy_ecs/src/schedule/mod.rs | 22 +++++------- crates/bevy_ecs/src/schedule/stage.rs | 7 ++-- .../bevy_ecs/src/schedule/system_container.rs | 4 +-- 5 files changed, 21 insertions(+), 71 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 197cee534f55d..a536d85fbbcae 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -467,13 +467,13 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { }) } -#[proc_macro_derive(SystemLabel, attributes(name_expr))] +#[proc_macro_derive(SystemLabel)] pub fn derive_system_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); derive_label(input, Ident::new("SystemLabelMarker", Span::call_site())).into() } -#[proc_macro_derive(StageLabel, attributes(name_expr))] +#[proc_macro_derive(StageLabel)] pub fn derive_stage_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); derive_label(input, Ident::new("StageLabelMarker", Span::call_site())).into() @@ -494,24 +494,7 @@ fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { }; let crate_path: Path = syn::parse(path_str.parse::().unwrap()).unwrap(); - let name = input - .attrs - .iter() - .find(|a| *a.path.get_ident().as_ref().unwrap() == "name_expr") - .map(|a| a.parse_args::().expect("Expected expression")) - .unwrap_or_else(|| { - let name = ident.to_string(); - syn::Expr::Lit(syn::ExprLit { - lit: syn::Lit::Str(syn::LitStr::new(&name, Span::call_site())), - attrs: Default::default(), - }) - }); - quote! { - impl #crate_path::Label<#crate_path::#label_type> for #ident { - fn name(&self) -> std::borrow::Cow<'static, str> { - std::borrow::Cow::Borrowed(#name) - } - } + impl #crate_path::Label<#crate_path::#label_type> for #ident {} } } diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 9e8bd0701c042..f892f610ef43e 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -7,15 +7,7 @@ use std::{ use crate::{StageLabelMarker, SystemLabelMarker}; -pub trait Label: DynHash + DynClone + Send + Sync + 'static { - fn name(&self) -> Cow<'static, str>; -} - -impl Debug for dyn Label { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.name()) - } -} +pub trait Label: DynHash + DynClone + Debug + Send + Sync + 'static {} pub type SystemLabel = Box>; pub type StageLabel = Box>; @@ -107,25 +99,7 @@ impl> From for Box> } } -impl Label for Cow<'static, str> { - fn name(&self) -> Cow<'static, str> { - self.clone() - } -} - -impl Label for &'static str { - fn name(&self) -> Cow<'static, str> { - Cow::Borrowed(self) - } -} -impl Label for Cow<'static, str> { - fn name(&self) -> Cow<'static, str> { - self.clone() - } -} - -impl Label for &'static str { - fn name(&self) -> Cow<'static, str> { - Cow::Borrowed(self) - } -} +impl Label for Cow<'static, str> {} +impl Label for &'static str {} +impl Label for Cow<'static, str> {} +impl Label for &'static str {} diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 83853c8a6835e..b18e71a41c8ed 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -84,7 +84,7 @@ impl Schedule { self.stage_order.push(name.clone()); let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {}.", name.name()); + panic!("Stage already exists: {:?}.", name); } self } @@ -103,12 +103,12 @@ impl Schedule { .enumerate() .find(|(_i, stage_name)| **stage_name == target.clone()) .map(|(i, _)| i) - .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); + .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); self.stage_order.insert(target_index + 1, name.clone()); let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {}.", name.name()); + panic!("Stage already exists: {:?}.", name); } self } @@ -127,12 +127,12 @@ impl Schedule { .enumerate() .find(|(_i, stage_name)| **stage_name == target.clone()) .map(|(i, _)| i) - .unwrap_or_else(|| panic!("Target stage does not exist: {}.", target.name())); + .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); self.stage_order.insert(target_index, name.clone()); let prev = self.stages.insert(name.clone(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {}.", name.name()); + panic!("Stage already exists: {:?}.", name); } self } @@ -146,10 +146,7 @@ impl Schedule { let stage = self .get_stage_mut::(name.clone()) .unwrap_or_else(move || { - panic!( - "Stage '{}' does not exist or is not a SystemStage", - name.name() - ) + panic!("Stage '{:?}' does not exist or is not a SystemStage", name) }); stage.add_system(system); self @@ -164,10 +161,7 @@ impl Schedule { let stage = self .get_stage_mut::(name.clone()) .unwrap_or_else(move || { - panic!( - "stage '{}' does not exist or is the wrong type", - name.name() - ) + panic!("stage '{:?}' does not exist or is the wrong type", name) }); func(stage); self @@ -188,7 +182,7 @@ impl Schedule { pub fn run_once(&mut self, world: &mut World, resources: &mut Resources) { for name in self.stage_order.iter() { #[cfg(feature = "trace")] - let stage_span = bevy_utils::tracing::info_span!("stage", name = &*name.name()); + let stage_span = bevy_utils::tracing::info_span!("stage", name = &format!("{:?}", name) as &str); #[cfg(feature = "trace")] let _stage_guard = stage_span.enter(); let stage = self.stages.get_mut(name).unwrap(); diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index be70be9af261b..e46744f8524f3 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -1103,17 +1103,16 @@ mod tests { #[test] fn ambiguity_detection() { use super::{find_ambiguities, SystemContainer}; - use std::borrow::Cow; fn find_ambiguities_labels( systems: &[impl SystemContainer], - ) -> Vec<(Cow<'static, str>, Cow<'static, str>)> { + ) -> Vec<(SystemLabel, SystemLabel)> { find_ambiguities(systems) .drain(..) .map(|(index_a, index_b)| { ( - systems[index_a].display_name(), - systems[index_b].display_name(), + systems[index_a].label().clone().unwrap(), + systems[index_b].label().clone().unwrap(), ) }) .collect() diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index 351ac84194584..c760df8eaf70a 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -45,7 +45,7 @@ impl SystemContainer for ExclusiveSystemContainer { fn display_name(&self) -> Cow<'static, str> { self.label .as_ref() - .map(|l| l.name()) + .map(|l| Cow::Owned(format!("{:?}", l))) .unwrap_or_else(|| self.system.name()) } @@ -93,7 +93,7 @@ impl SystemContainer for ParallelSystemContainer { fn display_name(&self) -> Cow<'static, str> { self.label .as_ref() - .map(|l| l.name()) + .map(|l| Cow::Owned(format!("{:?}", l))) .unwrap_or_else(|| self.system().name()) } From 6d82c4e21e6b70e0be06b029daae1e5dfa7a1a38 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 16:22:52 +0300 Subject: [PATCH 17/24] cargo fmt --- crates/bevy_ecs/src/schedule/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index b18e71a41c8ed..24805ba293ccc 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -182,7 +182,8 @@ impl Schedule { pub fn run_once(&mut self, world: &mut World, resources: &mut Resources) { for name in self.stage_order.iter() { #[cfg(feature = "trace")] - let stage_span = bevy_utils::tracing::info_span!("stage", name = &format!("{:?}", name) as &str); + let stage_span = + bevy_utils::tracing::info_span!("stage", name = &format!("{:?}", name) as &str); #[cfg(feature = "trace")] let _stage_guard = stage_span.enter(); let stage = self.stages.get_mut(name).unwrap(); From b7f1e8519c7d94f4062d35e0de5ec5f7951a63a3 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Tue, 16 Feb 2021 16:51:01 +0300 Subject: [PATCH 18/24] Fix test --- crates/bevy_ecs/src/schedule/system_descriptor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index 1ff3782db86c0..d9e6750d1eb64 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -21,7 +21,7 @@ use crate::{ /// # fn do_something() {} /// # fn do_the_other_thing() {} /// # fn do_something_else() {} -/// #[derive(SystemLabel, Clone, PartialEq, Eq, Hash)] +/// #[derive(SystemLabel, Debug, Clone, PartialEq, Eq, Hash)] /// struct Something; /// /// SystemStage::parallel() From 62f1eef44e7e45df824b49532fbdb9e08ccf0db5 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Wed, 17 Feb 2021 12:28:10 +0300 Subject: [PATCH 19/24] Fancify labels --- crates/bevy_transform/src/lib.rs | 20 +++++++++++++------- examples/ecs/ecs_guide.rs | 9 +++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index b393e349ee797..07db233fce30c 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -7,13 +7,19 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::{IntoSystem, ParallelSystemDescriptorCoercion}; +use bevy_ecs::{IntoSystem, ParallelSystemDescriptorCoercion, SystemLabel}; use bevy_reflect::RegisterTypeBuilder; use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousParent, Transform}; #[derive(Default)] pub struct TransformPlugin; +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] +pub enum Systems { + TransformPropagate, + ParentUpdate, +} + impl Plugin for TransformPlugin { fn build(&self, app: &mut AppBuilder) { app.register_type::() @@ -24,25 +30,25 @@ impl Plugin for TransformPlugin { // add transform systems to startup so the first update is "correct" .add_startup_system_to_stage( StartupStage::PostStartup, - parent_update_system.system().label("parent_update_system"), + parent_update_system.system().label(Systems::ParentUpdate), ) .add_startup_system_to_stage( StartupStage::PostStartup, transform_propagate_system::transform_propagate_system .system() - .label("transform_propagate_system") - .after("parent_update_system"), + .label(Systems::TransformPropagate) + .after(Systems::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, - parent_update_system.system().label("parent_update_system"), + parent_update_system.system().label(Systems::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, transform_propagate_system::transform_propagate_system .system() - .label("transform_propagate_system") - .after("parent_update_system"), + .label(Systems::TransformPropagate) + .after(Systems::ParentUpdate), ); } } diff --git a/examples/ecs/ecs_guide.rs b/examples/ecs/ecs_guide.rs index 2ffccf2bb3638..bd8bc8eb4c966 100644 --- a/examples/ecs/ecs_guide.rs +++ b/examples/ecs/ecs_guide.rs @@ -245,6 +245,11 @@ enum MyStages { AfterRound, } +#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] +enum MyLabels { + ScoreCheck, +} + // Our Bevy app's entry point fn main() { // Bevy apps are created using the builder pattern. We use the builder to add systems, resources, and plugins to our app @@ -314,11 +319,11 @@ fn main() { // Then, we use either `.before` or `.after` to describe the order we want the relationship .add_system_to_stage( MyStages::AfterRound, - score_check_system.system().label("score_check"), + score_check_system.system().label(MyLabels::ScoreCheck), ) .add_system_to_stage( MyStages::AfterRound, - game_over_system.system().after("score_check"), + game_over_system.system().after(MyLabels::ScoreCheck), ) // We can check our systems for execution order ambiguities by examining the output produced in the console // by adding the following Resource to our App :) From da24443bbfdfe6bdfea31a457e01cc95b1c8f1ed Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 17 Feb 2021 12:12:31 -0800 Subject: [PATCH 20/24] mod/use consistency --- crates/bevy_app/src/lib.rs | 48 ++++++++++++++++----------------- crates/bevy_asset/src/assets.rs | 7 ++--- crates/bevy_asset/src/lib.rs | 18 ++++++------- crates/bevy_audio/src/lib.rs | 8 +++--- crates/bevy_core/src/lib.rs | 3 +-- crates/bevy_input/src/lib.rs | 19 ++++--------- crates/bevy_render/src/lib.rs | 22 +++++++-------- crates/bevy_scene/src/lib.rs | 5 ++-- crates/bevy_sprite/src/lib.rs | 16 +++++------ crates/bevy_text/src/lib.rs | 8 +++--- crates/bevy_ui/src/lib.rs | 17 +++++------- crates/bevy_wgpu/src/lib.rs | 20 +++++++------- 12 files changed, 85 insertions(+), 106 deletions(-) diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 24c52a78b471c..e278ae119d9f2 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -1,3 +1,27 @@ +mod app; +mod app_builder; +mod event; +mod plugin; +mod plugin_group; +mod schedule_runner; + +pub use app::*; +pub use app_builder::*; +pub use bevy_derive::DynamicPlugin; +pub use event::*; +pub use plugin::*; +pub use plugin_group::*; +pub use schedule_runner::*; + +pub mod prelude { + pub use crate::{ + app::App, + app_builder::AppBuilder, + event::{EventReader, Events}, + CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage, + }; +} + use bevy_ecs::StageLabel; /// The names of the default App stages @@ -30,27 +54,3 @@ pub enum StartupStage { /// Name of app stage that runs once after the startup stage PostStartup, } - -mod app; -mod app_builder; -mod event; -mod plugin; -mod plugin_group; -mod schedule_runner; - -pub use app::*; -pub use app_builder::*; -pub use bevy_derive::DynamicPlugin; -pub use event::*; -pub use plugin::*; -pub use plugin_group::*; -pub use schedule_runner::*; - -pub mod prelude { - pub use crate::{ - app::App, - app_builder::AppBuilder, - event::{EventReader, Events}, - CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage, - }; -} diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index cdd3d93f5fc00..ba28afb781d34 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -1,5 +1,6 @@ use crate::{ - update_asset_storage_system, Asset, AssetLoader, AssetServer, Handle, HandleId, RefChange, + update_asset_storage_system, Asset, AssetLoader, AssetServer, AssetStage, Handle, HandleId, + RefChange, }; use bevy_app::{prelude::Events, AppBuilder}; use bevy_ecs::{FromResources, IntoSystem, ResMut}; @@ -219,11 +220,11 @@ impl AddAsset for AppBuilder { self.insert_resource(assets) .add_system_to_stage( - super::AssetStage::AssetEvents, + AssetStage::AssetEvents, Assets::::asset_event_system.system(), ) .add_system_to_stage( - crate::AssetStage::LoadAssets, + AssetStage::LoadAssets, update_asset_storage_system::.system(), ) .register_type::>() diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 4786931668208..3208a5efbee40 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -14,27 +14,27 @@ mod path; pub use asset_server::*; pub use assets::*; -use bevy_ecs::{IntoSystem, SystemStage}; -use bevy_reflect::RegisterTypeBuilder; -use bevy_tasks::IoTaskPool; pub use handle::*; pub use info::*; pub use io::*; pub use loader::*; pub use path::*; +pub mod prelude { + pub use crate::{AddAsset, AssetEvent, AssetServer, Assets, Handle, HandleUntyped}; +} + +use bevy_app::{prelude::Plugin, AppBuilder}; +use bevy_ecs::{IntoSystem, StageLabel, SystemStage}; +use bevy_reflect::RegisterTypeBuilder; +use bevy_tasks::IoTaskPool; + /// The names of asset stages in an App Schedule -use bevy_ecs::StageLabel; #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum AssetStage { LoadAssets, AssetEvents, } -pub mod prelude { - pub use crate::{AddAsset, AssetEvent, AssetServer, Assets, Handle, HandleUntyped}; -} - -use bevy_app::{prelude::Plugin, AppBuilder}; /// Adds support for Assets to an App. Assets are typed collections with change tracking, which are added as App Resources. /// Examples of assets: textures, sounds, 3d models, maps, scenes diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index 951a40afa5b00..c72a43ce02bea 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -2,14 +2,14 @@ mod audio; mod audio_output; mod audio_source; -pub use audio::*; -pub use audio_output::*; -pub use audio_source::*; - pub mod prelude { pub use crate::{Audio, AudioOutput, AudioSource, Decodable}; } +pub use audio::*; +pub use audio_output::*; +pub use audio_source::*; + use bevy_app::prelude::*; use bevy_asset::AddAsset; use bevy_ecs::IntoExclusiveSystem; diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 2299136ba9bd2..12c7b1377cc6d 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -5,8 +5,6 @@ mod name; mod task_pool_options; mod time; -use std::ops::Range; - use bevy_ecs::IntoSystem; use bevy_reflect::RegisterTypeBuilder; pub use bytes::*; @@ -21,6 +19,7 @@ pub mod prelude { } use bevy_app::prelude::*; +use std::ops::Range; /// Adds core functionality to Apps. #[derive(Default)] diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index 9ed240d8bff22..bdf91df42d741 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -44,29 +44,20 @@ impl Plugin for InputPlugin { .add_event::() .add_event::() .init_resource::>() - .add_system_to_stage(bevy_app::CoreStage::Event, keyboard_input_system.system()) + .add_system_to_stage(CoreStage::Event, keyboard_input_system.system()) .init_resource::>() - .add_system_to_stage( - bevy_app::CoreStage::Event, - mouse_button_input_system.system(), - ) + .add_system_to_stage(CoreStage::Event, mouse_button_input_system.system()) .add_event::() .add_event::() .init_resource::() .init_resource::>() .init_resource::>() .init_resource::>() - .add_system_to_stage(bevy_app::CoreStage::Event, gamepad_event_system.system()) - .add_startup_system_to_stage( - bevy_app::StartupStage::Startup, - gamepad_event_system.system(), - ) + .add_system_to_stage(CoreStage::Event, gamepad_event_system.system()) + .add_startup_system_to_stage(StartupStage::Startup, gamepad_event_system.system()) .add_event::() .init_resource::() - .add_system_to_stage( - bevy_app::CoreStage::Event, - touch_screen_input_system.system(), - ); + .add_system_to_stage(CoreStage::Event, touch_screen_input_system.system()); } } diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 05df8133e99f8..8097cfefd6860 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -33,7 +33,8 @@ pub mod prelude { use crate::prelude::*; use base::Msaa; use bevy_app::prelude::*; -use bevy_asset::AddAsset; +use bevy_asset::{AddAsset, AssetStage}; +use bevy_ecs::StageLabel; use camera::{ ActiveCameras, Camera, OrthographicProjection, PerspectiveProjection, VisibleEntities, }; @@ -52,7 +53,6 @@ use texture::HdrTextureLoader; #[cfg(feature = "png")] use texture::ImageTextureLoader; -use bevy_ecs::StageLabel; /// The names of "render" App stages #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum RenderStage { @@ -98,7 +98,7 @@ impl Plugin for RenderPlugin { } app.add_stage_after( - bevy_asset::AssetStage::AssetEvents, + AssetStage::AssetEvents, RenderStage::RenderResource, SystemStage::parallel(), ) @@ -141,28 +141,26 @@ impl Plugin for RenderPlugin { .register_type::() .init_resource::() .init_resource::() + .init_resource::() .init_resource::() .init_resource::() .init_resource::() + .add_system_to_stage(CoreStage::PreUpdate, draw::clear_draw_system.system()) .add_system_to_stage( - bevy_app::CoreStage::PreUpdate, - draw::clear_draw_system.system(), - ) - .add_system_to_stage( - bevy_app::CoreStage::PostUpdate, + CoreStage::PostUpdate, camera::active_cameras_system.system(), ) .add_system_to_stage( - bevy_app::CoreStage::PostUpdate, + CoreStage::PostUpdate, camera::camera_system::.system(), ) .add_system_to_stage( - bevy_app::CoreStage::PostUpdate, + CoreStage::PostUpdate, camera::camera_system::.system(), ) // registration order matters here. this must come after all camera_system:: systems .add_system_to_stage( - bevy_app::CoreStage::PostUpdate, + CoreStage::PostUpdate, camera::visible_entities_system.system(), ) .add_system_to_stage( @@ -190,8 +188,6 @@ impl Plugin for RenderPlugin { shader::clear_shader_defs_system.system(), ); - app.init_resource::(); - if let Some(ref config) = self.base_render_graph_config { let resources = app.resources(); let mut render_graph = resources.get_mut::().unwrap(); diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index 3a571b51410c8..794c8e1550a8f 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -5,7 +5,6 @@ mod scene_loader; mod scene_spawner; pub mod serde; -use bevy_ecs::{IntoExclusiveSystem, SystemStage}; pub use command::*; pub use dynamic_scene::*; pub use scene::*; @@ -20,11 +19,11 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_asset::AddAsset; +use bevy_ecs::{IntoExclusiveSystem, StageLabel, SystemStage}; #[derive(Default)] pub struct ScenePlugin; -use bevy_ecs::StageLabel; #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] enum Stages { SceneStage, @@ -37,7 +36,7 @@ impl Plugin for ScenePlugin { .init_asset_loader::() .init_resource::() .add_stage_after( - bevy_app::CoreStage::Event, + CoreStage::Event, Stages::SceneStage, SystemStage::parallel(), ) diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index cc1f3819e65aa..e0ea01cb2a1f3 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -9,7 +9,13 @@ mod sprite; mod texture_atlas; mod texture_atlas_builder; -use bevy_ecs::IntoSystem; +pub mod prelude { + pub use crate::{ + entity::{SpriteBundle, SpriteSheetBundle}, + ColorMaterial, Sprite, SpriteResizeMode, TextureAtlas, TextureAtlasSprite, + }; +} + pub use color_material::*; pub use dynamic_texture_atlas_builder::*; pub use rect::*; @@ -18,15 +24,9 @@ pub use sprite::*; pub use texture_atlas::*; pub use texture_atlas_builder::*; -pub mod prelude { - pub use crate::{ - entity::{SpriteBundle, SpriteSheetBundle}, - ColorMaterial, Sprite, SpriteResizeMode, TextureAtlas, TextureAtlasSprite, - }; -} - use bevy_app::prelude::*; use bevy_asset::{AddAsset, Assets, Handle, HandleUntyped}; +use bevy_ecs::IntoSystem; use bevy_math::Vec2; use bevy_reflect::{RegisterTypeBuilder, TypeUuid}; use bevy_render::{ diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index a1d44e6906ae0..166c80e1c7849 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -28,6 +28,7 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_asset::AddAsset; use bevy_ecs::{Entity, IntoSystem}; +use bevy_render::RenderStage; pub type DefaultTextPipeline = TextPipeline; @@ -40,10 +41,7 @@ impl Plugin for TextPlugin { .add_asset::() .init_asset_loader::() .insert_resource(DefaultTextPipeline::default()) - .add_system_to_stage(bevy_app::CoreStage::PostUpdate, text2d_system.system()) - .add_system_to_stage( - bevy_render::RenderStage::Draw, - text2d::draw_text2d_system.system(), - ); + .add_system_to_stage(CoreStage::PostUpdate, text2d_system.system()) + .add_system_to_stage(RenderStage::Draw, text2d::draw_text2d_system.system()); } } diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 74f2c4665ca4e..1f7c51d985aac 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -23,15 +23,17 @@ use bevy_app::prelude::*; use bevy_ecs::{ IntoSystem, ParallelSystemDescriptorCoercion, StageLabel, SystemLabel, SystemStage, }; -use bevy_render::render_graph::RenderGraph; +use bevy_render::{render_graph::RenderGraph, RenderStage}; use update::ui_z_system; #[derive(Default)] pub struct UiPlugin; + #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] pub enum UiStages { Ui, } + #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] pub enum UiSystems { Flex, @@ -44,12 +46,8 @@ pub mod system { impl Plugin for UiPlugin { fn build(&self, app: &mut AppBuilder) { app.init_resource::() - .add_stage_before( - bevy_app::CoreStage::PostUpdate, - UiStages::Ui, - SystemStage::parallel(), - ) - .add_system_to_stage(bevy_app::CoreStage::PreUpdate, ui_focus_system.system()) + .add_stage_before(CoreStage::PostUpdate, UiStages::Ui, SystemStage::parallel()) + .add_system_to_stage(CoreStage::PreUpdate, ui_focus_system.system()) // add these stages to front because these must run before transform update systems .add_system_to_stage( UiStages::Ui, @@ -64,10 +62,7 @@ impl Plugin for UiPlugin { flex_node_system.system().label(UiSystems::Flex), ) .add_system_to_stage(UiStages::Ui, ui_z_system.system()) - .add_system_to_stage( - bevy_render::RenderStage::Draw, - widget::draw_text_system.system(), - ); + .add_system_to_stage(RenderStage::Draw, widget::draw_text_system.system()); let resources = app.resources(); let mut render_graph = resources.get_mut::().unwrap(); diff --git a/crates/bevy_wgpu/src/lib.rs b/crates/bevy_wgpu/src/lib.rs index 4b0d15792664d..f7883483f8ade 100644 --- a/crates/bevy_wgpu/src/lib.rs +++ b/crates/bevy_wgpu/src/lib.rs @@ -5,14 +5,17 @@ mod wgpu_renderer; mod wgpu_resources; mod wgpu_type_converter; -use futures_lite::future; pub use wgpu_render_pass::*; pub use wgpu_renderer::*; pub use wgpu_resources::*; use bevy_app::prelude::*; use bevy_ecs::{IntoExclusiveSystem, IntoSystem, Resources, World}; -use bevy_render::renderer::{shared_buffers_update_system, RenderResourceContext, SharedBuffers}; +use bevy_render::{ + renderer::{shared_buffers_update_system, RenderResourceContext, SharedBuffers}, + RenderStage, +}; +use futures_lite::future; use renderer::WgpuRenderResourceContext; #[derive(Default)] @@ -21,14 +24,11 @@ pub struct WgpuPlugin; impl Plugin for WgpuPlugin { fn build(&self, app: &mut AppBuilder) { let render_system = get_wgpu_render_system(app.resources_mut()); - app.add_system_to_stage( - bevy_render::RenderStage::Render, - render_system.exclusive_system(), - ) - .add_system_to_stage( - bevy_render::RenderStage::PostRender, - shared_buffers_update_system.system(), - ); + app.add_system_to_stage(RenderStage::Render, render_system.exclusive_system()) + .add_system_to_stage( + RenderStage::PostRender, + shared_buffers_update_system.system(), + ); } } From 7c20ed22f03e089a82bb0e267f05980c902f8593 Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Thu, 18 Feb 2021 17:26:20 +0300 Subject: [PATCH 21/24] Implement requested changes --- crates/bevy_app/src/app_builder.rs | 36 ++++++------- crates/bevy_ecs/src/schedule/mod.rs | 80 ++++++++++++++--------------- crates/bevy_scene/src/lib.rs | 6 +-- crates/bevy_transform/src/lib.rs | 14 ++--- crates/bevy_ui/src/lib.rs | 20 ++++---- examples/ecs/ecs_guide.rs | 14 ++--- examples/game/alien_cake_addict.rs | 24 ++++----- 7 files changed, 97 insertions(+), 97 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 1235738636f2e..0c195d0c01a5e 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -54,40 +54,40 @@ impl AppBuilder { self } - pub fn add_stage(&mut self, name: impl Into, stage: S) -> &mut Self { - self.app.schedule.add_stage(name, stage); + pub fn add_stage(&mut self, label: impl Into, stage: S) -> &mut Self { + self.app.schedule.add_stage(label, stage); self } pub fn add_stage_after( &mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { - self.app.schedule.add_stage_after(target, name, stage); + self.app.schedule.add_stage_after(target, label, stage); self } pub fn add_stage_before( &mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { - self.app.schedule.add_stage_before(target, name, stage); + self.app.schedule.add_stage_before(target, label, stage); self } pub fn add_startup_stage( &mut self, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { self.app .schedule .stage(CoreStage::Startup, |schedule: &mut Schedule| { - schedule.add_stage(name, stage) + schedule.add_stage(label, stage) }); self } @@ -95,13 +95,13 @@ impl AppBuilder { pub fn add_startup_stage_after( &mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { self.app .schedule .stage(CoreStage::Startup, |schedule: &mut Schedule| { - schedule.add_stage_after(target, name, stage) + schedule.add_stage_after(target, label, stage) }); self } @@ -109,23 +109,23 @@ impl AppBuilder { pub fn add_startup_stage_before( &mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { self.app .schedule .stage(CoreStage::Startup, |schedule: &mut Schedule| { - schedule.add_stage_before(target, name, stage) + schedule.add_stage_before(target, label, stage) }); self } pub fn stage &mut T>( &mut self, - name: impl Into, + label: impl Into, func: F, ) -> &mut Self { - self.app.schedule.stage(name, func); + self.app.schedule.stage(label, func); self } @@ -135,10 +135,10 @@ impl AppBuilder { pub fn add_system_to_stage( &mut self, - stage_name: impl Into, + stage_label: impl Into, system: impl Into, ) -> &mut Self { - self.app.schedule.add_system_to_stage(stage_name, system); + self.app.schedule.add_system_to_stage(stage_label, system); self } @@ -148,13 +148,13 @@ impl AppBuilder { pub fn add_startup_system_to_stage( &mut self, - stage_name: impl Into, + stage_label: impl Into, system: impl Into, ) -> &mut Self { self.app .schedule .stage(CoreStage::Startup, |schedule: &mut Schedule| { - schedule.add_system_to_stage(stage_name, system) + schedule.add_system_to_stage(stage_label, system) }); self } diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index 24805ba293ccc..c539c9387f7cd 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -32,28 +32,28 @@ pub struct Schedule { pub struct StageLabelMarker; impl Schedule { - pub fn with_stage(mut self, name: impl Into, stage: S) -> Self { - self.add_stage(name, stage); + pub fn with_stage(mut self, label: impl Into, stage: S) -> Self { + self.add_stage(label, stage); self } pub fn with_stage_after( mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> Self { - self.add_stage_after(target, name, stage); + self.add_stage_after(target, label, stage); self } pub fn with_stage_before( mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> Self { - self.add_stage_before(target, name, stage); + self.add_stage_before(target, label, stage); self } @@ -64,10 +64,10 @@ impl Schedule { pub fn with_system_in_stage( mut self, - stage_name: impl Into, + stage_label: impl Into, system: impl Into, ) -> Self { - self.add_system_to_stage(stage_name, system); + self.add_system_to_stage(stage_label, system); self } @@ -79,12 +79,12 @@ impl Schedule { self } - pub fn add_stage(&mut self, name: impl Into, stage: S) -> &mut Self { - let name = name.into(); - self.stage_order.push(name.clone()); - let prev = self.stages.insert(name.clone(), Box::new(stage)); + pub fn add_stage(&mut self, label: impl Into, stage: S) -> &mut Self { + let label = label.into(); + self.stage_order.push(label.clone()); + let prev = self.stages.insert(label.clone(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {:?}.", name); + panic!("Stage already exists: {:?}.", label); } self } @@ -92,23 +92,23 @@ impl Schedule { pub fn add_stage_after( &mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { - let name = name.into(); + let label = label.into(); let target = target.into(); let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_name)| **stage_name == target.clone()) + .find(|(_i, stage_label)| **stage_label == target.clone()) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); - self.stage_order.insert(target_index + 1, name.clone()); - let prev = self.stages.insert(name.clone(), Box::new(stage)); + self.stage_order.insert(target_index + 1, label.clone()); + let prev = self.stages.insert(label.clone(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {:?}.", name); + panic!("Stage already exists: {:?}.", label); } self } @@ -116,37 +116,37 @@ impl Schedule { pub fn add_stage_before( &mut self, target: impl Into, - name: impl Into, + label: impl Into, stage: S, ) -> &mut Self { - let name = name.into(); + let label = label.into(); let target = target.into(); let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_name)| **stage_name == target.clone()) + .find(|(_i, stage_label)| **stage_label == target.clone()) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); - self.stage_order.insert(target_index, name.clone()); - let prev = self.stages.insert(name.clone(), Box::new(stage)); + self.stage_order.insert(target_index, label.clone()); + let prev = self.stages.insert(label.clone(), Box::new(stage)); if prev.is_some() { - panic!("Stage already exists: {:?}.", name); + panic!("Stage already exists: {:?}.", label); } self } pub fn add_system_to_stage( &mut self, - stage_name: impl Into, + stage_label: impl Into, system: impl Into, ) -> &mut Self { - let name = stage_name.into(); + let label = stage_label.into(); let stage = self - .get_stage_mut::(name.clone()) + .get_stage_mut::(label.clone()) .unwrap_or_else(move || { - panic!("Stage '{:?}' does not exist or is not a SystemStage", name) + panic!("Stage '{:?}' does not exist or is not a SystemStage", label) }); stage.add_system(system); self @@ -154,39 +154,39 @@ impl Schedule { pub fn stage &mut T>( &mut self, - name: impl Into, + label: impl Into, func: F, ) -> &mut Self { - let name = name.into(); + let label = label.into(); let stage = self - .get_stage_mut::(name.clone()) + .get_stage_mut::(label.clone()) .unwrap_or_else(move || { - panic!("stage '{:?}' does not exist or is the wrong type", name) + panic!("stage '{:?}' does not exist or is the wrong type", label) }); func(stage); self } - pub fn get_stage>(&self, name: L) -> Option<&T> { + pub fn get_stage>(&self, label: L) -> Option<&T> { self.stages - .get(&name.into()) + .get(&label.into()) .and_then(|stage| stage.downcast_ref::()) } - pub fn get_stage_mut>(&mut self, name: L) -> Option<&mut T> { + pub fn get_stage_mut>(&mut self, label: L) -> Option<&mut T> { self.stages - .get_mut(&name.into()) + .get_mut(&label.into()) .and_then(|stage| stage.downcast_mut::()) } pub fn run_once(&mut self, world: &mut World, resources: &mut Resources) { - for name in self.stage_order.iter() { + for label in self.stage_order.iter() { #[cfg(feature = "trace")] let stage_span = - bevy_utils::tracing::info_span!("stage", name = &format!("{:?}", name) as &str); + bevy_utils::tracing::info_span!("stage", name = &format!("{:?}", label) as &str); #[cfg(feature = "trace")] let _stage_guard = stage_span.enter(); - let stage = self.stages.get_mut(name).unwrap(); + let stage = self.stages.get_mut(label).unwrap(); stage.run(world, resources); } } diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index 794c8e1550a8f..d534e62e7362b 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -25,7 +25,7 @@ use bevy_ecs::{IntoExclusiveSystem, StageLabel, SystemStage}; pub struct ScenePlugin; #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] -enum Stages { +enum SceneStage { SceneStage, } @@ -37,9 +37,9 @@ impl Plugin for ScenePlugin { .init_resource::() .add_stage_after( CoreStage::Event, - Stages::SceneStage, + SceneStage::SceneStage, SystemStage::parallel(), ) - .add_system_to_stage(Stages::SceneStage, scene_spawner_system.exclusive_system()); + .add_system_to_stage(SceneStage::SceneStage, scene_spawner_system.exclusive_system()); } } diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 07db233fce30c..35d5e741948e7 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -15,7 +15,7 @@ use prelude::{parent_update_system, Children, GlobalTransform, Parent, PreviousP pub struct TransformPlugin; #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] -pub enum Systems { +pub enum TransformSystem { TransformPropagate, ParentUpdate, } @@ -30,25 +30,25 @@ impl Plugin for TransformPlugin { // add transform systems to startup so the first update is "correct" .add_startup_system_to_stage( StartupStage::PostStartup, - parent_update_system.system().label(Systems::ParentUpdate), + parent_update_system.system().label(TransformSystem::ParentUpdate), ) .add_startup_system_to_stage( StartupStage::PostStartup, transform_propagate_system::transform_propagate_system .system() - .label(Systems::TransformPropagate) - .after(Systems::ParentUpdate), + .label(TransformSystem::TransformPropagate) + .after(TransformSystem::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, - parent_update_system.system().label(Systems::ParentUpdate), + parent_update_system.system().label(TransformSystem::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, transform_propagate_system::transform_propagate_system .system() - .label(Systems::TransformPropagate) - .after(Systems::ParentUpdate), + .label(TransformSystem::TransformPropagate) + .after(TransformSystem::ParentUpdate), ); } } diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 1f7c51d985aac..b39ce1f6e5f8f 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -30,12 +30,12 @@ use update::ui_z_system; pub struct UiPlugin; #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] -pub enum UiStages { +pub enum UiStage { Ui, } #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)] -pub enum UiSystems { +pub enum UiSystem { Flex, } @@ -46,22 +46,22 @@ pub mod system { impl Plugin for UiPlugin { fn build(&self, app: &mut AppBuilder) { app.init_resource::() - .add_stage_before(CoreStage::PostUpdate, UiStages::Ui, SystemStage::parallel()) + .add_stage_before(CoreStage::PostUpdate, UiStage::Ui, SystemStage::parallel()) .add_system_to_stage(CoreStage::PreUpdate, ui_focus_system.system()) // add these stages to front because these must run before transform update systems .add_system_to_stage( - UiStages::Ui, - widget::text_system.system().before(UiSystems::Flex), + UiStage::Ui, + widget::text_system.system().before(UiSystem::Flex), ) .add_system_to_stage( - UiStages::Ui, - widget::image_node_system.system().before(UiSystems::Flex), + UiStage::Ui, + widget::image_node_system.system().before(UiSystem::Flex), ) .add_system_to_stage( - UiStages::Ui, - flex_node_system.system().label(UiSystems::Flex), + UiStage::Ui, + flex_node_system.system().label(UiSystem::Flex), ) - .add_system_to_stage(UiStages::Ui, ui_z_system.system()) + .add_system_to_stage(UiStage::Ui, ui_z_system.system()) .add_system_to_stage(RenderStage::Draw, widget::draw_text_system.system()); let resources = app.resources(); diff --git a/examples/ecs/ecs_guide.rs b/examples/ecs/ecs_guide.rs index bd8bc8eb4c966..030bcf0c6d1fe 100644 --- a/examples/ecs/ecs_guide.rs +++ b/examples/ecs/ecs_guide.rs @@ -240,7 +240,7 @@ fn local_state_system(mut state: Local, query: Query<(&Player, &Score)>) } #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] -enum MyStages { +enum MyStage { BeforeRound, AfterRound, } @@ -304,25 +304,25 @@ fn main() { // "after_round": score_check_system, game_over_system .add_stage_before( CoreStage::Update, - MyStages::BeforeRound, + MyStage::BeforeRound, SystemStage::parallel(), ) .add_stage_after( CoreStage::Update, - MyStages::AfterRound, + MyStage::AfterRound, SystemStage::parallel(), ) - .add_system_to_stage(MyStages::BeforeRound, new_round_system.system()) - .add_system_to_stage(MyStages::BeforeRound, new_player_system.system()) + .add_system_to_stage(MyStage::BeforeRound, new_round_system.system()) + .add_system_to_stage(MyStage::BeforeRound, new_player_system.system()) // We can ensure that game_over system runs after score_check_system using explicit ordering constraints // First, we label the system we want to refer to using `.label` // Then, we use either `.before` or `.after` to describe the order we want the relationship .add_system_to_stage( - MyStages::AfterRound, + MyStage::AfterRound, score_check_system.system().label(MyLabels::ScoreCheck), ) .add_system_to_stage( - MyStages::AfterRound, + MyStage::AfterRound, game_over_system.system().after(MyLabels::ScoreCheck), ) // We can check our systems for execution order ambiguities by examining the output produced in the console diff --git a/examples/game/alien_cake_addict.rs b/examples/game/alien_cake_addict.rs index eaae9f0515695..f0e50db1d7f99 100644 --- a/examples/game/alien_cake_addict.rs +++ b/examples/game/alien_cake_addict.rs @@ -6,7 +6,7 @@ use bevy::{ use rand::Rng; #[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)] -enum GameStages { +enum GameStage { InGame, BonusUpdate, } @@ -26,41 +26,41 @@ fn main() { .add_startup_system(setup_cameras.system()) .add_stage_after( CoreStage::Update, - GameStages::InGame, + GameStage::InGame, StateStage::::default(), ) - .on_state_enter(GameStages::InGame, GameState::Playing, setup.system()) - .on_state_update(GameStages::InGame, GameState::Playing, move_player.system()) + .on_state_enter(GameStage::InGame, GameState::Playing, setup.system()) + .on_state_update(GameStage::InGame, GameState::Playing, move_player.system()) .on_state_update( - GameStages::InGame, + GameStage::InGame, GameState::Playing, focus_camera.system(), ) .on_state_update( - GameStages::InGame, + GameStage::InGame, GameState::Playing, rotate_bonus.system(), ) .on_state_update( - GameStages::InGame, + GameStage::InGame, GameState::Playing, scoreboard_system.system(), ) - .on_state_exit(GameStages::InGame, GameState::Playing, teardown.system()) + .on_state_exit(GameStage::InGame, GameState::Playing, teardown.system()) .on_state_enter( - GameStages::InGame, + GameStage::InGame, GameState::GameOver, display_score.system(), ) .on_state_update( - GameStages::InGame, + GameStage::InGame, GameState::GameOver, gameover_keyboard.system(), ) - .on_state_exit(GameStages::InGame, GameState::GameOver, teardown.system()) + .on_state_exit(GameStage::InGame, GameState::GameOver, teardown.system()) .add_stage_after( CoreStage::Update, - GameStages::BonusUpdate, + GameStage::BonusUpdate, SystemStage::parallel() .with_run_criteria(FixedTimestep::step(5.0)) .with_system(spawn_bonus.system()), From a90479620412f53a0c41c183bf6286d8a1e50e7f Mon Sep 17 00:00:00 2001 From: TheRawMeatball Date: Thu, 18 Feb 2021 17:26:33 +0300 Subject: [PATCH 22/24] cargo fmt --- crates/bevy_scene/src/lib.rs | 5 ++++- crates/bevy_transform/src/lib.rs | 8 ++++++-- crates/bevy_ui/src/lib.rs | 5 +---- examples/game/alien_cake_addict.rs | 12 ++---------- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index d534e62e7362b..b6e6ffdd5f770 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -40,6 +40,9 @@ impl Plugin for ScenePlugin { SceneStage::SceneStage, SystemStage::parallel(), ) - .add_system_to_stage(SceneStage::SceneStage, scene_spawner_system.exclusive_system()); + .add_system_to_stage( + SceneStage::SceneStage, + scene_spawner_system.exclusive_system(), + ); } } diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 35d5e741948e7..2b23d25eb7b86 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -30,7 +30,9 @@ impl Plugin for TransformPlugin { // add transform systems to startup so the first update is "correct" .add_startup_system_to_stage( StartupStage::PostStartup, - parent_update_system.system().label(TransformSystem::ParentUpdate), + parent_update_system + .system() + .label(TransformSystem::ParentUpdate), ) .add_startup_system_to_stage( StartupStage::PostStartup, @@ -41,7 +43,9 @@ impl Plugin for TransformPlugin { ) .add_system_to_stage( CoreStage::PostUpdate, - parent_update_system.system().label(TransformSystem::ParentUpdate), + parent_update_system + .system() + .label(TransformSystem::ParentUpdate), ) .add_system_to_stage( CoreStage::PostUpdate, diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index b39ce1f6e5f8f..3a32cfb6807dc 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -57,10 +57,7 @@ impl Plugin for UiPlugin { UiStage::Ui, widget::image_node_system.system().before(UiSystem::Flex), ) - .add_system_to_stage( - UiStage::Ui, - flex_node_system.system().label(UiSystem::Flex), - ) + .add_system_to_stage(UiStage::Ui, flex_node_system.system().label(UiSystem::Flex)) .add_system_to_stage(UiStage::Ui, ui_z_system.system()) .add_system_to_stage(RenderStage::Draw, widget::draw_text_system.system()); diff --git a/examples/game/alien_cake_addict.rs b/examples/game/alien_cake_addict.rs index f0e50db1d7f99..dfa34bd448a18 100644 --- a/examples/game/alien_cake_addict.rs +++ b/examples/game/alien_cake_addict.rs @@ -31,16 +31,8 @@ fn main() { ) .on_state_enter(GameStage::InGame, GameState::Playing, setup.system()) .on_state_update(GameStage::InGame, GameState::Playing, move_player.system()) - .on_state_update( - GameStage::InGame, - GameState::Playing, - focus_camera.system(), - ) - .on_state_update( - GameStage::InGame, - GameState::Playing, - rotate_bonus.system(), - ) + .on_state_update(GameStage::InGame, GameState::Playing, focus_camera.system()) + .on_state_update(GameStage::InGame, GameState::Playing, rotate_bonus.system()) .on_state_update( GameStage::InGame, GameState::Playing, From ea539b050d86bea939512f4a71fe8d8a56795e9e Mon Sep 17 00:00:00 2001 From: Alexander Sepity Date: Thu, 18 Feb 2021 22:37:01 +0300 Subject: [PATCH 23/24] Improvements from @Ratyzs --- crates/bevy_app/src/app_builder.rs | 36 ++++---- crates/bevy_ecs/macros/src/lib.rs | 10 ++- crates/bevy_ecs/src/lib.rs | 4 +- crates/bevy_ecs/src/schedule/label.rs | 86 +++++++++--------- crates/bevy_ecs/src/schedule/mod.rs | 72 ++++++++------- crates/bevy_ecs/src/schedule/stage.rs | 88 +++++++++---------- .../bevy_ecs/src/schedule/system_container.rs | 32 +++---- .../src/schedule/system_descriptor.rs | 69 ++++++++------- crates/bevy_render/src/render_graph/graph.rs | 2 +- 9 files changed, 196 insertions(+), 203 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 0c195d0c01a5e..24a0c377cc96d 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -54,15 +54,15 @@ impl AppBuilder { self } - pub fn add_stage(&mut self, label: impl Into, stage: S) -> &mut Self { + pub fn add_stage(&mut self, label: impl StageLabel, stage: S) -> &mut Self { self.app.schedule.add_stage(label, stage); self } pub fn add_stage_after( &mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> &mut Self { self.app.schedule.add_stage_after(target, label, stage); @@ -71,19 +71,15 @@ impl AppBuilder { pub fn add_stage_before( &mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> &mut Self { self.app.schedule.add_stage_before(target, label, stage); self } - pub fn add_startup_stage( - &mut self, - label: impl Into, - stage: S, - ) -> &mut Self { + pub fn add_startup_stage(&mut self, label: impl StageLabel, stage: S) -> &mut Self { self.app .schedule .stage(CoreStage::Startup, |schedule: &mut Schedule| { @@ -94,8 +90,8 @@ impl AppBuilder { pub fn add_startup_stage_after( &mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> &mut Self { self.app @@ -108,8 +104,8 @@ impl AppBuilder { pub fn add_startup_stage_before( &mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> &mut Self { self.app @@ -122,7 +118,7 @@ impl AppBuilder { pub fn stage &mut T>( &mut self, - label: impl Into, + label: impl StageLabel, func: F, ) -> &mut Self { self.app.schedule.stage(label, func); @@ -135,7 +131,7 @@ impl AppBuilder { pub fn add_system_to_stage( &mut self, - stage_label: impl Into, + stage_label: impl StageLabel, system: impl Into, ) -> &mut Self { self.app.schedule.add_system_to_stage(stage_label, system); @@ -148,7 +144,7 @@ impl AppBuilder { pub fn add_startup_system_to_stage( &mut self, - stage_label: impl Into, + stage_label: impl StageLabel, system: impl Into, ) -> &mut Self { self.app @@ -161,7 +157,7 @@ impl AppBuilder { pub fn on_state_enter( &mut self, - stage: impl Into, + stage: impl StageLabel, state: T, system: impl Into, ) -> &mut Self { @@ -172,7 +168,7 @@ impl AppBuilder { pub fn on_state_update( &mut self, - stage: impl Into, + stage: impl StageLabel, state: T, system: impl Into, ) -> &mut Self { @@ -183,7 +179,7 @@ impl AppBuilder { pub fn on_state_exit( &mut self, - stage: impl Into, + stage: impl StageLabel, state: T, system: impl Into, ) -> &mut Self { diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index a536d85fbbcae..a474e04d3045c 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -470,13 +470,13 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { #[proc_macro_derive(SystemLabel)] pub fn derive_system_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - derive_label(input, Ident::new("SystemLabelMarker", Span::call_site())).into() + derive_label(input, Ident::new("SystemLabel", Span::call_site())).into() } #[proc_macro_derive(StageLabel)] pub fn derive_stage_label(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - derive_label(input, Ident::new("StageLabelMarker", Span::call_site())).into() + derive_label(input, Ident::new("StageLabel", Span::call_site())).into() } fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { @@ -495,6 +495,10 @@ fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { let crate_path: Path = syn::parse(path_str.parse::().unwrap()).unwrap(); quote! { - impl #crate_path::Label<#crate_path::#label_type> for #ident {} + impl #crate_path::#label_type for #ident { + fn dyn_clone(&self) -> Box { + Box::new(self.clone()) + } + } } } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 2a2fc0a08fe30..84df7b0ad1046 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -20,7 +20,7 @@ pub mod prelude { SystemSet, SystemStage, }, system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Label, Mut, Mutated, - Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World, + Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Mut, Mutated, Or, + QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World, }; } diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index f892f610ef43e..5e79f6efed031 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -5,13 +5,6 @@ use std::{ hash::{Hash, Hasher}, }; -use crate::{StageLabelMarker, SystemLabelMarker}; - -pub trait Label: DynHash + DynClone + Debug + Send + Sync + 'static {} - -pub type SystemLabel = Box>; -pub type StageLabel = Box>; - pub trait DynEq: Any { fn as_any(&self) -> &dyn Any; @@ -54,52 +47,53 @@ where } } -pub trait DynClone { - fn dyn_clone(&self) -> Box>; +pub trait StageLabel: DynHash + Debug + Send + Sync + 'static { + #[doc(hidden)] + fn dyn_clone(&self) -> Box; } +pub(crate) type BoxedStageLabel = Box; -impl DynClone for T -where - T: Label + Clone + 'static, -{ - fn dyn_clone(&self) -> Box> { - Box::new(self.clone()) - } -} - -impl PartialEq for dyn Label { - fn eq(&self, other: &Self) -> bool { - self.dyn_eq(other.as_dyn_eq()) - } +pub trait SystemLabel: DynHash + Debug + Send + Sync + 'static { + #[doc(hidden)] + fn dyn_clone(&self) -> Box; } +pub(crate) type BoxedSystemLabel = Box; + +macro_rules! impl_label { + ($trait_name:ident) => { + impl PartialEq for dyn $trait_name { + fn eq(&self, other: &Self) -> bool { + self.dyn_eq(other.as_dyn_eq()) + } + } -impl Eq for dyn Label {} + impl Eq for dyn $trait_name {} -impl Hash for dyn Label { - fn hash(&self, state: &mut H) { - self.dyn_hash(state); - } -} + impl Hash for dyn $trait_name { + fn hash(&self, state: &mut H) { + self.dyn_hash(state); + } + } -impl Clone for Box> { - fn clone(&self) -> Self { - self.dyn_clone() - } -} + impl Clone for Box { + fn clone(&self) -> Self { + self.dyn_clone() + } + } -impl> From for Box> { - fn from(t: T) -> Self { - Box::new(t) - } -} + impl $trait_name for Cow<'static, str> { + fn dyn_clone(&self) -> Box { + Box::new(self.clone()) + } + } -impl> From for Box> { - fn from(t: T) -> Self { - Box::new(t) - } + impl $trait_name for &'static str { + fn dyn_clone(&self) -> Box { + Box::new(<&str>::clone(self)) + } + } + }; } -impl Label for Cow<'static, str> {} -impl Label for &'static str {} -impl Label for Cow<'static, str> {} -impl Label for &'static str {} +impl_label!(StageLabel); +impl_label!(SystemLabel); diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index c539c9387f7cd..81ed8c35d41ff 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -2,6 +2,7 @@ mod executor; mod executor_parallel; mod label; mod stage; +//mod stageless; mod state; mod system_container; mod system_descriptor; @@ -24,23 +25,21 @@ use std::{any::TypeId, borrow::Cow}; #[derive(Default)] pub struct Schedule { - stages: HashMap>, - stage_order: Vec, + stages: HashMap>, + stage_order: Vec, run_criteria: RunCriteria, } -pub struct StageLabelMarker; - impl Schedule { - pub fn with_stage(mut self, label: impl Into, stage: S) -> Self { + pub fn with_stage(mut self, label: impl StageLabel, stage: S) -> Self { self.add_stage(label, stage); self } pub fn with_stage_after( mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> Self { self.add_stage_after(target, label, stage); @@ -49,8 +48,8 @@ impl Schedule { pub fn with_stage_before( mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> Self { self.add_stage_before(target, label, stage); @@ -64,7 +63,7 @@ impl Schedule { pub fn with_system_in_stage( mut self, - stage_label: impl Into, + stage_label: impl StageLabel, system: impl Into, ) -> Self { self.add_system_to_stage(stage_label, system); @@ -79,8 +78,8 @@ impl Schedule { self } - pub fn add_stage(&mut self, label: impl Into, stage: S) -> &mut Self { - let label = label.into(); + pub fn add_stage(&mut self, label: impl StageLabel, stage: S) -> &mut Self { + let label: Box = Box::new(label); self.stage_order.push(label.clone()); let prev = self.stages.insert(label.clone(), Box::new(stage)); if prev.is_some() { @@ -91,17 +90,17 @@ impl Schedule { pub fn add_stage_after( &mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> &mut Self { - let label = label.into(); - let target = target.into(); + let label: Box = Box::new(label); + let target = &target as &dyn StageLabel; let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_label)| **stage_label == target.clone()) + .find(|(_i, stage_label)| &***stage_label == target) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); @@ -115,17 +114,17 @@ impl Schedule { pub fn add_stage_before( &mut self, - target: impl Into, - label: impl Into, + target: impl StageLabel, + label: impl StageLabel, stage: S, ) -> &mut Self { - let label = label.into(); - let target = target.into(); + let label: Box = Box::new(label); + let target = &target as &dyn StageLabel; let target_index = self .stage_order .iter() .enumerate() - .find(|(_i, stage_label)| **stage_label == target.clone()) + .find(|(_i, stage_label)| &***stage_label == target) .map(|(i, _)| i) .unwrap_or_else(|| panic!("Target stage does not exist: {:?}.", target)); @@ -139,14 +138,16 @@ impl Schedule { pub fn add_system_to_stage( &mut self, - stage_label: impl Into, + stage_label: impl StageLabel, system: impl Into, ) -> &mut Self { - let label = stage_label.into(); let stage = self - .get_stage_mut::(label.clone()) + .get_stage_mut::(&stage_label) .unwrap_or_else(move || { - panic!("Stage '{:?}' does not exist or is not a SystemStage", label) + panic!( + "Stage '{:?}' does not exist or is not a SystemStage", + stage_label + ) }); stage.add_system(system); self @@ -154,28 +155,25 @@ impl Schedule { pub fn stage &mut T>( &mut self, - label: impl Into, + label: impl StageLabel, func: F, ) -> &mut Self { - let label = label.into(); - let stage = self - .get_stage_mut::(label.clone()) - .unwrap_or_else(move || { - panic!("stage '{:?}' does not exist or is the wrong type", label) - }); + let stage = self.get_stage_mut::(&label).unwrap_or_else(move || { + panic!("stage '{:?}' does not exist or is the wrong type", label) + }); func(stage); self } - pub fn get_stage>(&self, label: L) -> Option<&T> { + pub fn get_stage(&self, label: &dyn StageLabel) -> Option<&T> { self.stages - .get(&label.into()) + .get(label) .and_then(|stage| stage.downcast_ref::()) } - pub fn get_stage_mut>(&mut self, label: L) -> Option<&mut T> { + pub fn get_stage_mut(&mut self, label: &dyn StageLabel) -> Option<&mut T> { self.stages - .get_mut(&label.into()) + .get_mut(label) .and_then(|stage| stage.downcast_mut::()) } diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 98495c5bd98a2..6c84d3c1323c9 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -8,7 +8,7 @@ use super::{ SingleThreadedExecutor, SystemContainer, }; use crate::{ - InsertionPoint, Resources, RunCriteria, + BoxedSystemLabel, InsertionPoint, Resources, RunCriteria, ShouldRun::{self, *}, System, SystemDescriptor, SystemLabel, SystemSet, World, }; @@ -363,8 +363,8 @@ impl SystemStage { } enum DependencyGraphError { - LabelNotFound(SystemLabel), - DuplicateLabel(SystemLabel), + LabelNotFound(Box), + DuplicateLabel(Box), GraphCycles(Vec>), } @@ -394,7 +394,7 @@ fn sort_systems(systems: &mut Vec) -> Result<(), Dependenc fn build_dependency_graph( systems: &[impl SystemContainer], ) -> Result>, DependencyGraphError> { - let mut labels = HashMap::::default(); + let mut labels = HashMap::::default(); for (label, index) in systems.iter().enumerate().filter_map(|(index, container)| { container .label() @@ -623,7 +623,7 @@ impl Stage for SystemStage { #[cfg(test)] mod tests { - use crate::{prelude::*, SingleThreadedExecutor}; + use crate::{prelude::*, BoxedSystemLabel, SingleThreadedExecutor}; fn make_exclusive(tag: usize) -> impl FnMut(&mut Resources) { move |resources| resources.get_mut::>().unwrap().push(tag) @@ -1119,7 +1119,7 @@ mod tests { fn find_ambiguities_labels( systems: &[impl SystemContainer], - ) -> Vec<(SystemLabel, SystemLabel)> { + ) -> Vec<(BoxedSystemLabel, BoxedSystemLabel)> { find_ambiguities(systems) .drain(..) .map(|(index_a, index_b)| { @@ -1158,8 +1158,8 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("1".into(), "4".into())) - || ambiguities.contains(&("4".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) ); assert_eq!(ambiguities.len(), 1); @@ -1173,8 +1173,8 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("1".into(), "4".into())) - || ambiguities.contains(&("4".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) ); assert_eq!(ambiguities.len(), 1); @@ -1198,12 +1198,12 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("0".into(), "3".into())) - || ambiguities.contains(&("3".into(), "0".into())) + ambiguities.contains(&(Box::new("0"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("0"))) ); assert!( - ambiguities.contains(&("1".into(), "4".into())) - || ambiguities.contains(&("4".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) ); assert_eq!(ambiguities.len(), 2); @@ -1215,8 +1215,8 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("0".into(), "1".into())) - || ambiguities.contains(&("1".into(), "0".into())) + ambiguities.contains(&(Box::new("0"), Box::new("1"))) + || ambiguities.contains(&(Box::new("1"), Box::new("0"))) ); assert_eq!(ambiguities.len(), 1); @@ -1228,8 +1228,8 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("1".into(), "2".into())) - || ambiguities.contains(&("2".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("2"))) + || ambiguities.contains(&(Box::new("2"), Box::new("1"))) ); assert_eq!(ambiguities.len(), 1); @@ -1242,8 +1242,8 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("1".into(), "2".into())) - || ambiguities.contains(&("2".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("2"))) + || ambiguities.contains(&(Box::new("2"), Box::new("1"))) ); assert_eq!(ambiguities.len(), 1); @@ -1274,28 +1274,28 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.parallel); assert!( - ambiguities.contains(&("1".into(), "2".into())) - || ambiguities.contains(&("2".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("2"))) + || ambiguities.contains(&(Box::new("2"), Box::new("1"))) ); assert!( - ambiguities.contains(&("1".into(), "3".into())) - || ambiguities.contains(&("3".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("1"))) ); assert!( - ambiguities.contains(&("1".into(), "4".into())) - || ambiguities.contains(&("4".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) ); assert!( - ambiguities.contains(&("2".into(), "3".into())) - || ambiguities.contains(&("3".into(), "2".into())) + ambiguities.contains(&(Box::new("2"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("2"))) ); assert!( - ambiguities.contains(&("2".into(), "4".into())) - || ambiguities.contains(&("4".into(), "2".into())) + ambiguities.contains(&(Box::new("2"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("2"))) ); assert!( - ambiguities.contains(&("3".into(), "4".into())) - || ambiguities.contains(&("4".into(), "3".into())) + ambiguities.contains(&(Box::new("3"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("3"))) ); assert_eq!(ambiguities.len(), 6); @@ -1324,28 +1324,28 @@ mod tests { stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start); assert!( - ambiguities.contains(&("1".into(), "3".into())) - || ambiguities.contains(&("3".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("1"))) ); assert!( - ambiguities.contains(&("2".into(), "3".into())) - || ambiguities.contains(&("3".into(), "2".into())) + ambiguities.contains(&(Box::new("2"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("2"))) ); assert!( - ambiguities.contains(&("1".into(), "4".into())) - || ambiguities.contains(&("4".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) ); assert!( - ambiguities.contains(&("2".into(), "4".into())) - || ambiguities.contains(&("4".into(), "2".into())) + ambiguities.contains(&(Box::new("2"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("2"))) ); assert!( - ambiguities.contains(&("1".into(), "5".into())) - || ambiguities.contains(&("5".into(), "1".into())) + ambiguities.contains(&(Box::new("1"), Box::new("5"))) + || ambiguities.contains(&(Box::new("5"), Box::new("1"))) ); assert!( - ambiguities.contains(&("2".into(), "5".into())) - || ambiguities.contains(&("5".into(), "2".into())) + ambiguities.contains(&(Box::new("2"), Box::new("5"))) + || ambiguities.contains(&(Box::new("5"), Box::new("2"))) ); assert_eq!(ambiguities.len(), 6); } diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index c760df8eaf70a..09c5475dc0a9d 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, ptr::NonNull}; use crate::{ - ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System, SystemLabel, + BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System, }; pub(super) trait SystemContainer { @@ -9,9 +9,9 @@ pub(super) trait SystemContainer { fn dependencies(&self) -> &[usize]; fn set_dependencies(&mut self, dependencies: impl IntoIterator); fn system_set(&self) -> usize; - fn label(&self) -> &Option; - fn before(&self) -> &[SystemLabel]; - fn after(&self) -> &[SystemLabel]; + fn label(&self) -> &Option; + fn before(&self) -> &[BoxedSystemLabel]; + fn after(&self) -> &[BoxedSystemLabel]; fn is_compatible(&self, other: &Self) -> bool; } @@ -19,9 +19,9 @@ pub(super) struct ExclusiveSystemContainer { system: Box, dependencies: Vec, set: usize, - label: Option, - before: Vec, - after: Vec, + label: Option, + before: Vec, + after: Vec, } impl ExclusiveSystemContainer { @@ -62,15 +62,15 @@ impl SystemContainer for ExclusiveSystemContainer { self.set } - fn label(&self) -> &Option { + fn label(&self) -> &Option { &self.label } - fn before(&self) -> &[SystemLabel] { + fn before(&self) -> &[BoxedSystemLabel] { &self.before } - fn after(&self) -> &[SystemLabel] { + fn after(&self) -> &[BoxedSystemLabel] { &self.after } @@ -84,9 +84,9 @@ pub struct ParallelSystemContainer { pub(crate) should_run: bool, dependencies: Vec, set: usize, - label: Option, - before: Vec, - after: Vec, + label: Option, + before: Vec, + after: Vec, } impl SystemContainer for ParallelSystemContainer { @@ -110,15 +110,15 @@ impl SystemContainer for ParallelSystemContainer { self.set } - fn label(&self) -> &Option { + fn label(&self) -> &Option { &self.label } - fn before(&self) -> &[SystemLabel] { + fn before(&self) -> &[BoxedSystemLabel] { &self.before } - fn after(&self) -> &[SystemLabel] { + fn after(&self) -> &[BoxedSystemLabel] { &self.after } diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index 232634b2927ea..eac5f362b2241 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -1,5 +1,6 @@ use crate::{ - BoxedSystem, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, System, SystemLabel, + BoxedSystem, BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, + System, SystemLabel, }; /// Encapsulates a system and information on when it run in a `SystemStage`. @@ -78,9 +79,9 @@ impl From for SystemDescriptor { /// Encapsulates a parallel system and information on when it run in a `SystemStage`. pub struct ParallelSystemDescriptor { pub(crate) system: BoxedSystem<(), ()>, - pub(crate) label: Option, - pub(crate) before: Vec, - pub(crate) after: Vec, + pub(crate) label: Option, + pub(crate) before: Vec, + pub(crate) after: Vec, } fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor { @@ -94,28 +95,28 @@ fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescrip pub trait ParallelSystemDescriptorCoercion { /// Assigns a label to the system. - fn label(self, label: impl Into) -> ParallelSystemDescriptor; + fn label(self, label: impl SystemLabel) -> ParallelSystemDescriptor; /// Specifies that the system should run before the system with given label. - fn before(self, label: impl Into) -> ParallelSystemDescriptor; + fn before(self, label: impl SystemLabel) -> ParallelSystemDescriptor; /// Specifies that the system should run after the system with given label. - fn after(self, label: impl Into) -> ParallelSystemDescriptor; + fn after(self, label: impl SystemLabel) -> ParallelSystemDescriptor; } impl ParallelSystemDescriptorCoercion for ParallelSystemDescriptor { - fn label(mut self, label: impl Into) -> ParallelSystemDescriptor { - self.label = Some(label.into()); + fn label(mut self, label: impl SystemLabel) -> ParallelSystemDescriptor { + self.label = Some(Box::new(label)); self } - fn before(mut self, label: impl Into) -> ParallelSystemDescriptor { - self.before.push(label.into()); + fn before(mut self, label: impl SystemLabel) -> ParallelSystemDescriptor { + self.before.push(Box::new(label)); self } - fn after(mut self, label: impl Into) -> ParallelSystemDescriptor { - self.after.push(label.into()); + fn after(mut self, label: impl SystemLabel) -> ParallelSystemDescriptor { + self.after.push(Box::new(label)); self } } @@ -124,29 +125,29 @@ impl ParallelSystemDescriptorCoercion for S where S: System, { - fn label(self, label: impl Into) -> ParallelSystemDescriptor { + fn label(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).label(label) } - fn before(self, label: impl Into) -> ParallelSystemDescriptor { + fn before(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).before(label) } - fn after(self, label: impl Into) -> ParallelSystemDescriptor { + fn after(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).after(label) } } impl ParallelSystemDescriptorCoercion for BoxedSystem<(), ()> { - fn label(self, label: impl Into) -> ParallelSystemDescriptor { + fn label(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(self).label(label) } - fn before(self, label: impl Into) -> ParallelSystemDescriptor { + fn before(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(self).before(label) } - fn after(self, label: impl Into) -> ParallelSystemDescriptor { + fn after(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(self).after(label) } } @@ -161,9 +162,9 @@ pub(crate) enum InsertionPoint { /// Encapsulates an exclusive system and information on when it run in a `SystemStage`. pub struct ExclusiveSystemDescriptor { pub(crate) system: Box, - pub(crate) label: Option, - pub(crate) before: Vec, - pub(crate) after: Vec, + pub(crate) label: Option, + pub(crate) before: Vec, + pub(crate) after: Vec, pub(crate) insertion_point: InsertionPoint, } @@ -179,13 +180,13 @@ fn new_exclusive_descriptor(system: Box) -> ExclusiveSystem pub trait ExclusiveSystemDescriptorCoercion { /// Assigns a label to the system. - fn label(self, label: impl Into) -> ExclusiveSystemDescriptor; + fn label(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor; /// Specifies that the system should run before the system with given label. - fn before(self, label: impl Into) -> ExclusiveSystemDescriptor; + fn before(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor; /// Specifies that the system should run after the system with given label. - fn after(self, label: impl Into) -> ExclusiveSystemDescriptor; + fn after(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor; /// Specifies that the system should run with other exclusive systems at the start of stage. fn at_start(self) -> ExclusiveSystemDescriptor; @@ -199,18 +200,18 @@ pub trait ExclusiveSystemDescriptorCoercion { } impl ExclusiveSystemDescriptorCoercion for ExclusiveSystemDescriptor { - fn label(mut self, label: impl Into) -> ExclusiveSystemDescriptor { - self.label = Some(label.into()); + fn label(mut self, label: impl SystemLabel) -> ExclusiveSystemDescriptor { + self.label = Some(Box::new(label)); self } - fn before(mut self, label: impl Into) -> ExclusiveSystemDescriptor { - self.before.push(label.into()); + fn before(mut self, label: impl SystemLabel) -> ExclusiveSystemDescriptor { + self.before.push(Box::new(label)); self } - fn after(mut self, label: impl Into) -> ExclusiveSystemDescriptor { - self.after.push(label.into()); + fn after(mut self, label: impl SystemLabel) -> ExclusiveSystemDescriptor { + self.after.push(Box::new(label)); self } @@ -234,15 +235,15 @@ impl ExclusiveSystemDescriptorCoercion for T where T: ExclusiveSystem + 'static, { - fn label(self, label: impl Into) -> ExclusiveSystemDescriptor { + fn label(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).label(label) } - fn before(self, label: impl Into) -> ExclusiveSystemDescriptor { + fn before(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).before(label) } - fn after(self, label: impl Into) -> ExclusiveSystemDescriptor { + fn after(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).after(label) } diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index d00562f9bbfe1..6a1e14ef7036b 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -45,7 +45,7 @@ impl RenderGraph { { let schedule = self.system_node_schedule.as_mut().unwrap(); let stage = schedule - .get_stage_mut::(RenderGraphUpdate) + .get_stage_mut::(&RenderGraphUpdate) .unwrap(); stage.add_system(node.get_system(&mut self.commands)); self.add_node(name, node) From 3f0d0743486f8bb09b027ad8a80a8a9fc773e6a2 Mon Sep 17 00:00:00 2001 From: Alexander Sepity Date: Thu, 18 Feb 2021 23:37:59 +0300 Subject: [PATCH 24/24] Resolve conflicts --- crates/bevy_ecs/macros/src/lib.rs | 6 + crates/bevy_ecs/src/lib.rs | 5 +- crates/bevy_ecs/src/schedule/label.rs | 7 + crates/bevy_ecs/src/schedule/stage.rs | 170 +++++++++++++++++- .../bevy_ecs/src/schedule/system_container.rs | 16 +- .../src/schedule/system_descriptor.rs | 38 +++- 6 files changed, 236 insertions(+), 6 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index a474e04d3045c..66a764c0ecc6d 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -479,6 +479,12 @@ pub fn derive_stage_label(input: TokenStream) -> TokenStream { derive_label(input, Ident::new("StageLabel", Span::call_site())).into() } +#[proc_macro_derive(AmbiguitySetLabel)] +pub fn derive_ambiguity_set_label(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + derive_label(input, Ident::new("AmbiguitySetLabel", Span::call_site())).into() +} + fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 { let ident = input.ident; diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 84df7b0ad1046..be73d6c0638ab 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -20,7 +20,8 @@ pub mod prelude { SystemSet, SystemStage, }, system::{Commands, ExclusiveSystem, IntoExclusiveSystem, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, Mut, Mutated, Or, - QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, World, + Added, AmbiguitySetLabel, Bundle, Changed, Component, Entity, Flags, In, IntoChainSystem, + Mut, Mutated, Or, QuerySet, Ref, RefMut, ShouldRun, StageLabel, SystemLabel, With, Without, + World, }; } diff --git a/crates/bevy_ecs/src/schedule/label.rs b/crates/bevy_ecs/src/schedule/label.rs index 5e79f6efed031..725c3f80977b5 100644 --- a/crates/bevy_ecs/src/schedule/label.rs +++ b/crates/bevy_ecs/src/schedule/label.rs @@ -59,6 +59,12 @@ pub trait SystemLabel: DynHash + Debug + Send + Sync + 'static { } pub(crate) type BoxedSystemLabel = Box; +pub trait AmbiguitySetLabel: DynHash + Debug + Send + Sync + 'static { + #[doc(hidden)] + fn dyn_clone(&self) -> Box; +} +pub(crate) type BoxedAmbiguitySetLabel = Box; + macro_rules! impl_label { ($trait_name:ident) => { impl PartialEq for dyn $trait_name { @@ -97,3 +103,4 @@ macro_rules! impl_label { impl_label!(StageLabel); impl_label!(SystemLabel); +impl_label!(AmbiguitySetLabel); diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 6c84d3c1323c9..c81382636825c 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -482,9 +482,20 @@ fn topological_order( /// Returns vector containing all pairs of indices of systems with ambiguous execution order. /// Systems must be topologically sorted beforehand. fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> { + let mut ambiguity_set_labels = HashMap::default(); + for set in systems.iter().flat_map(|c| c.ambiguity_sets()) { + let len = ambiguity_set_labels.len(); + ambiguity_set_labels.entry(set).or_insert(len); + } + let mut all_ambiguity_sets = Vec::::with_capacity(systems.len()); let mut all_dependencies = Vec::::with_capacity(systems.len()); let mut all_dependants = Vec::::with_capacity(systems.len()); for (index, container) in systems.iter().enumerate() { + let mut ambiguity_sets = FixedBitSet::with_capacity(ambiguity_set_labels.len()); + for set in container.ambiguity_sets() { + ambiguity_sets.insert(ambiguity_set_labels[set]); + } + all_ambiguity_sets.push(ambiguity_sets); let mut dependencies = FixedBitSet::with_capacity(systems.len()); for &dependency in container.dependencies() { dependencies.union_with(&all_dependencies[dependency]); @@ -522,7 +533,10 @@ fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize)> { for index_b in full_bitset.difference(&relations) /*.take(index_a)*/ { - if !processed.contains(index_b) && !systems[index_a].is_compatible(&systems[index_b]) { + if !processed.contains(index_b) + && all_ambiguity_sets[index_a].is_disjoint(&all_ambiguity_sets[index_b]) + && !systems[index_a].is_compatible(&systems[index_b]) + { ambiguities.push((index_a, index_b)); } } @@ -1207,6 +1221,27 @@ mod tests { ); assert_eq!(ambiguities.len(), 2); + let mut stage = SystemStage::parallel() + .with_system(component.system().label("0")) + .with_system( + resource + .system() + .label("1") + .after("0") + .in_ambiguity_set("a"), + ) + .with_system(empty.system().label("2")) + .with_system(component.system().label("3").after("2").before("4")) + .with_system(resource.system().label("4").in_ambiguity_set("a")); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.parallel); + assert!( + ambiguities.contains(&(Box::new("0"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("0"))) + ); + assert_eq!(ambiguities.len(), 1); + let mut stage = SystemStage::parallel() .with_system(component.system().label("0").before("2")) .with_system(component.system().label("1").before("2")) @@ -1247,6 +1282,30 @@ mod tests { ); assert_eq!(ambiguities.len(), 1); + let mut stage = SystemStage::parallel() + .with_system(component.system().label("0").before("1").before("2")) + .with_system(component.system().label("1").in_ambiguity_set("a")) + .with_system(component.system().label("2").in_ambiguity_set("a")) + .with_system(component.system().label("3").after("1").after("2")); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.parallel); + assert_eq!(ambiguities.len(), 0); + + let mut stage = SystemStage::parallel() + .with_system(component.system().label("0").before("1").before("2")) + .with_system(component.system().label("1").in_ambiguity_set("a")) + .with_system(component.system().label("2").in_ambiguity_set("b")) + .with_system(component.system().label("3").after("1").after("2")); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.parallel); + assert!( + ambiguities.contains(&(Box::new("1"), Box::new("2"))) + || ambiguities.contains(&(Box::new("2"), Box::new("1"))) + ); + assert_eq!(ambiguities.len(), 1); + let mut stage = SystemStage::parallel() .with_system( component @@ -1299,6 +1358,76 @@ mod tests { ); assert_eq!(ambiguities.len(), 6); + let mut stage = SystemStage::parallel() + .with_system( + component + .system() + .label("0") + .before("1") + .before("2") + .before("3") + .before("4"), + ) + .with_system(component.system().label("1").in_ambiguity_set("a")) + .with_system(component.system().label("2").in_ambiguity_set("a")) + .with_system(component.system().label("3").in_ambiguity_set("a")) + .with_system(component.system().label("4").in_ambiguity_set("a")) + .with_system( + component + .system() + .label("5") + .after("1") + .after("2") + .after("3") + .after("4"), + ); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.parallel); + assert_eq!(ambiguities.len(), 0); + + let mut stage = SystemStage::parallel() + .with_system( + component + .system() + .label("0") + .before("1") + .before("2") + .before("3") + .before("4"), + ) + .with_system(component.system().label("1").in_ambiguity_set("a")) + .with_system(component.system().label("2").in_ambiguity_set("a")) + .with_system( + component + .system() + .label("3") + .in_ambiguity_set("a") + .in_ambiguity_set("b"), + ) + .with_system(component.system().label("4").in_ambiguity_set("b")) + .with_system( + component + .system() + .label("5") + .after("1") + .after("2") + .after("3") + .after("4"), + ); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.parallel); + assert!( + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) + ); + assert!( + ambiguities.contains(&(Box::new("2"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("2"))) + ); + assert_eq!(ambiguities.len(), 2); + let mut stage = SystemStage::parallel() .with_system(empty.exclusive_system().label("0")) .with_system(empty.exclusive_system().label("1").after("0")) @@ -1348,5 +1477,44 @@ mod tests { || ambiguities.contains(&(Box::new("5"), Box::new("2"))) ); assert_eq!(ambiguities.len(), 6); + + let mut stage = SystemStage::parallel() + .with_system(empty.exclusive_system().label("0").before("1").before("3")) + .with_system(empty.exclusive_system().label("1").in_ambiguity_set("a")) + .with_system(empty.exclusive_system().label("2").after("1")) + .with_system(empty.exclusive_system().label("3").in_ambiguity_set("a")) + .with_system(empty.exclusive_system().label("4").after("3").before("5")) + .with_system(empty.exclusive_system().label("5").in_ambiguity_set("a")) + .with_system(empty.exclusive_system().label("6").after("2").after("5")); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start); + assert!( + ambiguities.contains(&(Box::new("2"), Box::new("3"))) + || ambiguities.contains(&(Box::new("3"), Box::new("2"))) + ); + assert!( + ambiguities.contains(&(Box::new("1"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("1"))) + ); + assert!( + ambiguities.contains(&(Box::new("2"), Box::new("4"))) + || ambiguities.contains(&(Box::new("4"), Box::new("2"))) + ); + assert!( + ambiguities.contains(&(Box::new("2"), Box::new("5"))) + || ambiguities.contains(&(Box::new("5"), Box::new("2"))) + ); + assert_eq!(ambiguities.len(), 4); + + let mut stage = SystemStage::parallel() + .with_system(empty.exclusive_system().label("0").in_ambiguity_set("a")) + .with_system(empty.exclusive_system().label("1").in_ambiguity_set("a")) + .with_system(empty.exclusive_system().label("2").in_ambiguity_set("a")) + .with_system(empty.exclusive_system().label("3").in_ambiguity_set("a")); + stage.initialize_systems(&mut world, &mut resources); + stage.rebuild_orders_and_dependencies(); + let ambiguities = find_ambiguities_labels(&stage.exclusive_at_start); + assert_eq!(ambiguities.len(), 0); } } diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index 09c5475dc0a9d..1335639b5db04 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,7 +1,8 @@ use std::{borrow::Cow, ptr::NonNull}; use crate::{ - BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor, ParallelSystemDescriptor, System, + BoxedAmbiguitySetLabel, BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemDescriptor, + ParallelSystemDescriptor, System, }; pub(super) trait SystemContainer { @@ -12,6 +13,7 @@ pub(super) trait SystemContainer { fn label(&self) -> &Option; fn before(&self) -> &[BoxedSystemLabel]; fn after(&self) -> &[BoxedSystemLabel]; + fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel]; fn is_compatible(&self, other: &Self) -> bool; } @@ -22,6 +24,7 @@ pub(super) struct ExclusiveSystemContainer { label: Option, before: Vec, after: Vec, + ambiguity_sets: Vec, } impl ExclusiveSystemContainer { @@ -33,6 +36,7 @@ impl ExclusiveSystemContainer { label: descriptor.label, before: descriptor.before, after: descriptor.after, + ambiguity_sets: descriptor.ambiguity_sets, } } @@ -74,6 +78,10 @@ impl SystemContainer for ExclusiveSystemContainer { &self.after } + fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel] { + &self.ambiguity_sets + } + fn is_compatible(&self, _: &Self) -> bool { false } @@ -87,6 +95,7 @@ pub struct ParallelSystemContainer { label: Option, before: Vec, after: Vec, + ambiguity_sets: Vec, } impl SystemContainer for ParallelSystemContainer { @@ -122,6 +131,10 @@ impl SystemContainer for ParallelSystemContainer { &self.after } + fn ambiguity_sets(&self) -> &[BoxedAmbiguitySetLabel] { + &self.ambiguity_sets + } + fn is_compatible(&self, other: &Self) -> bool { self.system() .component_access() @@ -146,6 +159,7 @@ impl ParallelSystemContainer { label: descriptor.label, before: descriptor.before, after: descriptor.after, + ambiguity_sets: descriptor.ambiguity_sets, } } diff --git a/crates/bevy_ecs/src/schedule/system_descriptor.rs b/crates/bevy_ecs/src/schedule/system_descriptor.rs index eac5f362b2241..205033737982b 100644 --- a/crates/bevy_ecs/src/schedule/system_descriptor.rs +++ b/crates/bevy_ecs/src/schedule/system_descriptor.rs @@ -1,6 +1,6 @@ use crate::{ - BoxedSystem, BoxedSystemLabel, ExclusiveSystem, ExclusiveSystemCoerced, ExclusiveSystemFn, - System, SystemLabel, + AmbiguitySetLabel, BoxedAmbiguitySetLabel, BoxedSystem, BoxedSystemLabel, ExclusiveSystem, + ExclusiveSystemCoerced, ExclusiveSystemFn, System, SystemLabel, }; /// Encapsulates a system and information on when it run in a `SystemStage`. @@ -82,6 +82,7 @@ pub struct ParallelSystemDescriptor { pub(crate) label: Option, pub(crate) before: Vec, pub(crate) after: Vec, + pub(crate) ambiguity_sets: Vec, } fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescriptor { @@ -90,6 +91,7 @@ fn new_parallel_descriptor(system: BoxedSystem<(), ()>) -> ParallelSystemDescrip label: None, before: Vec::new(), after: Vec::new(), + ambiguity_sets: Vec::new(), } } @@ -102,6 +104,10 @@ pub trait ParallelSystemDescriptorCoercion { /// Specifies that the system should run after the system with given label. fn after(self, label: impl SystemLabel) -> ParallelSystemDescriptor; + + /// Specifies that the system is exempt from execution order ambiguity detection + /// with other systems in this set. + fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor; } impl ParallelSystemDescriptorCoercion for ParallelSystemDescriptor { @@ -119,6 +125,11 @@ impl ParallelSystemDescriptorCoercion for ParallelSystemDescriptor { self.after.push(Box::new(label)); self } + + fn in_ambiguity_set(mut self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor { + self.ambiguity_sets.push(Box::new(set)); + self + } } impl ParallelSystemDescriptorCoercion for S @@ -136,6 +147,10 @@ where fn after(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(Box::new(self)).after(label) } + + fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor { + new_parallel_descriptor(Box::new(self)).in_ambiguity_set(set) + } } impl ParallelSystemDescriptorCoercion for BoxedSystem<(), ()> { @@ -150,6 +165,10 @@ impl ParallelSystemDescriptorCoercion for BoxedSystem<(), ()> { fn after(self, label: impl SystemLabel) -> ParallelSystemDescriptor { new_parallel_descriptor(self).after(label) } + + fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ParallelSystemDescriptor { + new_parallel_descriptor(self).in_ambiguity_set(set) + } } #[derive(Debug, Clone, Copy)] @@ -165,6 +184,7 @@ pub struct ExclusiveSystemDescriptor { pub(crate) label: Option, pub(crate) before: Vec, pub(crate) after: Vec, + pub(crate) ambiguity_sets: Vec, pub(crate) insertion_point: InsertionPoint, } @@ -174,6 +194,7 @@ fn new_exclusive_descriptor(system: Box) -> ExclusiveSystem label: None, before: Vec::new(), after: Vec::new(), + ambiguity_sets: Vec::new(), insertion_point: InsertionPoint::AtStart, } } @@ -188,6 +209,10 @@ pub trait ExclusiveSystemDescriptorCoercion { /// Specifies that the system should run after the system with given label. fn after(self, label: impl SystemLabel) -> ExclusiveSystemDescriptor; + /// Specifies that the system is exempt from execution order ambiguity detection + /// with other systems in this set. + fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ExclusiveSystemDescriptor; + /// Specifies that the system should run with other exclusive systems at the start of stage. fn at_start(self) -> ExclusiveSystemDescriptor; @@ -215,6 +240,11 @@ impl ExclusiveSystemDescriptorCoercion for ExclusiveSystemDescriptor { self } + fn in_ambiguity_set(mut self, set: impl AmbiguitySetLabel) -> ExclusiveSystemDescriptor { + self.ambiguity_sets.push(Box::new(set)); + self + } + fn at_start(mut self) -> ExclusiveSystemDescriptor { self.insertion_point = InsertionPoint::AtStart; self @@ -247,6 +277,10 @@ where new_exclusive_descriptor(Box::new(self)).after(label) } + fn in_ambiguity_set(self, set: impl AmbiguitySetLabel) -> ExclusiveSystemDescriptor { + new_exclusive_descriptor(Box::new(self)).in_ambiguity_set(set) + } + fn at_start(self) -> ExclusiveSystemDescriptor { new_exclusive_descriptor(Box::new(self)).at_start() }