From 5ecff1e2dc772a4780b6c1e6c2783a8f53095e48 Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Tue, 3 Dec 2024 21:25:43 -0600 Subject: [PATCH 1/8] turn apply_deferred into a ZST system --- crates/bevy_ecs/src/schedule/executor/mod.rs | 130 ++++++++++++++++--- 1 file changed, 114 insertions(+), 16 deletions(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 37fd9ff7246c8..f3629c82c159a 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -2,6 +2,9 @@ mod multi_threaded; mod simple; mod single_threaded; +use alloc::borrow::Cow; +use core::any::TypeId; + pub use self::{ multi_threaded::{MainThreadExecutor, MultiThreadedExecutor}, simple::SimpleExecutor, @@ -11,9 +14,13 @@ pub use self::{ use fixedbitset::FixedBitSet; use crate::{ - schedule::{BoxedCondition, NodeId}, - system::BoxedSystem, - world::World, + archetype::ArchetypeComponentId, + component::{ComponentId, Tick}, + prelude::{IntoSystemSet, SystemSet}, + query::Access, + schedule::{BoxedCondition, InternedSystemSet, NodeId, SystemTypeSet}, + system::{BoxedSystem, System, SystemIn}, + world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, World}, }; /// Types that can run a [`SystemSchedule`] on a [`World`]. @@ -100,32 +107,123 @@ impl SystemSchedule { } } -/// Instructs the executor to call [`System::apply_deferred`](crate::system::System::apply_deferred) -/// on the systems that have run but not applied their [`Deferred`](crate::system::Deferred) system parameters -/// (like [`Commands`](crate::prelude::Commands)) or other system buffers. +/// A special [`System`] that instructs the executor to call +/// [`System::apply_deferred`] on the systems that have run but not applied +/// their [`Deferred`] system parameters (like [`Commands`]) or other system buffers. /// /// ## Scheduling /// /// `apply_deferred` systems are scheduled *by default* /// - later in the same schedule run (for example, if a system with `Commands` param /// is scheduled in `Update`, all the changes will be visible in `PostUpdate`) -/// - between systems with dependencies if the dependency -/// [has deferred buffers](crate::system::System::has_deferred) -/// (if system `bar` directly or indirectly depends on `foo`, and `foo` uses `Commands` param, -/// changes to the world in `foo` will be visible in `bar`) +/// - between systems with dependencies if the dependency [has deferred buffers] +/// (if system `bar` directly or indirectly depends on `foo`, and `foo` uses +/// `Commands` param, changes to the world in `foo` will be visible in `bar`) /// /// ## Notes -/// - This function (currently) does nothing if it's called manually or wrapped inside a [`PipeSystem`](crate::system::PipeSystem). -/// - Modifying a [`Schedule`](super::Schedule) may change the order buffers are applied. +/// - This system (currently) does nothing if it's called manually or wrapped +/// inside a [`PipeSystem`]. +/// - Modifying a [`Schedule`] may change the order buffers are applied. +/// +/// [`System::apply_deferred`]: crate::system::System::apply_deferred +/// [`Deferred`]: crate::system::Deferred +/// [`Commands`]: crate::prelude::Commands +/// [has deferred buffers]: crate::system::System::has_deferred +/// [`PipeSystem`]: crate::system::PipeSystem +/// [`Schedule`]: super::Schedule #[doc(alias = "apply_system_buffers")] -#[allow(unused_variables)] -pub fn apply_deferred(world: &mut World) {} +#[allow(unused_variables, non_camel_case_types)] +pub struct apply_deferred; /// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_deferred`]. pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool { - use crate::system::IntoSystem; // deref to use `System::type_id` instead of `Any::type_id` - system.as_ref().type_id() == apply_deferred.system_type_id() + system.as_ref().type_id() == TypeId::of::() +} + +impl System for apply_deferred { + type In = (); + type Out = (); + + fn name(&self) -> Cow<'static, str> { + Cow::Borrowed("bevy_ecs::apply_deferred") + } + + fn component_access(&self) -> &Access { + // This system accesses no components. + const { &Access::new() } + } + + fn archetype_component_access(&self) -> &Access { + // This system accesses no archetype components. + const { &Access::new() } + } + + fn is_send(&self) -> bool { + false + } + + fn is_exclusive(&self) -> bool { + // This system is labeled exclusive because it is used by the system + // executor to find places where deferred commands should be applied. + true + } + + fn has_deferred(&self) -> bool { + // This system itself doesn't have any commands to apply, but when it + // is pulled from the schedule to be ran, the executor will apply + // deferred commands from other systems. + false + } + + unsafe fn run_unsafe( + &mut self, + _input: SystemIn<'_, Self>, + _world: UnsafeWorldCell, + ) -> Self::Out { + // This system does nothing on its own. The executor will apply deferred + // commands from other systems instead of running this system. + } + + fn run(&mut self, _input: SystemIn<'_, Self>, _world: &mut World) -> Self::Out { + // This system does nothing on its own. The executor will apply deferred + // commands from other systems instead of running this system. + } + + fn apply_deferred(&mut self, _world: &mut World) {} + + fn queue_deferred(&mut self, _world: DeferredWorld) {} + + unsafe fn validate_param_unsafe(&mut self, _world: UnsafeWorldCell) -> bool { + // This system is always valid to run because it doesn't do anything, + // and only used as a marker for the executor. + true + } + + fn initialize(&mut self, _world: &mut World) {} + + fn update_archetype_component_access(&mut self, _world: UnsafeWorldCell) {} + + fn check_change_tick(&mut self, _change_tick: Tick) {} + + fn default_system_sets(&self) -> Vec { + vec![SystemTypeSet::::new().intern()] + } + + fn get_last_run(&self) -> Tick { + // This system is never run, so it has no last run tick. + Tick::MAX + } + + fn set_last_run(&mut self, _last_run: Tick) {} +} + +impl IntoSystemSet<()> for apply_deferred { + type Set = SystemTypeSet; + + fn into_system_set(self) -> Self::Set { + SystemTypeSet::::new() + } } /// These functions hide the bottom of the callstack from `RUST_BACKTRACE=1` (assuming the default panic handler is used). From 7205c603915cb4c4ef222b8bb04084ff02fe1c0f Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Tue, 3 Dec 2024 21:51:50 -0600 Subject: [PATCH 2/8] elaborate on is_exclusive comment --- crates/bevy_ecs/src/schedule/executor/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index f3629c82c159a..d8aec0eed1a19 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -165,7 +165,8 @@ impl System for apply_deferred { fn is_exclusive(&self) -> bool { // This system is labeled exclusive because it is used by the system - // executor to find places where deferred commands should be applied. + // executor to find places where deferred commands should be applied, + // and commands can only be applied with exclusive access to the world. true } From 5163b1b627a6e2558e422768356a1e5c809c2a0c Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Tue, 3 Dec 2024 22:12:51 -0600 Subject: [PATCH 3/8] remove allowed unused_variables lint --- crates/bevy_ecs/src/schedule/executor/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index d8aec0eed1a19..4f7491ab44dde 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -132,7 +132,7 @@ impl SystemSchedule { /// [`PipeSystem`]: crate::system::PipeSystem /// [`Schedule`]: super::Schedule #[doc(alias = "apply_system_buffers")] -#[allow(unused_variables, non_camel_case_types)] +#[allow(non_camel_case_types)] pub struct apply_deferred; /// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_deferred`]. From 477eb0af1f1e7affafcfb4afc225b9d872f7dcf5 Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Tue, 3 Dec 2024 22:31:36 -0600 Subject: [PATCH 4/8] remove redundant doc link --- crates/bevy_ecs/src/schedule/executor/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 4f7491ab44dde..88062f88fa8ae 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -135,7 +135,7 @@ impl SystemSchedule { #[allow(non_camel_case_types)] pub struct apply_deferred; -/// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_deferred`]. +/// Returns `true` if the [`System`] is an instance of [`apply_deferred`]. pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool { // deref to use `System::type_id` instead of `Any::type_id` system.as_ref().type_id() == TypeId::of::() From 1dcb403fb9b513090e99a17e7bc17cc7047db91f Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Wed, 4 Dec 2024 18:22:24 -0600 Subject: [PATCH 5/8] rename to ApplyDeferred and add deprecated alias --- Cargo.toml | 2 +- crates/bevy_ecs/src/lib.rs | 5 +++-- crates/bevy_ecs/src/schedule/config.rs | 14 +++++++------- crates/bevy_ecs/src/schedule/executor/mod.rs | 17 +++++++++++------ crates/bevy_ecs/src/schedule/executor/simple.rs | 2 +- crates/bevy_ecs/src/schedule/graph/mod.rs | 4 ++-- crates/bevy_ecs/src/schedule/schedule.rs | 12 ++++++------ crates/bevy_ecs/src/system/commands/mod.rs | 7 ++++--- crates/bevy_ecs/src/system/function_system.rs | 2 +- crates/bevy_ecs/src/system/mod.rs | 4 ++-- crates/bevy_ecs/src/system/system_param.rs | 16 ++++++++-------- .../bevy_render/src/view/window/screenshot.rs | 2 +- crates/bevy_transform/src/commands.rs | 4 ++-- crates/bevy_ui/src/layout/mod.rs | 6 +++--- 14 files changed, 52 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e943f81f61d70..e60ce19bb7d18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1839,7 +1839,7 @@ wasm = false [package.metadata.example.apply_deferred] name = "Apply System Buffers" -description = "Show how to use `apply_deferred` system" +description = "Show how to use `ApplyDeferred` system" category = "ECS (Entity Component System)" wasm = false diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index fbf4645a192fc..3d33e7f367dc1 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -42,6 +42,7 @@ pub use bevy_ptr as ptr; /// /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { + #[expect(deprecated)] #[doc(hidden)] pub use crate::{ bundle::Bundle, @@ -53,8 +54,8 @@ pub mod prelude { query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without}, removal_detection::RemovedComponents, schedule::{ - apply_deferred, common_conditions::*, Condition, IntoSystemConfigs, IntoSystemSet, - IntoSystemSetConfigs, Schedule, Schedules, SystemSet, + apply_deferred, common_conditions::*, ApplyDeferred, Condition, IntoSystemConfigs, + IntoSystemSet, IntoSystemSetConfigs, Schedule, Schedules, SystemSet, }, system::{ Commands, Deferred, EntityCommand, EntityCommands, In, InMut, InRef, IntoSystem, Local, diff --git a/crates/bevy_ecs/src/schedule/config.rs b/crates/bevy_ecs/src/schedule/config.rs index 3faac82edb456..4c80d421d2193 100644 --- a/crates/bevy_ecs/src/schedule/config.rs +++ b/crates/bevy_ecs/src/schedule/config.rs @@ -293,7 +293,7 @@ where /// Runs before all systems in `set`. If `self` has any systems that produce [`Commands`](crate::system::Commands) /// or other [`Deferred`](crate::system::Deferred) operations, all systems in `set` will see their effect. /// - /// If automatically inserting [`apply_deferred`](crate::schedule::apply_deferred) like + /// If automatically inserting [`ApplyDeferred`](crate::schedule::ApplyDeferred) like /// this isn't desired, use [`before_ignore_deferred`](Self::before_ignore_deferred) instead. /// /// Calling [`.chain`](Self::chain) is often more convenient and ensures that all systems are added to the schedule. @@ -305,7 +305,7 @@ where /// Run after all systems in `set`. If `set` has any systems that produce [`Commands`](crate::system::Commands) /// or other [`Deferred`](crate::system::Deferred) operations, all systems in `self` will see their effect. /// - /// If automatically inserting [`apply_deferred`](crate::schedule::apply_deferred) like + /// If automatically inserting [`ApplyDeferred`](crate::schedule::ApplyDeferred) like /// this isn't desired, use [`after_ignore_deferred`](Self::after_ignore_deferred) instead. /// /// Calling [`.chain`](Self::chain) is often more convenient and ensures that all systems are added to the schedule. @@ -429,7 +429,7 @@ where /// /// Ordering constraints will be applied between the successive elements. /// - /// If the preceding node on a edge has deferred parameters, a [`apply_deferred`](crate::schedule::apply_deferred) + /// If the preceding node on a edge has deferred parameters, a [`ApplyDeferred`](crate::schedule::ApplyDeferred) /// will be inserted on the edge. If this behavior is not desired consider using /// [`chain_ignore_deferred`](Self::chain_ignore_deferred) instead. fn chain(self) -> SystemConfigs { @@ -440,7 +440,7 @@ where /// /// Ordering constraints will be applied between the successive elements. /// - /// Unlike [`chain`](Self::chain) this will **not** add [`apply_deferred`](crate::schedule::apply_deferred) on the edges. + /// Unlike [`chain`](Self::chain) this will **not** add [`ApplyDeferred`](crate::schedule::ApplyDeferred) on the edges. fn chain_ignore_deferred(self) -> SystemConfigs { self.into_configs().chain_ignore_deferred() } @@ -610,7 +610,7 @@ where /// Runs before all systems in `set`. If `self` has any systems that produce [`Commands`](crate::system::Commands) /// or other [`Deferred`](crate::system::Deferred) operations, all systems in `set` will see their effect. /// - /// If automatically inserting [`apply_deferred`](crate::schedule::apply_deferred) like + /// If automatically inserting [`ApplyDeferred`](crate::schedule::ApplyDeferred) like /// this isn't desired, use [`before_ignore_deferred`](Self::before_ignore_deferred) instead. fn before(self, set: impl IntoSystemSet) -> SystemSetConfigs { self.into_configs().before(set) @@ -619,7 +619,7 @@ where /// Runs before all systems in `set`. If `set` has any systems that produce [`Commands`](crate::system::Commands) /// or other [`Deferred`](crate::system::Deferred) operations, all systems in `self` will see their effect. /// - /// If automatically inserting [`apply_deferred`](crate::schedule::apply_deferred) like + /// If automatically inserting [`ApplyDeferred`](crate::schedule::ApplyDeferred) like /// this isn't desired, use [`after_ignore_deferred`](Self::after_ignore_deferred) instead. fn after(self, set: impl IntoSystemSet) -> SystemSetConfigs { self.into_configs().after(set) @@ -672,7 +672,7 @@ where /// /// Ordering constraints will be applied between the successive elements. /// - /// Unlike [`chain`](Self::chain) this will **not** add [`apply_deferred`](crate::schedule::apply_deferred) on the edges. + /// Unlike [`chain`](Self::chain) this will **not** add [`ApplyDeferred`](crate::schedule::ApplyDeferred) on the edges. fn chain_ignore_deferred(self) -> SystemSetConfigs { self.into_configs().chain_ignore_deferred() } diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 88062f88fa8ae..54505c77fcaf4 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -107,13 +107,18 @@ impl SystemSchedule { } } +/// See [`ApplyDeferred`]. +#[deprecated = "Use `ApplyDeferred` instead"] +#[expect(non_upper_case_globals)] +pub const apply_deferred: ApplyDeferred = ApplyDeferred; + /// A special [`System`] that instructs the executor to call /// [`System::apply_deferred`] on the systems that have run but not applied /// their [`Deferred`] system parameters (like [`Commands`]) or other system buffers. /// /// ## Scheduling /// -/// `apply_deferred` systems are scheduled *by default* +/// `ApplyDeferred` systems are scheduled *by default* /// - later in the same schedule run (for example, if a system with `Commands` param /// is scheduled in `Update`, all the changes will be visible in `PostUpdate`) /// - between systems with dependencies if the dependency [has deferred buffers] @@ -133,15 +138,15 @@ impl SystemSchedule { /// [`Schedule`]: super::Schedule #[doc(alias = "apply_system_buffers")] #[allow(non_camel_case_types)] -pub struct apply_deferred; +pub struct ApplyDeferred; -/// Returns `true` if the [`System`] is an instance of [`apply_deferred`]. +/// Returns `true` if the [`System`] is an instance of [`ApplyDeferred`]. pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool { // deref to use `System::type_id` instead of `Any::type_id` - system.as_ref().type_id() == TypeId::of::() + system.as_ref().type_id() == TypeId::of::() } -impl System for apply_deferred { +impl System for ApplyDeferred { type In = (); type Out = (); @@ -219,7 +224,7 @@ impl System for apply_deferred { fn set_last_run(&mut self, _last_run: Tick) {} } -impl IntoSystemSet<()> for apply_deferred { +impl IntoSystemSet<()> for ApplyDeferred { type Set = SystemTypeSet; fn into_system_set(self) -> Self::Set { diff --git a/crates/bevy_ecs/src/schedule/executor/simple.rs b/crates/bevy_ecs/src/schedule/executor/simple.rs index 508f1fbffd07a..9940bacced91b 100644 --- a/crates/bevy_ecs/src/schedule/executor/simple.rs +++ b/crates/bevy_ecs/src/schedule/executor/simple.rs @@ -145,7 +145,7 @@ fn evaluate_and_fold_conditions(conditions: &mut [BoxedCondition], world: &mut W #[cfg(test)] #[test] fn skip_automatic_sync_points() { - // Schedules automatically insert apply_deferred systems, but these should + // Schedules automatically insert ApplyDeferred systems, but these should // not be executed as they only serve as markers and are not initialized use crate::prelude::*; let mut sched = Schedule::default(); diff --git a/crates/bevy_ecs/src/schedule/graph/mod.rs b/crates/bevy_ecs/src/schedule/graph/mod.rs index 08c4951d201cf..553be0bc195a3 100644 --- a/crates/bevy_ecs/src/schedule/graph/mod.rs +++ b/crates/bevy_ecs/src/schedule/graph/mod.rs @@ -23,9 +23,9 @@ pub(crate) enum DependencyKind { Before, /// A node that should be succeeded. After, - /// A node that should be preceded and will **not** automatically insert an instance of `apply_deferred` on the edge. + /// A node that should be preceded and will **not** automatically insert an instance of `ApplyDeferred` on the edge. BeforeNoSync, - /// A node that should be succeeded and will **not** automatically insert an instance of `apply_deferred` on the edge. + /// A node that should be succeeded and will **not** automatically insert an instance of `ApplyDeferred` on the edge. AfterNoSync, } diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 6ce385bade128..85e89a04225c2 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -213,9 +213,9 @@ fn make_executor(kind: ExecutorKind) -> Box { #[derive(PartialEq)] pub enum Chain { /// Run nodes in order. If there are deferred parameters in preceding systems a - /// [`apply_deferred`] will be added on the edge. + /// [`ApplyDeferred`] will be added on the edge. Yes, - /// Run nodes in order. This will not add [`apply_deferred`] between nodes. + /// Run nodes in order. This will not add [`ApplyDeferred`] between nodes. YesIgnoreDeferred, /// Nodes are allowed to run in any order. No, @@ -367,7 +367,7 @@ impl Schedule { /// Set whether the schedule applies deferred system buffers on final time or not. This is a catch-all /// in case a system uses commands but was not explicitly ordered before an instance of - /// [`apply_deferred`]. By default this + /// [`ApplyDeferred`]. By default this /// setting is true, but may be disabled if needed. pub fn set_apply_final_deferred(&mut self, apply_final_deferred: bool) -> &mut Self { self.executor.set_apply_final_deferred(apply_final_deferred); @@ -1191,13 +1191,13 @@ impl ScheduleGraph { Ok(sync_point_graph) } - /// add an [`apply_deferred`] system with no config + /// add an [`ApplyDeferred`] system with no config fn add_auto_sync(&mut self) -> NodeId { let id = NodeId::System(self.systems.len()); self.systems .push(SystemNode::new(Box::new(IntoSystem::into_system( - apply_deferred, + ApplyDeferred, )))); self.system_conditions.push(Vec::new()); @@ -1998,7 +1998,7 @@ pub struct ScheduleBuildSettings { /// /// Defaults to [`LogLevel::Warn`]. pub hierarchy_detection: LogLevel, - /// Auto insert [`apply_deferred`] systems into the schedule, + /// Auto insert [`ApplyDeferred`] systems into the schedule, /// when there are [`Deferred`](crate::prelude::Deferred) /// in one system and there are ordering dependencies on that system. [`Commands`](crate::system::Commands) is one /// such deferred buffer. diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index aa5523b0bdbce..647dac20b51b5 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -29,7 +29,7 @@ pub use parallel_scope::*; /// /// Since each command requires exclusive access to the `World`, /// all queued commands are automatically applied in sequence -/// when the `apply_deferred` system runs (see [`apply_deferred`] documentation for more details). +/// when the `ApplyDeferred` system runs (see [`ApplyDeferred`] documentation for more details). /// /// Each command can be used to modify the [`World`] in arbitrary ways: /// * spawning or despawning entities @@ -43,7 +43,8 @@ pub use parallel_scope::*; /// /// # Usage /// -/// Add `mut commands: Commands` as a function argument to your system to get a copy of this struct that will be applied the next time a copy of [`apply_deferred`] runs. +/// Add `mut commands: Commands` as a function argument to your system to get a +/// copy of this struct that will be applied the next time a copy of [`ApplyDeferred`] runs. /// Commands are almost always used as a [`SystemParam`](crate::system::SystemParam). /// /// ``` @@ -75,7 +76,7 @@ pub use parallel_scope::*; /// # } /// ``` /// -/// [`apply_deferred`]: crate::schedule::apply_deferred +/// [`ApplyDeferred`]: crate::schedule::ApplyDeferred pub struct Commands<'w, 's> { queue: InternalQueue<'s>, entities: &'w Entities, diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 7c5806abbcd6a..cea8929ebb143 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -110,7 +110,7 @@ impl SystemMeta { } /// Marks the system as having deferred buffers like [`Commands`](`super::Commands`) - /// This lets the scheduler insert [`apply_deferred`](`crate::prelude::apply_deferred`) systems automatically. + /// This lets the scheduler insert [`ApplyDeferred`](`crate::prelude::ApplyDeferred`) systems automatically. #[inline] pub fn set_has_deferred(&mut self) { self.has_deferred = true; diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index 394e03c205ba3..b230535c0bf0b 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -323,7 +323,7 @@ mod tests { query::{Added, Changed, Or, With, Without}, removal_detection::RemovedComponents, schedule::{ - apply_deferred, common_conditions::resource_exists, Condition, IntoSystemConfigs, + common_conditions::resource_exists, ApplyDeferred, Condition, IntoSystemConfigs, Schedule, }, system::{ @@ -493,7 +493,7 @@ mod tests { let mut schedule = Schedule::default(); - schedule.add_systems((incr_e_on_flip, apply_deferred, World::clear_trackers).chain()); + schedule.add_systems((incr_e_on_flip, ApplyDeferred, World::clear_trackers).chain()); schedule.run(&mut world); assert_eq!(world.resource::().0, 1); diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 7519a1e30a089..2186e2b8a3d10 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -210,14 +210,14 @@ pub unsafe trait SystemParam: Sized { } /// Applies any deferred mutations stored in this [`SystemParam`]'s state. - /// This is used to apply [`Commands`] during [`apply_deferred`](crate::prelude::apply_deferred). + /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred). /// /// [`Commands`]: crate::prelude::Commands #[inline] #[allow(unused_variables)] fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {} - /// Queues any deferred mutations to be applied at the next [`apply_deferred`](crate::prelude::apply_deferred). + /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred). #[inline] #[allow(unused_variables)] fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {} @@ -1149,12 +1149,12 @@ unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> { pub trait SystemBuffer: FromWorld + Send + 'static { /// Applies any deferred mutations to the [`World`]. fn apply(&mut self, system_meta: &SystemMeta, world: &mut World); - /// Queues any deferred mutations to be applied at the next [`apply_deferred`](crate::prelude::apply_deferred). + /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred). fn queue(&mut self, _system_meta: &SystemMeta, _world: DeferredWorld) {} } /// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during -/// [`apply_deferred`](crate::schedule::apply_deferred). +/// [`ApplyDeferred`](crate::schedule::ApplyDeferred). /// This is used internally by [`Commands`] to defer `World` mutations. /// /// [`Commands`]: crate::system::Commands @@ -1197,7 +1197,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static { /// struct AlarmFlag(bool); /// /// impl AlarmFlag { -/// /// Sounds the alarm the next time buffers are applied via apply_deferred. +/// /// Sounds the alarm the next time buffers are applied via ApplyDeferred. /// pub fn flag(&mut self) { /// self.0 = true; /// } @@ -1205,7 +1205,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static { /// /// impl SystemBuffer for AlarmFlag { /// // When `AlarmFlag` is used in a system, this function will get -/// // called the next time buffers are applied via apply_deferred. +/// // called the next time buffers are applied via ApplyDeferred. /// fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) { /// if self.0 { /// world.resource_mut::().0 = true; @@ -2337,12 +2337,12 @@ trait DynParamState: Sync + Send { unsafe fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta); /// Applies any deferred mutations stored in this [`SystemParam`]'s state. - /// This is used to apply [`Commands`] during [`apply_deferred`](crate::prelude::apply_deferred). + /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred). /// /// [`Commands`]: crate::prelude::Commands fn apply(&mut self, system_meta: &SystemMeta, world: &mut World); - /// Queues any deferred mutations to be applied at the next [`apply_deferred`](crate::prelude::apply_deferred). + /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred). fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld); /// Refer to [`SystemParam::validate_param`]. diff --git a/crates/bevy_render/src/view/window/screenshot.rs b/crates/bevy_render/src/view/window/screenshot.rs index ad03ca0920937..7912931df3ba0 100644 --- a/crates/bevy_render/src/view/window/screenshot.rs +++ b/crates/bevy_render/src/view/window/screenshot.rs @@ -410,7 +410,7 @@ impl Plugin for ScreenshotPlugin { First, clear_screenshots .after(event_update_system) - .before(apply_deferred), + .before(ApplyDeferred), ) .add_systems(Update, trigger_screenshots) .register_type::() diff --git a/crates/bevy_transform/src/commands.rs b/crates/bevy_transform/src/commands.rs index 2860ddf381ca7..ff309174078a6 100644 --- a/crates/bevy_transform/src/commands.rs +++ b/crates/bevy_transform/src/commands.rs @@ -83,7 +83,7 @@ pub trait BuildChildrenTransformExt { /// /// Note that both the hierarchy and transform updates will only execute /// the next time commands are applied - /// (during [`apply_deferred`](bevy_ecs::schedule::apply_deferred)). + /// (during [`ApplyDeferred`](bevy_ecs::schedule::ApplyDeferred)). fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self; /// Make this entity parentless while preserving this entity's [`GlobalTransform`] @@ -94,7 +94,7 @@ pub trait BuildChildrenTransformExt { /// /// Note that both the hierarchy and transform updates will only execute /// the next time commands are applied - /// (during [`apply_deferred`](bevy_ecs::schedule::apply_deferred)). + /// (during [`ApplyDeferred`](bevy_ecs::schedule::ApplyDeferred)). fn remove_parent_in_place(&mut self) -> &mut Self; } impl BuildChildrenTransformExt for EntityCommands<'_> { diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 99d1f37693434..90a3250328a7e 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -461,7 +461,7 @@ mod tests { event::Events, prelude::{Commands, Component, In, Query, With}, query::Without, - schedule::{apply_deferred, IntoSystemConfigs, Schedule}, + schedule::{ApplyDeferred, IntoSystemConfigs, Schedule}, system::RunSystemOnce, world::World, }; @@ -527,7 +527,7 @@ mod tests { // UI is driven by calculated camera target info, so we need to run the camera system first bevy_render::camera::camera_system::, update_target_camera_system, - apply_deferred, + ApplyDeferred, ui_layout_system, sync_simple_transforms, propagate_transforms, @@ -1171,7 +1171,7 @@ mod tests { // UI is driven by calculated camera target info, so we need to run the camera system first bevy_render::camera::camera_system::, update_target_camera_system, - apply_deferred, + ApplyDeferred, ui_layout_system, ) .chain(), From 655b42b8c8071c982090e4158ffd788c58c883e7 Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Wed, 4 Dec 2024 18:26:07 -0600 Subject: [PATCH 6/8] elaborate on deprecation reason --- crates/bevy_ecs/src/schedule/executor/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 54505c77fcaf4..1988f32b6b241 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -108,7 +108,7 @@ impl SystemSchedule { } /// See [`ApplyDeferred`]. -#[deprecated = "Use `ApplyDeferred` instead"] +#[deprecated = "Use `ApplyDeferred` instead. This was previously a function but is now a marker struct System."] #[expect(non_upper_case_globals)] pub const apply_deferred: ApplyDeferred = ApplyDeferred; From 6deafb013371d2d4fc52962668f5374dd25020b1 Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Wed, 4 Dec 2024 18:45:17 -0600 Subject: [PATCH 7/8] remove allow lint --- crates/bevy_ecs/src/schedule/executor/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 1988f32b6b241..8787d90cda6d3 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -137,7 +137,6 @@ pub const apply_deferred: ApplyDeferred = ApplyDeferred; /// [`PipeSystem`]: crate::system::PipeSystem /// [`Schedule`]: super::Schedule #[doc(alias = "apply_system_buffers")] -#[allow(non_camel_case_types)] pub struct ApplyDeferred; /// Returns `true` if the [`System`] is an instance of [`ApplyDeferred`]. From 9ce41e9e8d6ff1cfa29b446a0e48af70c3dd117f Mon Sep 17 00:00:00 2001 From: Christian Hughes Date: Wed, 4 Dec 2024 18:47:26 -0600 Subject: [PATCH 8/8] document why ApplyDeferred is non-send --- crates/bevy_ecs/src/schedule/executor/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 8787d90cda6d3..09ae3c84cfa14 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -164,6 +164,10 @@ impl System for ApplyDeferred { } fn is_send(&self) -> bool { + // Although this system itself does nothing on its own, the system + // executor uses it to apply deferred commands. Commands must be allowed + // to access non-send resources, so this system must be non-send for + // scheduling purposes. false }