Turn apply_deferred into a ZST System (#16642)

# Objective

- Required by #16622 due to differing implementations of `System` by
`FunctionSystem` and `ExclusiveFunctionSystem`.
- Optimize the memory usage of instances of `apply_deferred` in system
schedules.

## Solution

By changing `apply_deferred` from being an ordinary system that ends up
as an `ExclusiveFunctionSystem`, and instead into a ZST struct that
implements `System` manually, we save ~320 bytes per instance of
`apply_deferred` in any schedule.

## Testing

- All current tests pass.

---

## Migration Guide

- If you were previously calling the special `apply_deferred` system via
`apply_deferred(world)`, don't.
This commit is contained in:
Christian Hughes 2024-12-05 12:14:05 -06:00 committed by GitHub
parent 67bd2b00e1
commit f87b9fe20c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 166 additions and 57 deletions

View file

@ -1839,7 +1839,7 @@ wasm = false
[package.metadata.example.apply_deferred] [package.metadata.example.apply_deferred]
name = "Apply System Buffers" name = "Apply System Buffers"
description = "Show how to use `apply_deferred` system" description = "Show how to use `ApplyDeferred` system"
category = "ECS (Entity Component System)" category = "ECS (Entity Component System)"
wasm = false wasm = false

View file

@ -42,6 +42,7 @@ pub use bevy_ptr as ptr;
/// ///
/// This includes the most common types in this crate, re-exported for your convenience. /// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude { pub mod prelude {
#[expect(deprecated)]
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
bundle::Bundle, bundle::Bundle,
@ -53,8 +54,8 @@ pub mod prelude {
query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without}, query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without},
removal_detection::RemovedComponents, removal_detection::RemovedComponents,
schedule::{ schedule::{
apply_deferred, common_conditions::*, Condition, IntoSystemConfigs, IntoSystemSet, apply_deferred, common_conditions::*, ApplyDeferred, Condition, IntoSystemConfigs,
IntoSystemSetConfigs, Schedule, Schedules, SystemSet, IntoSystemSet, IntoSystemSetConfigs, Schedule, Schedules, SystemSet,
}, },
system::{ system::{
Commands, Deferred, EntityCommand, EntityCommands, In, InMut, InRef, IntoSystem, Local, Commands, Deferred, EntityCommand, EntityCommands, In, InMut, InRef, IntoSystem, Local,

View file

@ -293,7 +293,7 @@ where
/// Runs before all systems in `set`. If `self` has any systems that produce [`Commands`](crate::system::Commands) /// 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. /// 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. /// 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. /// 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) /// 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. /// 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. /// 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. /// 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. /// 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 /// will be inserted on the edge. If this behavior is not desired consider using
/// [`chain_ignore_deferred`](Self::chain_ignore_deferred) instead. /// [`chain_ignore_deferred`](Self::chain_ignore_deferred) instead.
fn chain(self) -> SystemConfigs { fn chain(self) -> SystemConfigs {
@ -440,7 +440,7 @@ where
/// ///
/// Ordering constraints will be applied between the successive elements. /// 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 { fn chain_ignore_deferred(self) -> SystemConfigs {
self.into_configs().chain_ignore_deferred() 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) /// 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. /// 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. /// this isn't desired, use [`before_ignore_deferred`](Self::before_ignore_deferred) instead.
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs { fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs {
self.into_configs().before(set) 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) /// 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. /// 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. /// this isn't desired, use [`after_ignore_deferred`](Self::after_ignore_deferred) instead.
fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs { fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs {
self.into_configs().after(set) self.into_configs().after(set)
@ -672,7 +672,7 @@ where
/// ///
/// Ordering constraints will be applied between the successive elements. /// 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 { fn chain_ignore_deferred(self) -> SystemSetConfigs {
self.into_configs().chain_ignore_deferred() self.into_configs().chain_ignore_deferred()
} }

View file

@ -2,6 +2,9 @@ mod multi_threaded;
mod simple; mod simple;
mod single_threaded; mod single_threaded;
use alloc::borrow::Cow;
use core::any::TypeId;
pub use self::{ pub use self::{
multi_threaded::{MainThreadExecutor, MultiThreadedExecutor}, multi_threaded::{MainThreadExecutor, MultiThreadedExecutor},
simple::SimpleExecutor, simple::SimpleExecutor,
@ -11,9 +14,13 @@ pub use self::{
use fixedbitset::FixedBitSet; use fixedbitset::FixedBitSet;
use crate::{ use crate::{
schedule::{BoxedCondition, NodeId}, archetype::ArchetypeComponentId,
system::BoxedSystem, component::{ComponentId, Tick},
world::World, 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`]. /// Types that can run a [`SystemSchedule`] on a [`World`].
@ -100,32 +107,132 @@ impl SystemSchedule {
} }
} }
/// Instructs the executor to call [`System::apply_deferred`](crate::system::System::apply_deferred) /// See [`ApplyDeferred`].
/// on the systems that have run but not applied their [`Deferred`](crate::system::Deferred) system parameters #[deprecated = "Use `ApplyDeferred` instead. This was previously a function but is now a marker struct System."]
/// (like [`Commands`](crate::prelude::Commands)) or other system buffers. #[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 /// ## 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 /// - 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`) /// is scheduled in `Update`, all the changes will be visible in `PostUpdate`)
/// - between systems with dependencies if the dependency /// - between systems with dependencies if the dependency [has deferred buffers]
/// [has deferred buffers](crate::system::System::has_deferred) /// (if system `bar` directly or indirectly depends on `foo`, and `foo` uses
/// (if system `bar` directly or indirectly depends on `foo`, and `foo` uses `Commands` param, /// `Commands` param, changes to the world in `foo` will be visible in `bar`)
/// changes to the world in `foo` will be visible in `bar`)
/// ///
/// ## Notes /// ## Notes
/// - This function (currently) does nothing if it's called manually or wrapped inside a [`PipeSystem`](crate::system::PipeSystem). /// - This system (currently) does nothing if it's called manually or wrapped
/// - Modifying a [`Schedule`](super::Schedule) may change the order buffers are applied. /// 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")] #[doc(alias = "apply_system_buffers")]
#[allow(unused_variables)] pub struct ApplyDeferred;
pub fn apply_deferred(world: &mut World) {}
/// Returns `true` if the [`System`](crate::system::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 { pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool {
use crate::system::IntoSystem;
// deref to use `System::type_id` instead of `Any::type_id` // 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::<ApplyDeferred>()
}
impl System for ApplyDeferred {
type In = ();
type Out = ();
fn name(&self) -> Cow<'static, str> {
Cow::Borrowed("bevy_ecs::apply_deferred")
}
fn component_access(&self) -> &Access<ComponentId> {
// This system accesses no components.
const { &Access::new() }
}
fn archetype_component_access(&self) -> &Access<ArchetypeComponentId> {
// This system accesses no archetype components.
const { &Access::new() }
}
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
}
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,
// and commands can only be applied with exclusive access to the world.
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<InternedSystemSet> {
vec![SystemTypeSet::<Self>::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 ApplyDeferred {
type Set = SystemTypeSet<Self>;
fn into_system_set(self) -> Self::Set {
SystemTypeSet::<Self>::new()
}
} }
/// These functions hide the bottom of the callstack from `RUST_BACKTRACE=1` (assuming the default panic handler is used). /// These functions hide the bottom of the callstack from `RUST_BACKTRACE=1` (assuming the default panic handler is used).

View file

@ -145,7 +145,7 @@ fn evaluate_and_fold_conditions(conditions: &mut [BoxedCondition], world: &mut W
#[cfg(test)] #[cfg(test)]
#[test] #[test]
fn skip_automatic_sync_points() { 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 // not be executed as they only serve as markers and are not initialized
use crate::prelude::*; use crate::prelude::*;
let mut sched = Schedule::default(); let mut sched = Schedule::default();

View file

@ -23,9 +23,9 @@ pub(crate) enum DependencyKind {
Before, Before,
/// A node that should be succeeded. /// A node that should be succeeded.
After, 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, 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, AfterNoSync,
} }

View file

@ -213,9 +213,9 @@ fn make_executor(kind: ExecutorKind) -> Box<dyn SystemExecutor> {
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum Chain { pub enum Chain {
/// Run nodes in order. If there are deferred parameters in preceding systems a /// 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, 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, YesIgnoreDeferred,
/// Nodes are allowed to run in any order. /// Nodes are allowed to run in any order.
No, 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 /// 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 /// 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. /// setting is true, but may be disabled if needed.
pub fn set_apply_final_deferred(&mut self, apply_final_deferred: bool) -> &mut Self { pub fn set_apply_final_deferred(&mut self, apply_final_deferred: bool) -> &mut Self {
self.executor.set_apply_final_deferred(apply_final_deferred); self.executor.set_apply_final_deferred(apply_final_deferred);
@ -1191,13 +1191,13 @@ impl ScheduleGraph {
Ok(sync_point_graph) 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 { fn add_auto_sync(&mut self) -> NodeId {
let id = NodeId::System(self.systems.len()); let id = NodeId::System(self.systems.len());
self.systems self.systems
.push(SystemNode::new(Box::new(IntoSystem::into_system( .push(SystemNode::new(Box::new(IntoSystem::into_system(
apply_deferred, ApplyDeferred,
)))); ))));
self.system_conditions.push(Vec::new()); self.system_conditions.push(Vec::new());
@ -1998,7 +1998,7 @@ pub struct ScheduleBuildSettings {
/// ///
/// Defaults to [`LogLevel::Warn`]. /// Defaults to [`LogLevel::Warn`].
pub hierarchy_detection: LogLevel, 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) /// when there are [`Deferred`](crate::prelude::Deferred)
/// in one system and there are ordering dependencies on that system. [`Commands`](crate::system::Commands) is one /// in one system and there are ordering dependencies on that system. [`Commands`](crate::system::Commands) is one
/// such deferred buffer. /// such deferred buffer.

View file

@ -29,7 +29,7 @@ pub use parallel_scope::*;
/// ///
/// Since each command requires exclusive access to the `World`, /// Since each command requires exclusive access to the `World`,
/// all queued commands are automatically applied in sequence /// 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: /// Each command can be used to modify the [`World`] in arbitrary ways:
/// * spawning or despawning entities /// * spawning or despawning entities
@ -43,7 +43,8 @@ pub use parallel_scope::*;
/// ///
/// # Usage /// # 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). /// 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> { pub struct Commands<'w, 's> {
queue: InternalQueue<'s>, queue: InternalQueue<'s>,
entities: &'w Entities, entities: &'w Entities,

View file

@ -110,7 +110,7 @@ impl SystemMeta {
} }
/// Marks the system as having deferred buffers like [`Commands`](`super::Commands`) /// 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] #[inline]
pub fn set_has_deferred(&mut self) { pub fn set_has_deferred(&mut self) {
self.has_deferred = true; self.has_deferred = true;

View file

@ -323,7 +323,7 @@ mod tests {
query::{Added, Changed, Or, With, Without}, query::{Added, Changed, Or, With, Without},
removal_detection::RemovedComponents, removal_detection::RemovedComponents,
schedule::{ schedule::{
apply_deferred, common_conditions::resource_exists, Condition, IntoSystemConfigs, common_conditions::resource_exists, ApplyDeferred, Condition, IntoSystemConfigs,
Schedule, Schedule,
}, },
system::{ system::{
@ -493,7 +493,7 @@ mod tests {
let mut schedule = Schedule::default(); 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); schedule.run(&mut world);
assert_eq!(world.resource::<Added>().0, 1); assert_eq!(world.resource::<Added>().0, 1);

View file

@ -210,14 +210,14 @@ pub unsafe trait SystemParam: Sized {
} }
/// Applies any deferred mutations stored in this [`SystemParam`]'s state. /// 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 /// [`Commands`]: crate::prelude::Commands
#[inline] #[inline]
#[allow(unused_variables)] #[allow(unused_variables)]
fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {} 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] #[inline]
#[allow(unused_variables)] #[allow(unused_variables)]
fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {} 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 { pub trait SystemBuffer: FromWorld + Send + 'static {
/// Applies any deferred mutations to the [`World`]. /// Applies any deferred mutations to the [`World`].
fn apply(&mut self, system_meta: &SystemMeta, world: &mut 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) {} fn queue(&mut self, _system_meta: &SystemMeta, _world: DeferredWorld) {}
} }
/// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during /// 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. /// This is used internally by [`Commands`] to defer `World` mutations.
/// ///
/// [`Commands`]: crate::system::Commands /// [`Commands`]: crate::system::Commands
@ -1197,7 +1197,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static {
/// struct AlarmFlag(bool); /// struct AlarmFlag(bool);
/// ///
/// impl AlarmFlag { /// 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) { /// pub fn flag(&mut self) {
/// self.0 = true; /// self.0 = true;
/// } /// }
@ -1205,7 +1205,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static {
/// ///
/// impl SystemBuffer for AlarmFlag { /// impl SystemBuffer for AlarmFlag {
/// // When `AlarmFlag` is used in a system, this function will get /// // 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) { /// fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
/// if self.0 { /// if self.0 {
/// world.resource_mut::<Alarm>().0 = true; /// world.resource_mut::<Alarm>().0 = true;
@ -2337,12 +2337,12 @@ trait DynParamState: Sync + Send {
unsafe fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta); unsafe fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta);
/// Applies any deferred mutations stored in this [`SystemParam`]'s state. /// 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 /// [`Commands`]: crate::prelude::Commands
fn apply(&mut self, system_meta: &SystemMeta, world: &mut 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); fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld);
/// Refer to [`SystemParam::validate_param`]. /// Refer to [`SystemParam::validate_param`].

View file

@ -410,7 +410,7 @@ impl Plugin for ScreenshotPlugin {
First, First,
clear_screenshots clear_screenshots
.after(event_update_system) .after(event_update_system)
.before(apply_deferred), .before(ApplyDeferred),
) )
.add_systems(Update, trigger_screenshots) .add_systems(Update, trigger_screenshots)
.register_type::<Screenshot>() .register_type::<Screenshot>()

View file

@ -83,7 +83,7 @@ pub trait BuildChildrenTransformExt {
/// ///
/// Note that both the hierarchy and transform updates will only execute /// Note that both the hierarchy and transform updates will only execute
/// the next time commands are applied /// 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; fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self;
/// Make this entity parentless while preserving this entity's [`GlobalTransform`] /// 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 /// Note that both the hierarchy and transform updates will only execute
/// the next time commands are applied /// 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; fn remove_parent_in_place(&mut self) -> &mut Self;
} }
impl BuildChildrenTransformExt for EntityCommands<'_> { impl BuildChildrenTransformExt for EntityCommands<'_> {

View file

@ -461,7 +461,7 @@ mod tests {
event::Events, event::Events,
prelude::{Commands, Component, In, Query, With}, prelude::{Commands, Component, In, Query, With},
query::Without, query::Without,
schedule::{apply_deferred, IntoSystemConfigs, Schedule}, schedule::{ApplyDeferred, IntoSystemConfigs, Schedule},
system::RunSystemOnce, system::RunSystemOnce,
world::World, 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 // UI is driven by calculated camera target info, so we need to run the camera system first
bevy_render::camera::camera_system::<OrthographicProjection>, bevy_render::camera::camera_system::<OrthographicProjection>,
update_target_camera_system, update_target_camera_system,
apply_deferred, ApplyDeferred,
ui_layout_system, ui_layout_system,
sync_simple_transforms, sync_simple_transforms,
propagate_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 // UI is driven by calculated camera target info, so we need to run the camera system first
bevy_render::camera::camera_system::<OrthographicProjection>, bevy_render::camera::camera_system::<OrthographicProjection>,
update_target_camera_system, update_target_camera_system,
apply_deferred, ApplyDeferred,
ui_layout_system, ui_layout_system,
) )
.chain(), .chain(),