diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 4b9a71812f083..dc800ae99a70e 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -1,10 +1,9 @@ use crate::{CoreStage, Events, Plugin, PluginGroup, PluginGroupBuilder, StartupStage}; use bevy_ecs::{ component::{Component, ComponentDescriptor}, - prelude::{FromWorld, IntoExclusiveSystem}, - schedule::{ - IntoSystemDescriptor, RunOnce, Schedule, Stage, StageLabel, State, SystemSet, SystemStage, - }, + prelude::{ExclusiveSystem, FromWorld, IntoExclusiveSystem, IntoSystem, StageConfig, System}, + schedule::{RunOnce, Schedule, Stage, StageLabel, State, SystemSet, SystemStage}, + system::BoxedSystem, world::World, }; use bevy_utils::tracing::debug; @@ -50,7 +49,7 @@ impl Default for App { app.add_default_stages() .add_event::() - .add_system_to_stage(CoreStage::Last, World::clear_trackers.exclusive_system()); + .add_exclusive(World::clear_trackers.stage(CoreStage::Last)); #[cfg(feature = "bevy_ci_testing")] { @@ -203,85 +202,108 @@ impl App { /// App::new() /// .add_system(my_system); /// ``` - pub fn add_system(&mut self, system: impl IntoSystemDescriptor) -> &mut Self { - self.add_system_to_stage(CoreStage::Update, system) - } - - pub fn add_system_set(&mut self, system_set: SystemSet) -> &mut Self { - self.add_system_set_to_stage(CoreStage::Update, system_set) - } - - pub fn add_system_to_stage( - &mut self, - stage_label: impl StageLabel, - system: impl IntoSystemDescriptor, - ) -> &mut Self { - self.schedule.add_system_to_stage(stage_label, system); - self - } - - pub fn add_system_set_to_stage( - &mut self, - stage_label: impl StageLabel, - system_set: SystemSet, - ) -> &mut Self { - self.schedule - .add_system_set_to_stage(stage_label, system_set); + pub fn add_system(&mut self, system: impl IntoSystem<(), (), Params>) -> &mut Self { + let system = system.system(); + if system.config().startup { + let system = { + if system.config().stage.is_some() { + system + } else { + system.stage(StartupStage::Startup) + } + }; + self.schedule + .stage(CoreStage::Startup, |schedule: &mut Schedule| { + schedule.add_system(system) + }); + } else { + let system = { + if system.config().stage.is_some() { + system + } else { + system.stage(CoreStage::Update) + } + }; + self.schedule.add_system(system); + } self } - /// Adds a system that is run once at application startup - /// - /// Startup systems run exactly once BEFORE all other systems. These are generally used for - /// app initialization code (ex: adding entities and resources). - /// - /// * For adding a system that runs for every frame, see [`App::add_system`]. - /// * For adding a system to specific stage, see [`App::add_system_to_stage`]. - /// - /// ## Example - /// ``` - /// # use bevy_app::prelude::*; - /// # use bevy_ecs::prelude::*; - /// # - /// fn my_startup_system(_commands: Commands) { - /// println!("My startup system"); - /// } - /// - /// App::new() - /// .add_startup_system(my_startup_system); - /// ``` - pub fn add_startup_system( - &mut self, - system: impl IntoSystemDescriptor, - ) -> &mut Self { - self.add_startup_system_to_stage(StartupStage::Startup, system) - } - - pub fn add_startup_system_set(&mut self, system_set: SystemSet) -> &mut Self { - self.add_startup_system_set_to_stage(StartupStage::Startup, system_set) - } + pub fn add_system_set(&mut self, set: SystemSet) -> &mut Self { + fn ensure_no_conflicts(set: &SystemSet) { + if let Some(l) = set.systems + .iter() + .filter(|s| s.config().stage != set.config().stage) + .next() + .and_then(|s| s.config().stage.as_ref()) { + panic!("System set stage conflicts with internal exclusive system's stage: {:?}", l.as_ref()); + } + if let Some(l) = set.exclusive_systems + .iter() + .filter(|s| s.config().stage != set.config().stage) + .next() + .and_then(|s| s.config().stage.as_ref()) { + panic!("System set stage conflicts with internal exclusive system's stage: {:?}", l.as_ref()); + } + } - pub fn add_startup_system_to_stage( - &mut self, - stage_label: impl StageLabel, - system: impl IntoSystemDescriptor, - ) -> &mut Self { - self.schedule - .stage(CoreStage::Startup, |schedule: &mut Schedule| { - schedule.add_system_to_stage(stage_label, system) - }); + if set.config().startup { + let set = { + if set.config().stage.is_some() { + set + } else { + set.stage(StartupStage::Startup) + } + }; + ensure_no_conflicts(&set); + self.schedule + .stage(CoreStage::Startup, |schedule: &mut Schedule| { + schedule.add_system_set(set) + }); + } else { + let set = { + if set.config().stage.is_some() { + set + } else { + set.stage(CoreStage::Update) + } + }; + ensure_no_conflicts(&set); + self.schedule.add_system_set(set); + } self } - pub fn add_startup_system_set_to_stage( + pub fn add_exclusive( &mut self, - stage_label: impl StageLabel, - system_set: SystemSet, - ) -> &mut Self { - self.schedule - .stage(CoreStage::Startup, |schedule: &mut Schedule| { - schedule.add_system_set_to_stage(stage_label, system_set) - }); + system: impl IntoExclusiveSystem, + ) -> &mut Self + where + SystemType: ExclusiveSystem + StageConfig, + { + let system = system.exclusive_system(); + if system.config().startup { + let system = { + if system.config().stage.is_some() { + system + } else { + system.exclusive_system().stage(StartupStage::Startup) + } + }; + self.schedule + .stage(CoreStage::Startup, |schedule: &mut Schedule| { + schedule.add_exclusive(system) + }); + } else { + let system = { + if system.config().stage.is_some() { + system + } else { + system.exclusive_system().stage(CoreStage::Update) + } + }; + self.schedule.add_exclusive(system); + } self } @@ -307,7 +329,7 @@ impl App { T: Component + Debug + Clone + Eq + Hash, { self.insert_resource(State::new(initial)) - .add_system_set_to_stage(stage, State::::get_driver()) + .add_system_set(State::::get_driver().stage(stage)) } pub fn add_default_stages(&mut self) -> &mut Self { @@ -335,7 +357,7 @@ impl App { T: Component, { self.insert_resource(Events::::default()) - .add_system_to_stage(CoreStage::First, Events::::update_system) + .add_system(Events::::update_system.stage(CoreStage::First)) } /// Inserts a resource to the current [App] and overwrites any resource previously added of the same type. diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index d444cdee2d159..cb0d5f1de6b8e 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -3,7 +3,7 @@ use crate::{ RefChange, }; use bevy_app::{App, EventWriter, Events}; -use bevy_ecs::{system::ResMut, world::FromWorld}; +use bevy_ecs::{prelude::StageConfig, system::ResMut, world::FromWorld}; use bevy_utils::HashMap; use crossbeam_channel::Sender; use std::fmt::Debug; @@ -214,8 +214,8 @@ impl AddAsset for App { }; self.insert_resource(assets) - .add_system_to_stage(AssetStage::AssetEvents, Assets::::asset_event_system) - .add_system_to_stage(AssetStage::LoadAssets, update_asset_storage_system::) + .add_system(Assets::::asset_event_system.stage(AssetStage::AssetEvents)) + .add_system(update_asset_storage_system::.stage(AssetStage::LoadAssets)) .register_type::>() .add_event::>() } diff --git a/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs b/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs index 8224edd3893da..aa30833027b26 100644 --- a/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs +++ b/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs @@ -1,7 +1,10 @@ use crate::{Asset, Assets}; use bevy_app::prelude::*; use bevy_diagnostic::{Diagnostic, DiagnosticId, Diagnostics, MAX_DIAGNOSTIC_NAME_WIDTH}; -use bevy_ecs::system::{Res, ResMut}; +use bevy_ecs::{ + prelude::StartupConfig, + system::{Res, ResMut}, +}; /// Adds "asset count" diagnostic to an App pub struct AssetCountDiagnosticsPlugin { @@ -18,7 +21,7 @@ impl Default for AssetCountDiagnosticsPlugin { impl Plugin for AssetCountDiagnosticsPlugin { fn build(&self, app: &mut App) { - app.add_startup_system(Self::setup_system) + app.add_system(Self::setup_system.startup()) .add_system(Self::diagnostic_system); } } diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 0067c266ce981..42e3c30150726 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -27,7 +27,10 @@ pub use loader::*; pub use path::*; use bevy_app::{prelude::Plugin, App}; -use bevy_ecs::schedule::{StageLabel, SystemStage}; +use bevy_ecs::{ + prelude::StageConfig, + schedule::{StageLabel, SystemStage}, +}; use bevy_tasks::IoTaskPool; /// The names of asset stages in an App Schedule @@ -101,15 +104,12 @@ impl Plugin for AssetPlugin { SystemStage::parallel(), ) .register_type::() - .add_system_to_stage( - bevy_app::CoreStage::PreUpdate, - asset_server::free_unused_assets_system, - ); + .add_system(asset_server::free_unused_assets_system.stage(bevy_app::CoreStage::PreUpdate)); #[cfg(all( feature = "filesystem_watcher", all(not(target_arch = "wasm32"), not(target_os = "android")) ))] - app.add_system_to_stage(AssetStage::LoadAssets, io::filesystem_watcher_system); + app.add_system(io::filesystem_watcher_system.stage(AssetStage::LoadAssets)); } } diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index 5f44d68f9f40b..bbf39dcfb1b85 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -13,7 +13,7 @@ pub use audio_source::*; use bevy_app::prelude::*; use bevy_asset::AddAsset; -use bevy_ecs::system::IntoExclusiveSystem; +use bevy_ecs::{prelude::StageConfig, system::IntoExclusiveSystem}; /// Adds support for audio playback to an App #[derive(Default)] @@ -24,9 +24,10 @@ impl Plugin for AudioPlugin { app.init_non_send_resource::>() .add_asset::() .init_resource::>() - .add_system_to_stage( - CoreStage::PostUpdate, - play_queued_audio_system::.exclusive_system(), + .add_exclusive( + play_queued_audio_system:: + .exclusive_system() + .stage(CoreStage::PostUpdate), ); #[cfg(any(feature = "mp3", feature = "flac", feature = "wav", feature = "vorbis"))] diff --git a/crates/bevy_core/src/label.rs b/crates/bevy_core/src/label.rs index 6c99bc76d8eea..91456dab7e5ea 100644 --- a/crates/bevy_core/src/label.rs +++ b/crates/bevy_core/src/label.rs @@ -122,6 +122,7 @@ pub(crate) fn entity_labels_system( #[cfg(test)] mod tests { use bevy_ecs::{ + prelude::StageConfig, schedule::{Schedule, Stage, SystemStage}, world::World, }; @@ -133,7 +134,7 @@ mod tests { world.insert_resource(EntityLabels::default()); let mut schedule = Schedule::default(); schedule.add_stage("test", SystemStage::single_threaded()); - schedule.add_system_to_stage("test", entity_labels_system); + schedule.add_system(entity_labels_system.stage("test")); (world, schedule) } diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index 5af6bc88f297e..085eb6588f7ad 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -20,8 +20,8 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_ecs::{ entity::Entity, - schedule::{ExclusiveSystemDescriptorCoercion, SystemLabel}, - system::IntoExclusiveSystem, + prelude::{ScheduleConfig, StageConfig, StartupConfig}, + schedule::SystemLabel, }; use bevy_utils::HashSet; use std::ops::Range; @@ -58,12 +58,13 @@ impl Plugin for CorePlugin { .register_type::() // time system is added as an "exclusive system" to ensure it runs before other systems // in CoreStage::First - .add_system_to_stage( - CoreStage::First, - time_system.exclusive_system().label(CoreSystem::Time), + .add_exclusive(time_system.stage(CoreStage::First).label(CoreSystem::Time)) + .add_system( + entity_labels_system + .startup() + .stage(StartupStage::PostStartup), ) - .add_startup_system_to_stage(StartupStage::PostStartup, entity_labels_system) - .add_system_to_stage(CoreStage::PostUpdate, entity_labels_system); + .add_system(entity_labels_system.stage(CoreStage::PostUpdate)); register_rust_types(app); register_math_types(app); diff --git a/crates/bevy_core/src/time/fixed_timestep.rs b/crates/bevy_core/src/time/fixed_timestep.rs index 3655da70db419..67337ac5a71f4 100644 --- a/crates/bevy_core/src/time/fixed_timestep.rs +++ b/crates/bevy_core/src/time/fixed_timestep.rs @@ -4,7 +4,7 @@ use bevy_ecs::{ component::ComponentId, query::Access, schedule::ShouldRun, - system::{ConfigurableSystem, IntoSystem, Local, Res, ResMut, System, SystemId}, + system::{ConfigurableSystem, IntoSystem, Local, Res, ResMut, System, SystemConfig, SystemId}, world::World, }; use bevy_utils::HashMap; @@ -51,6 +51,7 @@ impl FixedTimesteps { pub struct FixedTimestep { state: State, internal_system: Box>, + config: SystemConfig, } impl Default for FixedTimestep { @@ -58,6 +59,7 @@ impl Default for FixedTimestep { Self { state: State::default(), internal_system: Box::new(Self::prepare_system.system()), + config: SystemConfig::default(), } } } @@ -197,4 +199,12 @@ impl System for FixedTimestep { fn check_change_tick(&mut self, change_tick: u32) { self.internal_system.check_change_tick(change_tick); } + + fn config(&self) -> &SystemConfig { + &self.config + } + + fn config_mut(&mut self) -> &mut SystemConfig { + &mut self.config + } } diff --git a/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs index add37dee3c556..56550576bf71a 100644 --- a/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs @@ -1,5 +1,6 @@ use bevy_app::{App, Plugin}; use bevy_ecs::{ + prelude::StartupConfig, system::{IntoExclusiveSystem, ResMut}, world::World, }; @@ -12,8 +13,8 @@ pub struct EntityCountDiagnosticsPlugin; impl Plugin for EntityCountDiagnosticsPlugin { fn build(&self, app: &mut App) { - app.add_startup_system(Self::setup_system) - .add_system(Self::diagnostic_system.exclusive_system()); + app.add_system(Self::setup_system.startup()) + .add_exclusive(Self::diagnostic_system.exclusive_system()); } } diff --git a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs index 2ff6f17af4f80..b90862b9b4f73 100644 --- a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs @@ -1,7 +1,10 @@ use crate::{Diagnostic, DiagnosticId, Diagnostics}; use bevy_app::prelude::*; use bevy_core::Time; -use bevy_ecs::system::{Res, ResMut}; +use bevy_ecs::{ + prelude::StartupConfig, + system::{Res, ResMut}, +}; /// Adds "frame time" diagnostic to an App, specifically "frame time", "fps" and "frame count" #[derive(Default)] @@ -13,7 +16,7 @@ pub struct FrameTimeDiagnosticsState { impl Plugin for FrameTimeDiagnosticsPlugin { fn build(&self, app: &mut bevy_app::App) { - app.add_startup_system(Self::setup_system) + app.add_system(Self::setup_system.startup()) .insert_resource(FrameTimeDiagnosticsState { frame_count: 0.0 }) .add_system(Self::diagnostic_system); } diff --git a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs index e4054b20b9884..8945bc26f3439 100644 --- a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs @@ -1,7 +1,10 @@ use super::{Diagnostic, DiagnosticId, Diagnostics}; use bevy_app::prelude::*; use bevy_core::{Time, Timer}; -use bevy_ecs::system::{Res, ResMut}; +use bevy_ecs::{ + prelude::StageConfig, + system::{Res, ResMut}, +}; use bevy_log::{debug, info}; use bevy_utils::Duration; @@ -36,9 +39,9 @@ impl Plugin for LogDiagnosticsPlugin { }); if self.debug { - app.add_system_to_stage(CoreStage::PostUpdate, Self::log_diagnostics_debug_system); + app.add_system(Self::log_diagnostics_debug_system.stage(CoreStage::PostUpdate)); } else { - app.add_system_to_stage(CoreStage::PostUpdate, Self::log_diagnostics_system); + app.add_system(Self::log_diagnostics_system.stage(CoreStage::PostUpdate)); } } } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index c51925b710569..5adb27b252898 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -24,13 +24,15 @@ pub mod prelude { event::{EventReader, EventWriter}, query::{Added, ChangeTrackers, Changed, Or, QueryState, With, Without}, schedule::{ - AmbiguitySetLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, - RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaLabel, RunCriteriaPiping, - Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage, + AmbiguitySetLabel, RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaLabel, + RunCriteriaPiping, Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, + SystemStage, }, system::{ - Commands, ConfigurableSystem, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem, - Local, NonSend, NonSendMut, Query, QuerySet, RemovedComponents, Res, ResMut, System, + AmbiguityConfig, Commands, ConfigurableSystem, ExclusiveConfig, ExclusiveSystem, In, + IntoChainSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend, NonSendMut, Query, + QuerySet, RemovedComponents, Res, ResMut, RunCriteraConfig, ScheduleConfig, + StageConfig, StartupConfig, System, SystemConfig, }, world::{FromWorld, Mut, World}, }; diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index a1c386446c5d0..bb9e66c10c52b 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -6,7 +6,6 @@ mod run_criteria; mod stage; mod state; mod system_container; -mod system_descriptor; mod system_set; pub use executor::*; @@ -17,12 +16,15 @@ pub use run_criteria::*; pub use stage::*; pub use state::*; pub use system_container::*; -pub use system_descriptor::*; pub use system_set::*; use std::fmt::Debug; -use crate::{system::System, world::World}; +use crate::{ + prelude::{ExclusiveSystem, IntoExclusiveSystem, IntoSystem}, + system::System, + world::World, +}; use bevy_utils::HashMap; #[derive(Default)] @@ -63,15 +65,6 @@ impl Schedule { self } - pub fn with_system_in_stage( - mut self, - stage_label: impl StageLabel, - system: impl IntoSystemDescriptor, - ) -> Self { - self.add_system_to_stage(stage_label, system); - self - } - pub fn set_run_criteria>( &mut self, system: S, @@ -138,11 +131,10 @@ impl Schedule { self } - pub fn add_system_to_stage( - &mut self, - stage_label: impl StageLabel, - system: impl IntoSystemDescriptor, - ) -> &mut Self { + pub fn add_system(&mut self, system: impl IntoSystem<(), (), Params>) -> &mut Self { + let system = system.system(); + let stage_label = system.config().stage.clone().expect("test"); + // Use a function instead of a closure to ensure that it is codegend inside bevy_ecs instead // of the game. Closures inherit generic parameters from their enclosing function. #[cold] @@ -154,20 +146,57 @@ impl Schedule { } let stage = self - .get_stage_mut::(&stage_label) + .get_stage_mut::(stage_label.as_ref()) .unwrap_or_else(move || stage_not_found(&stage_label)); stage.add_system(system); self } - pub fn add_system_set_to_stage( + pub fn add_system_set(&mut self, system_set: SystemSet) -> &mut Self { + let stage_label = system_set.config().stage.clone().expect("test"); + + // Use a function instead of a closure to ensure that it is codegend inside bevy_ecs instead + // of the game. Closures inherit generic parameters from their enclosing function. + #[cold] + fn stage_not_found(stage_label: &dyn Debug) -> ! { + panic!( + "Stage '{:?}' does not exist or is not a SystemStage", + stage_label + ) + } + + let stage = self + .get_stage_mut::(stage_label.as_ref()) + .unwrap_or_else(move || stage_not_found(&stage_label)); + stage.add_system_set(system_set); + self + } + + pub fn add_exclusive( &mut self, - stage_label: impl StageLabel, - system_set: SystemSet, - ) -> &mut Self { - self.stage(stage_label, |stage: &mut SystemStage| { - stage.add_system_set(system_set) - }) + system: impl IntoExclusiveSystem, + ) -> &mut Self + where + SystemType: ExclusiveSystem, + { + let system = system.exclusive_system(); + let stage_label = system.config().stage.clone().expect("test"); + + // Use a function instead of a closure to ensure that it is codegend inside bevy_ecs instead + // of the game. Closures inherit generic parameters from their enclosing function. + #[cold] + fn stage_not_found(stage_label: &dyn Debug) -> ! { + panic!( + "Stage '{:?}' does not exist or is not a SystemStage", + stage_label + ) + } + + let stage = self + .get_stage_mut::(stage_label.as_ref()) + .unwrap_or_else(move || stage_not_found(&stage_label)); + stage.add_exclusive(system); + self } pub fn stage &mut T>( diff --git a/crates/bevy_ecs/src/schedule/run_criteria.rs b/crates/bevy_ecs/src/schedule/run_criteria.rs index 56c43452d3e60..892920e51d211 100644 --- a/crates/bevy_ecs/src/schedule/run_criteria.rs +++ b/crates/bevy_ecs/src/schedule/run_criteria.rs @@ -3,7 +3,7 @@ use crate::{ component::ComponentId, query::Access, schedule::{BoxedRunCriteriaLabel, GraphNode, RunCriteriaLabel}, - system::{BoxedSystem, IntoSystem, System, SystemId}, + system::{BoxedSystem, IntoSystem, System, SystemConfig, SystemId}, world::World, }; use std::borrow::Cow; @@ -399,6 +399,7 @@ where pub struct RunOnce { ran: bool, system_id: SystemId, + system_config: SystemConfig, archetype_component_access: Access, component_access: Access, } @@ -408,6 +409,7 @@ impl Default for RunOnce { Self { ran: false, system_id: SystemId::new(), + system_config: SystemConfig::default(), archetype_component_access: Default::default(), component_access: Default::default(), } @@ -454,4 +456,12 @@ impl System for RunOnce { fn initialize(&mut self, _world: &mut World) {} fn check_change_tick(&mut self, _change_tick: u32) {} + + fn config(&self) -> &SystemConfig { + &self.system_config + } + + fn config_mut(&mut self) -> &mut SystemConfig { + &mut self.system_config + } } diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index 9d5dda4bdf385..75eddccbb9381 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -1,14 +1,14 @@ use crate::{ component::ComponentId, - prelude::IntoSystem, + prelude::*, schedule::{ graph_utils::{self, DependencyGraphError}, BoxedRunCriteria, BoxedRunCriteriaLabel, BoxedSystemLabel, DuplicateLabelStrategy, - ExclusiveSystemContainer, GraphNode, InsertionPoint, ParallelExecutor, - ParallelSystemContainer, ParallelSystemExecutor, RunCriteriaContainer, - RunCriteriaDescriptor, RunCriteriaDescriptorOrLabel, RunCriteriaInner, ShouldRun, - SingleThreadedExecutor, SystemContainer, SystemDescriptor, SystemSet, + GraphNode, ParallelExecutor, ParallelSystemContainer, ParallelSystemExecutor, + RunCriteriaContainer, RunCriteriaDescriptor, RunCriteriaDescriptorOrLabel, + RunCriteriaInner, ShouldRun, SingleThreadedExecutor, SystemSet, }, + system::{BoxedExclusiveSystem, BoxedSystem, InsertionPoint}, world::{World, WorldId}, }; use bevy_utils::{tracing::info, HashMap, HashSet}; @@ -16,7 +16,8 @@ use downcast_rs::{impl_downcast, Downcast}; use fixedbitset::FixedBitSet; use std::fmt::Debug; -use super::IntoSystemDescriptor; +use super::system_container::SystemContainer; +use super::ExclusiveSystemContainer; pub trait Stage: Downcast + Send + Sync { /// Runs the stage; this happens once per update. @@ -48,7 +49,7 @@ impl_downcast!(Stage); pub struct ReportExecutionOrderAmbiguities; /// Stores and executes systems. Execution order is not defined unless explicitly specified; -/// see `SystemDescriptor` documentation. +/// see [SystemConfig](crate::system::SystemConfig) documentation to configure which stage a system runs in. pub struct SystemStage { /// The WorldId this stage was last run on. world_id: Option, @@ -107,10 +108,19 @@ impl SystemStage { } } - pub fn single(system: impl IntoSystemDescriptor) -> Self { + pub fn single(system: impl IntoSystem<(), (), Params>) -> Self { Self::single_threaded().with_system(system) } + pub fn single_exclusive( + system: impl IntoExclusiveSystem, + ) -> Self + where + SystemType: ExclusiveSystem, + { + Self::single_threaded().with_exclusive(system) + } + pub fn single_threaded() -> Self { Self::new(Box::new(SingleThreadedExecutor::default())) } @@ -133,72 +143,107 @@ impl SystemStage { self.executor = executor; } - pub fn with_system(mut self, system: impl IntoSystemDescriptor) -> Self { + pub fn with_system(mut self, system: impl IntoSystem<(), (), Params>) -> Self { self.add_system(system); self } - pub fn add_system(&mut self, system: impl IntoSystemDescriptor) -> &mut Self { - self.add_system_inner(system.into_descriptor(), None); + pub fn with_exclusive( + mut self, + system: impl IntoExclusiveSystem, + ) -> Self + where + SystemType: ExclusiveSystem, + { + self.add_exclusive(system); + self + } + + pub fn add_system(&mut self, system: impl IntoSystem<(), (), Params>) -> &mut Self { + self.add_system_inner(Box::new(system.system()), None); + self + } + + pub fn add_boxed_system(&mut self, system: BoxedSystem<(), ()>) -> &mut Self { + self.add_system_inner(system, None); + self + } + + pub fn add_exclusive( + &mut self, + system: impl IntoExclusiveSystem, + ) -> &mut Self + where + SystemType: ExclusiveSystem, + { + self.add_exclusive_inner(Box::new(system.exclusive_system()), None); self } - fn add_system_inner(&mut self, system: SystemDescriptor, default_run_criteria: Option) { + pub fn add_boxed_exclusive_system(&mut self, system: BoxedExclusiveSystem) -> &mut Self { + self.add_exclusive_inner(system, None); + self + } + fn add_system_inner( + &mut self, + system: BoxedSystem<(), ()>, + default_run_criteria: Option, + ) { self.systems_modified = true; - match system { - SystemDescriptor::Exclusive(mut descriptor) => { - let insertion_point = descriptor.insertion_point; - let criteria = descriptor.run_criteria.take(); - let mut container = ExclusiveSystemContainer::from_descriptor(descriptor); - match criteria { - Some(RunCriteriaDescriptorOrLabel::Label(label)) => { - container.run_criteria_label = Some(label); - } - Some(RunCriteriaDescriptorOrLabel::Descriptor(criteria_descriptor)) => { - container.run_criteria_label = criteria_descriptor.label.clone(); - container.run_criteria_index = - Some(self.add_run_criteria_internal(criteria_descriptor)); - } - None => { - container.run_criteria_index = default_run_criteria; - } - } - match insertion_point { - InsertionPoint::AtStart => { - let index = self.exclusive_at_start.len(); - self.uninitialized_at_start.push(index); - self.exclusive_at_start.push(container); - } - InsertionPoint::BeforeCommands => { - let index = self.exclusive_before_commands.len(); - self.uninitialized_before_commands.push(index); - self.exclusive_before_commands.push(container); - } - InsertionPoint::AtEnd => { - let index = self.exclusive_at_end.len(); - self.uninitialized_at_end.push(index); - self.exclusive_at_end.push(container); - } - } + let mut container = ParallelSystemContainer::from_system(system); + match container.system_mut().config_mut().run_criteria.take() { + Some(RunCriteriaDescriptorOrLabel::Label(label)) => { + container.run_criteria_label = Some(label); } - SystemDescriptor::Parallel(mut descriptor) => { - let criteria = descriptor.run_criteria.take(); - let mut container = ParallelSystemContainer::from_descriptor(descriptor); - match criteria { - Some(RunCriteriaDescriptorOrLabel::Label(label)) => { - container.run_criteria_label = Some(label); - } - Some(RunCriteriaDescriptorOrLabel::Descriptor(criteria_descriptor)) => { - container.run_criteria_label = criteria_descriptor.label.clone(); - container.run_criteria_index = - Some(self.add_run_criteria_internal(criteria_descriptor)); - } - None => { - container.run_criteria_index = default_run_criteria; - } - } - self.uninitialized_parallel.push(self.parallel.len()); - self.parallel.push(container); + Some(RunCriteriaDescriptorOrLabel::Descriptor(criteria_descriptor)) => { + container.run_criteria_label = criteria_descriptor.label.clone(); + container.run_criteria_index = + Some(self.add_run_criteria_internal(criteria_descriptor)); + } + None => { + container.run_criteria_index = default_run_criteria; + } + } + self.uninitialized_parallel.push(self.parallel.len()); + self.parallel.push(container); + } + + fn add_exclusive_inner( + &mut self, + system: BoxedExclusiveSystem, + default_run_criteria: Option, + ) { + self.systems_modified = true; + let mut container = ExclusiveSystemContainer::from_system(system); + match container.system_mut().config_mut().run_criteria.take() { + Some(RunCriteriaDescriptorOrLabel::Label(label)) => { + container.run_criteria_label = Some(label); + } + Some(RunCriteriaDescriptorOrLabel::Descriptor(criteria_descriptor)) => { + container.run_criteria_label = criteria_descriptor.label.clone(); + container.run_criteria_index = + Some(self.add_run_criteria_internal(criteria_descriptor)); + } + None => { + container.run_criteria_index = default_run_criteria; + } + } + + match container.system_mut().config_mut().insertion_point { + InsertionPoint::AtStart => { + let index = self.exclusive_at_start.len(); + self.uninitialized_at_start.push(index); + self.exclusive_at_start.push(container); + } + InsertionPoint::BeforeCommands => { + let index = self.exclusive_before_commands.len(); + self.uninitialized_before_commands.push(index); + self.exclusive_before_commands.push(container); + } + InsertionPoint::AtEnd => { + let index = self.exclusive_at_end.len(); + self.uninitialized_at_end.push(index); + self.exclusive_at_end.push(container); } } } @@ -239,20 +284,31 @@ impl SystemStage { pub fn add_system_set(&mut self, system_set: SystemSet) -> &mut Self { self.systems_modified = true; - let (run_criteria, mut systems) = system_set.bake(); + let (run_criteria, mut systems, mut exclusive_systems) = system_set.bake(); let set_run_criteria_index = run_criteria.and_then(|criteria| { // validate that no systems have criteria for system in systems.iter_mut() { - if let Some(name) = match system { - SystemDescriptor::Exclusive(descriptor) => descriptor - .run_criteria - .is_some() - .then(|| descriptor.system.name()), - SystemDescriptor::Parallel(descriptor) => descriptor - .run_criteria - .is_some() - .then(|| descriptor.system.name()), - } { + if let Some(name) = system + .config() + .run_criteria + .is_some() + .then(|| system.name()) + { + panic!( + "The system {} has a run criteria, but its `SystemSet` also has a run \ + criteria. This is not supported. Consider moving the system into a \ + different `SystemSet` or calling `add_system()` instead.", + name + ) + } + } + for system in exclusive_systems.iter_mut() { + if let Some(name) = system + .config() + .run_criteria + .is_some() + .then(|| system.name()) + { panic!( "The system {} has a run criteria, but its `SystemSet` also has a run \ criteria. This is not supported. Consider moving the system into a \ @@ -267,18 +323,13 @@ impl SystemStage { } RunCriteriaDescriptorOrLabel::Label(label) => { for system in systems.iter_mut() { - match system { - SystemDescriptor::Exclusive(descriptor) => { - descriptor.run_criteria = - Some(RunCriteriaDescriptorOrLabel::Label(label.clone())) - } - SystemDescriptor::Parallel(descriptor) => { - descriptor.run_criteria = - Some(RunCriteriaDescriptorOrLabel::Label(label.clone())) - } - } + system.config_mut().run_criteria = + Some(RunCriteriaDescriptorOrLabel::Label(label.clone())) + } + for system in exclusive_systems.iter_mut() { + system.config_mut().run_criteria = + Some(RunCriteriaDescriptorOrLabel::Label(label.clone())) } - None } } @@ -286,6 +337,9 @@ impl SystemStage { for system in systems.drain(..) { self.add_system_inner(system, set_run_criteria_index); } + for system in exclusive_systems.drain(..) { + self.add_exclusive_inner(system, set_run_criteria_index); + } self } @@ -894,13 +948,15 @@ impl Stage for SystemStage { mod tests { use crate::{ entity::Entity, + prelude::{ + AmbiguityConfig, ExclusiveConfig, IntoExclusiveSystem, RunCriteraConfig, ScheduleConfig, + }, query::{ChangeTrackers, Changed}, schedule::{ - BoxedSystemLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion, - RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaPiping, ShouldRun, - SingleThreadedExecutor, Stage, SystemSet, SystemStage, + BoxedSystemLabel, RunCriteria, RunCriteriaDescriptorCoercion, RunCriteriaPiping, + ShouldRun, SingleThreadedExecutor, Stage, SystemSet, SystemStage, }, - system::{In, IntoExclusiveSystem, IntoSystem, Local, Query, ResMut}, + system::{In, IntoSystem, Local, Query, ResMut}, world::World, }; @@ -926,10 +982,10 @@ mod tests { let mut world = World::new(); world.insert_resource(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().at_start()) + .with_exclusive(make_exclusive(0).exclusive_system().at_start()) .with_system(make_parallel(1)) - .with_system(make_exclusive(2).exclusive_system().before_commands()) - .with_system(make_exclusive(3).exclusive_system().at_end()); + .with_exclusive(make_exclusive(2).exclusive_system().before_commands()) + .with_exclusive(make_exclusive(3).exclusive_system().at_end()); stage.run(&mut world); assert_eq!( *world.get_resource_mut::>().unwrap(), @@ -944,10 +1000,10 @@ mod tests { world.get_resource_mut::>().unwrap().clear(); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().before_commands()) - .with_system(make_exclusive(3).exclusive_system().at_end()) + .with_exclusive(make_exclusive(2).exclusive_system().before_commands()) + .with_exclusive(make_exclusive(3).exclusive_system().at_end()) .with_system(make_parallel(1)) - .with_system(make_exclusive(0).exclusive_system().at_start()); + .with_exclusive(make_exclusive(0).exclusive_system().at_start()); stage.run(&mut world); assert_eq!( *world.get_resource::>().unwrap(), @@ -962,10 +1018,10 @@ mod tests { world.get_resource_mut::>().unwrap().clear(); let mut stage = SystemStage::parallel() - .with_system(make_parallel(2).exclusive_system().before_commands()) - .with_system(make_parallel(3).exclusive_system().at_end()) + .with_exclusive(make_parallel(2).exclusive_system().before_commands()) + .with_exclusive(make_parallel(3).exclusive_system().at_end()) .with_system(make_parallel(1)) - .with_system(make_parallel(0).exclusive_system().at_start()); + .with_exclusive(make_parallel(0).exclusive_system().at_start()); stage.run(&mut world); assert_eq!( *world.get_resource::>().unwrap(), @@ -984,9 +1040,9 @@ mod tests { let mut world = World::new(); world.insert_resource(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_exclusive(make_exclusive(1).exclusive_system().label("1").after("0")) + .with_exclusive(make_exclusive(2).exclusive_system().after("1")) + .with_exclusive(make_exclusive(0).exclusive_system().label("0")); stage.run(&mut world); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world); @@ -1001,9 +1057,9 @@ mod tests { let mut world = World::new(); world.insert_resource(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_exclusive(make_exclusive(1).exclusive_system().label("1").before("2")) + .with_exclusive(make_exclusive(2).exclusive_system().label("2")) + .with_exclusive(make_exclusive(0).exclusive_system().before("1")); stage.run(&mut world); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world); @@ -1018,11 +1074,11 @@ mod tests { let mut world = World::new(); world.insert_resource(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_exclusive(make_exclusive(2).exclusive_system().label("2")) + .with_exclusive(make_exclusive(1).exclusive_system().after("0").before("2")) + .with_exclusive(make_exclusive(0).exclusive_system().label("0")) + .with_exclusive(make_exclusive(4).exclusive_system().label("4")) + .with_exclusive(make_exclusive(3).exclusive_system().after("2").before("4")); stage.run(&mut world); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world); @@ -1037,14 +1093,14 @@ mod tests { let mut world = World::new(); world.insert_resource(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system( + .with_exclusive( make_exclusive(1) .exclusive_system() .label("first") .after("0"), ) - .with_system(make_exclusive(2).exclusive_system().after("first")) - .with_system( + .with_exclusive(make_exclusive(2).exclusive_system().after("first")) + .with_exclusive( make_exclusive(0) .exclusive_system() .label("first") @@ -1060,11 +1116,11 @@ mod tests { world.get_resource_mut::>().unwrap().clear(); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().after("01").label("2")) - .with_system(make_exclusive(1).exclusive_system().label("01").after("0")) - .with_system(make_exclusive(0).exclusive_system().label("01").label("0")) - .with_system(make_exclusive(4).exclusive_system().label("4")) - .with_system(make_exclusive(3).exclusive_system().after("2").before("4")); + .with_exclusive(make_exclusive(2).exclusive_system().after("01").label("2")) + .with_exclusive(make_exclusive(1).exclusive_system().label("01").after("0")) + .with_exclusive(make_exclusive(0).exclusive_system().label("01").label("0")) + .with_exclusive(make_exclusive(4).exclusive_system().label("4")) + .with_exclusive(make_exclusive(3).exclusive_system().after("2").before("4")); stage.run(&mut world); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world); @@ -1075,16 +1131,16 @@ mod tests { world.get_resource_mut::>().unwrap().clear(); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().label("234").label("2")) - .with_system( + .with_exclusive(make_exclusive(2).exclusive_system().label("234").label("2")) + .with_exclusive( make_exclusive(1) .exclusive_system() .before("234") .after("0"), ) - .with_system(make_exclusive(0).exclusive_system().label("0")) - .with_system(make_exclusive(4).exclusive_system().label("234").label("4")) - .with_system( + .with_exclusive(make_exclusive(0).exclusive_system().label("0")) + .with_exclusive(make_exclusive(4).exclusive_system().label("234").label("4")) + .with_exclusive( make_exclusive(3) .exclusive_system() .label("234") @@ -1105,7 +1161,7 @@ mod tests { let mut world = World::new(); world.insert_resource(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system( + .with_exclusive( make_exclusive(2) .exclusive_system() .label("2") @@ -1113,7 +1169,7 @@ mod tests { .before("3") .before("3"), ) - .with_system( + .with_exclusive( make_exclusive(1) .exclusive_system() .label("1") @@ -1121,9 +1177,9 @@ mod tests { .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( + .with_exclusive(make_exclusive(0).exclusive_system().label("0").before("1")) + .with_exclusive(make_exclusive(4).exclusive_system().label("4").after("3")) + .with_exclusive( make_exclusive(3) .exclusive_system() .label("3") @@ -1144,14 +1200,14 @@ mod tests { let mut world = World::new(); world.insert_resource(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(2).exclusive_system().label("2")) + .with_exclusive(make_exclusive(2).exclusive_system().label("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_exclusive(make_exclusive(0).exclusive_system().label("0")) + .with_exclusive(make_exclusive(4).exclusive_system().label("4")) + .with_exclusive(make_exclusive(3).exclusive_system().after("2").before("4")), ) - .with_system(make_exclusive(1).exclusive_system().after("0").before("2")); + .with_exclusive(make_exclusive(1).exclusive_system().after("0").before("2")); stage.run(&mut world); stage.set_executor(Box::new(SingleThreadedExecutor::default())); stage.run(&mut world); @@ -1166,13 +1222,13 @@ mod tests { let mut world = World::new(); world.insert_resource(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().before("1")) + .with_exclusive(make_exclusive(0).exclusive_system().before("1")) .with_system_set( SystemSet::new() .with_run_criteria(every_other_time) - .with_system(make_exclusive(1).exclusive_system().label("1")), + .with_exclusive(make_exclusive(1).exclusive_system().label("1")), ) - .with_system(make_exclusive(2).exclusive_system().after("1")); + .with_exclusive(make_exclusive(2).exclusive_system().after("1")); stage.run(&mut world); stage.run(&mut world); stage.set_executor(Box::new(SingleThreadedExecutor::default())); @@ -1190,7 +1246,7 @@ mod tests { let mut world = World::new(); world.insert_resource(Vec::::new()); let mut stage = SystemStage::parallel() - .with_system(make_exclusive(0).exclusive_system().label("0").after("0")); + .with_exclusive(make_exclusive(0).exclusive_system().label("0").after("0")); stage.run(&mut world); } @@ -1200,8 +1256,8 @@ mod tests { let mut world = World::new(); world.insert_resource(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_exclusive(make_exclusive(0).exclusive_system().label("0").after("1")) + .with_exclusive(make_exclusive(1).exclusive_system().label("1").after("0")); stage.run(&mut world); } @@ -1211,9 +1267,9 @@ mod tests { let mut world = World::new(); world.insert_resource(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_exclusive(make_exclusive(0).exclusive_system().label("0")) + .with_exclusive(make_exclusive(1).exclusive_system().after("0").before("2")) + .with_exclusive(make_exclusive(2).exclusive_system().label("2").before("0")); stage.run(&mut world); } @@ -1840,26 +1896,26 @@ mod tests { 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")) - .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_exclusive(empty.label("0")) + .with_exclusive(empty.label("1").after("0")) + .with_exclusive(empty.label("2").after("1")) + .with_exclusive(empty.label("3").after("2")) + .with_exclusive(empty.label("4").after("3")) + .with_exclusive(empty.label("5").after("4")) + .with_exclusive(empty.label("6").after("5")) + .with_exclusive(empty.label("7").after("6")); stage.initialize_systems(&mut world); 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_exclusive(empty.label("0").before("1").before("3")) + .with_exclusive(empty.label("1")) + .with_exclusive(empty.label("2").after("1")) + .with_exclusive(empty.label("3")) + .with_exclusive(empty.label("4").after("3").before("5")) + .with_exclusive(empty.label("5")) + .with_exclusive(empty.label("6").after("2").after("5")); stage.initialize_systems(&mut world); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_first_labels(&stage.exclusive_at_start); @@ -1890,13 +1946,13 @@ mod tests { 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")); + .with_exclusive(empty.label("0").before("1").before("3")) + .with_exclusive(empty.label("1").in_ambiguity_set("a")) + .with_exclusive(empty.label("2").after("1")) + .with_exclusive(empty.label("3").in_ambiguity_set("a")) + .with_exclusive(empty.label("4").after("3").before("5")) + .with_exclusive(empty.label("5").in_ambiguity_set("a")) + .with_exclusive(empty.label("6").after("2").after("5")); stage.initialize_systems(&mut world); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_first_labels(&stage.exclusive_at_start); @@ -1919,10 +1975,10 @@ mod tests { 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")); + .with_exclusive(empty.label("0").in_ambiguity_set("a")) + .with_exclusive(empty.label("1").in_ambiguity_set("a")) + .with_exclusive(empty.label("2").in_ambiguity_set("a")) + .with_exclusive(empty.label("3").in_ambiguity_set("a")); stage.initialize_systems(&mut world); stage.rebuild_orders_and_dependencies(); let ambiguities = find_ambiguities_first_labels(&stage.exclusive_at_start); diff --git a/crates/bevy_ecs/src/schedule/state.rs b/crates/bevy_ecs/src/schedule/state.rs index c18b6fecdb202..777afc10e53bd 100644 --- a/crates/bevy_ecs/src/schedule/state.rs +++ b/crates/bevy_ecs/src/schedule/state.rs @@ -4,7 +4,7 @@ use crate::{ RunCriteriaDescriptor, RunCriteriaDescriptorCoercion, RunCriteriaLabel, ShouldRun, SystemSet, }, - system::{ConfigurableSystem, In, IntoChainSystem, Local, Res, ResMut}, + system::{ConfigurableSystem, In, IntoChainSystem, Local, Res, ResMut, RunCriteraConfig}, }; use std::{any::TypeId, fmt::Debug, hash::Hash}; use thiserror::Error; diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index 68e493da714b5..db07eddc83d91 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,11 +1,8 @@ use crate::{ component::ComponentId, query::Access, - schedule::{ - BoxedAmbiguitySetLabel, BoxedRunCriteriaLabel, BoxedSystemLabel, ExclusiveSystemDescriptor, - GraphNode, ParallelSystemDescriptor, - }, - system::{ExclusiveSystem, System}, + schedule::{BoxedAmbiguitySetLabel, BoxedRunCriteriaLabel, BoxedSystemLabel, GraphNode}, + system::{BoxedExclusiveSystem, BoxedSystem, ExclusiveSystem, System}, }; use std::{borrow::Cow, cell::UnsafeCell}; @@ -25,27 +22,19 @@ pub trait SystemContainer: GraphNode