Rename apply_system_buffers to apply_deferred (#8726)

# Objective

- `apply_system_buffers` is an unhelpful name: it introduces a new
internal-only concept
- this is particularly rough for beginners as reasoning about how
commands work is a critical stumbling block

## Solution

- rename `apply_system_buffers` to the more descriptive `apply_deferred`
- rename related fields, arguments and methods in the internals fo
bevy_ecs for consistency
- update the docs


## Changelog

`apply_system_buffers` has been renamed to `apply_deferred`, to more
clearly communicate its intent and relation to `Deferred` system
parameters like `Commands`.

## Migration Guide

- `apply_system_buffers` has been renamed to `apply_deferred`
- the `apply_system_buffers` method on the `System` trait has been
renamed to `apply_deferred`
- the `is_apply_system_buffers` function has been replaced by
`is_apply_deferred`
- `Executor::set_apply_final_buffers` is now
`Executor::set_apply_final_deferred`
- `Schedule::apply_system_buffers` is now `Schedule::apply_deferred`

---------

Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
This commit is contained in:
Alice Cecile 2023-06-02 10:04:13 -04:00 committed by GitHub
parent 6b4c7d5d88
commit cbd4abf0fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 102 additions and 107 deletions

View file

@ -1043,12 +1043,12 @@ category = "ECS (Entity Component System)"
wasm = false
[[example]]
name = "apply_system_buffers"
path = "examples/ecs/apply_system_buffers.rs"
name = "apply_deferred"
path = "examples/ecs/apply_deferred.rs"
[package.metadata.example.apply_system_buffers]
[package.metadata.example.apply_deferred]
name = "Apply System Buffers"
description = "Show how to use `apply_system_buffers` system"
description = "Show how to use `apply_deferred` system"
category = "ECS (Entity Component System)"
wasm = false

View file

@ -316,7 +316,7 @@ impl<'a, 'w, 's, E: Event> IntoIterator for &'a mut EventReader<'w, 's, E> {
/// // custom events to unknown 3rd party plugins (modding API).
/// //
/// // NOTE: the event won't actually be sent until commands get applied during
/// // apply_system_buffers.
/// // apply_deferred.
/// commands.add(|w: &mut World| {
/// w.send_event(MyEvent);
/// });

View file

@ -39,7 +39,7 @@ pub mod prelude {
query::{Added, AnyOf, Changed, Or, QueryState, With, Without},
removal_detection::RemovedComponents,
schedule::{
apply_state_transition, apply_system_buffers, common_conditions::*, Condition,
apply_deferred, apply_state_transition, common_conditions::*, Condition,
IntoSystemConfigs, IntoSystemSet, IntoSystemSetConfig, IntoSystemSetConfigs, NextState,
OnEnter, OnExit, OnTransition, Schedule, Schedules, State, States, SystemSet,
},

View file

@ -1042,8 +1042,8 @@ where
!self.condition.run(input, world)
}
fn apply_buffers(&mut self, world: &mut World) {
self.condition.apply_buffers(world);
fn apply_deferred(&mut self, world: &mut World) {
self.condition.apply_deferred(world);
}
fn initialize(&mut self, world: &mut World) {

View file

@ -19,7 +19,7 @@ pub(super) trait SystemExecutor: Send + Sync {
fn kind(&self) -> ExecutorKind;
fn init(&mut self, schedule: &SystemSchedule);
fn run(&mut self, schedule: &mut SystemSchedule, world: &mut World);
fn set_apply_final_buffers(&mut self, value: bool);
fn set_apply_final_deferred(&mut self, value: bool);
}
/// Specifies how a [`Schedule`](super::Schedule) will be run.
@ -35,7 +35,7 @@ pub enum ExecutorKind {
/// other things, or just trying minimize overhead.
#[cfg_attr(target_arch = "wasm32", default)]
SingleThreaded,
/// Like [`SingleThreaded`](ExecutorKind::SingleThreaded) but calls [`apply_buffers`](crate::system::System::apply_buffers)
/// Like [`SingleThreaded`](ExecutorKind::SingleThreaded) but calls [`apply_deferred`](crate::system::System::apply_deferred)
/// immediately after running each system.
Simple,
/// Runs the schedule using a thread pool. Non-conflicting systems can run in parallel.
@ -77,18 +77,19 @@ impl SystemSchedule {
}
}
/// Instructs the executor to call [`apply_buffers`](crate::system::System::apply_buffers)
/// on the systems that have run but not applied their buffers.
/// 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.
///
/// **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.
#[doc(alias = "apply_system_buffers")]
#[allow(unused_variables)]
pub fn apply_system_buffers(world: &mut World) {}
pub fn apply_deferred(world: &mut World) {}
/// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_system_buffers`].
pub(super) fn is_apply_system_buffers(system: &BoxedSystem) -> bool {
/// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_deferred`].
pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool {
use std::any::Any;
// deref to use `System::type_id` instead of `Any::type_id`
system.as_ref().type_id() == apply_system_buffers.type_id()
system.as_ref().type_id() == apply_deferred.type_id()
}

View file

@ -17,9 +17,7 @@ use crate::{
archetype::ArchetypeComponentId,
prelude::Resource,
query::Access,
schedule::{
is_apply_system_buffers, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule,
},
schedule::{is_apply_deferred, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule},
system::BoxedSystem,
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
@ -108,8 +106,8 @@ pub struct MultiThreadedExecutor {
completed_systems: FixedBitSet,
/// Systems that have run but have not had their buffers applied.
unapplied_systems: FixedBitSet,
/// Setting when true applies system buffers after all systems have run
apply_final_buffers: bool,
/// Setting when true applies deferred system buffers after all systems have run
apply_final_deferred: bool,
/// When set, tells the executor that a thread has panicked.
panic_payload: Arc<Mutex<Option<Box<dyn Any + Send>>>>,
/// When set, stops the executor from running any more systems.
@ -127,8 +125,8 @@ impl SystemExecutor for MultiThreadedExecutor {
ExecutorKind::MultiThreaded
}
fn set_apply_final_buffers(&mut self, value: bool) {
self.apply_final_buffers = value;
fn set_apply_final_deferred(&mut self, value: bool) {
self.apply_final_deferred = value;
}
fn init(&mut self, schedule: &SystemSchedule) {
@ -230,10 +228,10 @@ impl SystemExecutor for MultiThreadedExecutor {
},
);
if self.apply_final_buffers {
if self.apply_final_deferred {
// Do one final apply buffers after all systems have completed
// Commands should be applied while on the scope's thread, not the executor's thread
let res = apply_system_buffers(&self.unapplied_systems, systems, world);
let res = apply_deferred(&self.unapplied_systems, systems, world);
if let Err(payload) = res {
let mut panic_payload = self.panic_payload.lock().unwrap();
*panic_payload = Some(payload);
@ -278,7 +276,7 @@ impl MultiThreadedExecutor {
skipped_systems: FixedBitSet::new(),
completed_systems: FixedBitSet::new(),
unapplied_systems: FixedBitSet::new(),
apply_final_buffers: true,
apply_final_deferred: true,
panic_payload: Arc::new(Mutex::new(None)),
stop_spawning: false,
}
@ -556,14 +554,14 @@ impl MultiThreadedExecutor {
let sender = self.sender.clone();
let panic_payload = self.panic_payload.clone();
if is_apply_system_buffers(system) {
if is_apply_deferred(system) {
// TODO: avoid allocation
let unapplied_systems = self.unapplied_systems.clone();
self.unapplied_systems.clear();
let task = async move {
#[cfg(feature = "trace")]
let system_guard = system_span.enter();
let res = apply_system_buffers(&unapplied_systems, systems, world);
let res = apply_deferred(&unapplied_systems, systems, world);
#[cfg(feature = "trace")]
drop(system_guard);
// tell the executor that the system finished
@ -681,7 +679,7 @@ impl MultiThreadedExecutor {
}
}
fn apply_system_buffers(
fn apply_deferred(
unapplied_systems: &FixedBitSet,
systems: &[SyncUnsafeCell<BoxedSystem>],
world: &mut World,
@ -690,7 +688,7 @@ fn apply_system_buffers(
// SAFETY: none of these systems are running, no other references exist
let system = unsafe { &mut *systems[system_index].get() };
let res = std::panic::catch_unwind(AssertUnwindSafe(|| {
system.apply_buffers(world);
system.apply_deferred(world);
}));
if let Err(payload) = res {
eprintln!(

View file

@ -9,7 +9,7 @@ use crate::{
};
/// A variant of [`SingleThreadedExecutor`](crate::schedule::SingleThreadedExecutor) that calls
/// [`apply_buffers`](crate::system::System::apply_buffers) immediately after running each system.
/// [`apply_deferred`](crate::system::System::apply_deferred) immediately after running each system.
#[derive(Default)]
pub struct SimpleExecutor {
/// Systems sets whose conditions have been evaluated.
@ -23,7 +23,7 @@ impl SystemExecutor for SimpleExecutor {
ExecutorKind::Simple
}
fn set_apply_final_buffers(&mut self, _: bool) {
fn set_apply_final_deferred(&mut self, _: bool) {
// do nothing. simple executor does not do a final sync
}
@ -89,7 +89,7 @@ impl SystemExecutor for SimpleExecutor {
std::panic::resume_unwind(payload);
}
system.apply_buffers(world);
system.apply_deferred(world);
}
self.evaluated_sets.clear();

View file

@ -4,9 +4,7 @@ use fixedbitset::FixedBitSet;
use std::panic::AssertUnwindSafe;
use crate::{
schedule::{
is_apply_system_buffers, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule,
},
schedule::{is_apply_deferred, BoxedCondition, ExecutorKind, SystemExecutor, SystemSchedule},
world::World,
};
@ -22,8 +20,8 @@ pub struct SingleThreadedExecutor {
completed_systems: FixedBitSet,
/// Systems that have run but have not had their buffers applied.
unapplied_systems: FixedBitSet,
/// Setting when true applies system buffers after all systems have run
apply_final_buffers: bool,
/// Setting when true applies deferred system buffers after all systems have run
apply_final_deferred: bool,
}
impl SystemExecutor for SingleThreadedExecutor {
@ -31,8 +29,8 @@ impl SystemExecutor for SingleThreadedExecutor {
ExecutorKind::SingleThreaded
}
fn set_apply_final_buffers(&mut self, apply_final_buffers: bool) {
self.apply_final_buffers = apply_final_buffers;
fn set_apply_final_deferred(&mut self, apply_final_deferred: bool) {
self.apply_final_deferred = apply_final_deferred;
}
fn init(&mut self, schedule: &SystemSchedule) {
@ -87,10 +85,10 @@ impl SystemExecutor for SingleThreadedExecutor {
}
let system = &mut schedule.systems[system_index];
if is_apply_system_buffers(system) {
if is_apply_deferred(system) {
#[cfg(feature = "trace")]
let system_span = info_span!("system", name = &*name).entered();
self.apply_system_buffers(schedule, world);
self.apply_deferred(schedule, world);
#[cfg(feature = "trace")]
system_span.exit();
} else {
@ -109,8 +107,8 @@ impl SystemExecutor for SingleThreadedExecutor {
}
}
if self.apply_final_buffers {
self.apply_system_buffers(schedule, world);
if self.apply_final_deferred {
self.apply_deferred(schedule, world);
}
self.evaluated_sets.clear();
self.completed_systems.clear();
@ -123,14 +121,14 @@ impl SingleThreadedExecutor {
evaluated_sets: FixedBitSet::new(),
completed_systems: FixedBitSet::new(),
unapplied_systems: FixedBitSet::new(),
apply_final_buffers: true,
apply_final_deferred: true,
}
}
fn apply_system_buffers(&mut self, schedule: &mut SystemSchedule, world: &mut World) {
fn apply_deferred(&mut self, schedule: &mut SystemSchedule, world: &mut World) {
for system_index in self.unapplied_systems.ones() {
let system = &mut schedule.systems[system_index];
system.apply_buffers(world);
system.apply_deferred(world);
}
self.unapplied_systems.clear();

View file

@ -219,12 +219,12 @@ impl Schedule {
self
}
/// Set whether the schedule applies buffers on final time or not. This is a catchall
/// incase a system uses commands but was not explicitly ordered after a
/// [`apply_system_buffers`](crate::prelude::apply_system_buffers). By default this
/// 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`](crate::prelude::apply_deferred). By default this
/// setting is true, but may be disabled if needed.
pub fn set_apply_final_buffers(&mut self, apply_final_buffers: bool) -> &mut Self {
self.executor.set_apply_final_buffers(apply_final_buffers);
pub fn set_apply_final_deferred(&mut self, apply_final_deferred: bool) -> &mut Self {
self.executor.set_apply_final_deferred(apply_final_deferred);
self
}
@ -287,17 +287,17 @@ impl Schedule {
}
}
/// Directly applies any accumulated system buffers (like [`Commands`](crate::prelude::Commands)) to the `world`.
/// Directly applies any accumulated [`Deferred`](crate::system::Deferred) system parameters (like [`Commands`](crate::prelude::Commands)) to the `world`.
///
/// Like always, system buffers are applied in the "topological sort order" of the schedule graph.
/// Like always, deferred system parameters are applied in the "topological sort order" of the schedule graph.
/// As a result, buffers from one system are only guaranteed to be applied before those of other systems
/// if there is an explicit system ordering between the two systems.
///
/// This is used in rendering to extract data from the main world, storing the data in system buffers,
/// before applying their buffers in a different world.
pub fn apply_system_buffers(&mut self, world: &mut World) {
pub fn apply_deferred(&mut self, world: &mut World) {
for system in &mut self.executable.systems {
system.apply_buffers(world);
system.apply_deferred(world);
}
}
}

View file

@ -187,9 +187,9 @@ where
)
}
fn apply_buffers(&mut self, world: &mut World) {
self.a.apply_buffers(world);
self.b.apply_buffers(world);
fn apply_deferred(&mut self, world: &mut World) {
self.a.apply_deferred(world);
self.b.apply_deferred(world);
}
fn initialize(&mut self, world: &mut World) {

View file

@ -50,11 +50,11 @@ pub trait Command: Send + 'static {
///
/// Since each command requires exclusive access to the `World`,
/// all queued commands are automatically applied in sequence
/// when the [`apply_system_buffers`] system runs.
/// when the [`apply_deferred`] system runs.
///
/// The command queue of an individual system can also be manually applied
/// by calling [`System::apply_buffers`].
/// Similarly, the command queue of a schedule can be manually applied via [`Schedule::apply_system_buffers`].
/// by calling [`System::apply_deferred`].
/// Similarly, the command queue of a schedule can be manually applied via [`Schedule::apply_deferred`].
///
/// Each command can be used to modify the [`World`] in arbitrary ways:
/// * spawning or despawning entities
@ -68,7 +68,7 @@ pub trait Command: Send + 'static {
///
/// # 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_system_buffers`] 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 [`apply_deferred`] runs.
/// Commands are almost always used as a [`SystemParam`](crate::system::SystemParam).
///
/// ```
@ -100,9 +100,9 @@ pub trait Command: Send + 'static {
/// # }
/// ```
///
/// [`System::apply_buffers`]: crate::system::System::apply_buffers
/// [`apply_system_buffers`]: crate::schedule::apply_system_buffers
/// [`Schedule::apply_system_buffers`]: crate::schedule::Schedule::apply_system_buffers
/// [`System::apply_deferred`]: crate::system::System::apply_deferred
/// [`apply_deferred`]: crate::schedule::apply_deferred
/// [`Schedule::apply_deferred`]: crate::schedule::Schedule::apply_deferred
#[derive(SystemParam)]
pub struct Commands<'w, 's> {
queue: Deferred<'s, CommandQueue>,

View file

@ -122,7 +122,7 @@ where
}
#[inline]
fn apply_buffers(&mut self, _world: &mut World) {
fn apply_deferred(&mut self, _world: &mut World) {
// "pure" exclusive systems do not have any buffers to apply.
// Systems made by piping a normal system with an exclusive system
// might have buffers to apply, but this is handled by `PipeSystem`.

View file

@ -445,7 +445,7 @@ where
}
#[inline]
fn apply_buffers(&mut self, world: &mut World) {
fn apply_deferred(&mut self, world: &mut World) {
let param_state = self.param_state.as_mut().expect(Self::PARAM_MESSAGE);
F::Param::apply(param_state, &self.system_meta, world);
}

View file

@ -491,7 +491,7 @@ mod tests {
prelude::AnyOf,
query::{Added, Changed, Or, With, Without},
removal_detection::RemovedComponents,
schedule::{apply_system_buffers, IntoSystemConfigs, Schedule},
schedule::{apply_deferred, IntoSystemConfigs, Schedule},
system::{
adapter::new, Commands, In, IntoSystem, Local, NonSend, NonSendMut, ParamSet, Query,
QueryComponentError, Res, ResMut, Resource, System, SystemState,
@ -717,7 +717,7 @@ mod tests {
let mut schedule = Schedule::default();
schedule.add_systems((incr_e_on_flip, apply_system_buffers, World::clear_trackers).chain());
schedule.add_systems((incr_e_on_flip, apply_deferred, World::clear_trackers).chain());
schedule.run(&mut world);
assert_eq!(world.resource::<Added>().0, 1);

View file

@ -61,7 +61,8 @@ pub trait System: Send + Sync + 'static {
// - `update_archetype_component_access` has been called.
unsafe { self.run_unsafe(input, world) }
}
fn apply_buffers(&mut self, world: &mut World);
/// Applies any [`Deferred`](crate::system::Deferred) system parameters (or other system buffers) of this system to the world.
fn apply_deferred(&mut self, world: &mut World);
/// Initialize the system.
fn initialize(&mut self, _world: &mut World);
/// Update the system's archetype component [`Access`].

View file

@ -118,7 +118,7 @@ pub unsafe trait SystemParam: Sized {
}
/// Applies any deferred mutations stored in this [`SystemParam`]'s state.
/// This is used to apply [`Commands`] during [`apply_system_buffers`](crate::prelude::apply_system_buffers).
/// This is used to apply [`Commands`] during [`apply_deferred`](crate::prelude::apply_deferred).
///
/// [`Commands`]: crate::prelude::Commands
#[inline]
@ -766,7 +766,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static {
}
/// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during
/// [`apply_system_buffers`](crate::schedule::apply_system_buffers).
/// [`apply_deferred`](crate::schedule::apply_deferred).
/// This is used internally by [`Commands`] to defer `World` mutations.
///
/// [`Commands`]: crate::system::Commands
@ -809,7 +809,7 @@ pub trait SystemBuffer: FromWorld + Send + 'static {
/// struct AlarmFlag(bool);
///
/// impl AlarmFlag {
/// /// Sounds the alarm the next time buffers are applied via apply_system_buffers.
/// /// Sounds the alarm the next time buffers are applied via apply_deferred.
/// pub fn flag(&mut self) {
/// self.0 = true;
/// }
@ -817,7 +817,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_system_buffers.
/// // called the next time buffers are applied via apply_deferred.
/// fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
/// if self.0 {
/// world.resource_mut::<Alarm>().0 = true;

View file

@ -202,7 +202,7 @@ impl Plugin for PbrPlugin {
PostUpdate,
(
add_clusters.in_set(SimulationLightSystems::AddClusters),
apply_system_buffers.in_set(SimulationLightSystems::AddClustersFlush),
apply_deferred.in_set(SimulationLightSystems::AddClustersFlush),
assign_lights_to_clusters
.in_set(SimulationLightSystems::AssignLightsToClusters)
.after(TransformSystem::TransformPropagate)
@ -283,7 +283,7 @@ impl Plugin for PbrPlugin {
.in_set(RenderLightSystems::PrepareLights),
// A sync is needed after prepare_lights, before prepare_view_uniforms,
// because prepare_lights creates new views for shadow mapping
apply_system_buffers
apply_deferred
.in_set(RenderSet::Prepare)
.after(RenderLightSystems::PrepareLights)
.before(ViewSet::PrepareUniforms),

View file

@ -165,7 +165,7 @@ where
prepare_previous_view_projection_uniforms
.in_set(RenderSet::Prepare)
.after(PrepassLightsViewFlush),
apply_system_buffers
apply_deferred
.in_set(RenderSet::Prepare)
.in_set(PrepassLightsViewFlush)
.after(prepare_lights),

View file

@ -72,39 +72,39 @@ pub struct RenderPlugin {
/// The labels of the default App rendering sets.
///
/// The sets run in the order listed, with [`apply_system_buffers`] inserted between each set.
/// The sets run in the order listed, with [`apply_deferred`] inserted between each set.
///
/// The `*Flush` sets are assigned to the copy of [`apply_system_buffers`]
/// The `*Flush` sets are assigned to the copy of [`apply_deferred`]
/// that runs immediately after the matching system set.
/// These can be useful for ordering, but you almost never want to add your systems to these sets.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub enum RenderSet {
/// The copy of [`apply_system_buffers`] that runs at the beginning of this schedule.
/// The copy of [`apply_deferred`] that runs at the beginning of this schedule.
/// This is used for applying the commands from the [`ExtractSchedule`]
ExtractCommands,
/// Prepare render resources from the extracted data for the GPU.
Prepare,
/// The copy of [`apply_system_buffers`] that runs immediately after [`Prepare`](RenderSet::Prepare).
/// The copy of [`apply_deferred`] that runs immediately after [`Prepare`](RenderSet::Prepare).
PrepareFlush,
/// Create [`BindGroups`](render_resource::BindGroup) that depend on
/// [`Prepare`](RenderSet::Prepare) data and queue up draw calls to run during the
/// [`Render`](RenderSet::Render) step.
Queue,
/// The copy of [`apply_system_buffers`] that runs immediately after [`Queue`](RenderSet::Queue).
/// The copy of [`apply_deferred`] that runs immediately after [`Queue`](RenderSet::Queue).
QueueFlush,
// TODO: This could probably be moved in favor of a system ordering abstraction in Render or Queue
/// Sort the [`RenderPhases`](render_phase::RenderPhase) here.
PhaseSort,
/// The copy of [`apply_system_buffers`] that runs immediately after [`PhaseSort`](RenderSet::PhaseSort).
/// The copy of [`apply_deferred`] that runs immediately after [`PhaseSort`](RenderSet::PhaseSort).
PhaseSortFlush,
/// Actual rendering happens here.
/// In most cases, only the render backend should insert resources here.
Render,
/// The copy of [`apply_system_buffers`] that runs immediately after [`Render`](RenderSet::Render).
/// The copy of [`apply_deferred`] that runs immediately after [`Render`](RenderSet::Render).
RenderFlush,
/// Cleanup render resources here.
Cleanup,
/// The copy of [`apply_system_buffers`] that runs immediately after [`Cleanup`](RenderSet::Cleanup).
/// The copy of [`apply_deferred`] that runs immediately after [`Cleanup`](RenderSet::Cleanup).
CleanupFlush,
}
@ -116,7 +116,7 @@ impl Render {
/// Sets up the base structure of the rendering [`Schedule`].
///
/// The sets defined in this enum are configured to run in order,
/// and a copy of [`apply_system_buffers`] is inserted into each `*Flush` set.
/// and a copy of [`apply_deferred`] is inserted into each `*Flush` set.
pub fn base_schedule() -> Schedule {
use RenderSet::*;
@ -124,11 +124,11 @@ impl Render {
// Create "stage-like" structure using buffer flushes + ordering
schedule.add_systems((
apply_system_buffers.in_set(PrepareFlush),
apply_system_buffers.in_set(QueueFlush),
apply_system_buffers.in_set(PhaseSortFlush),
apply_system_buffers.in_set(RenderFlush),
apply_system_buffers.in_set(CleanupFlush),
apply_deferred.in_set(PrepareFlush),
apply_deferred.in_set(QueueFlush),
apply_deferred.in_set(PhaseSortFlush),
apply_deferred.in_set(RenderFlush),
apply_deferred.in_set(CleanupFlush),
));
schedule.configure_sets(
@ -158,7 +158,7 @@ impl Render {
/// running the next frame while rendering the current frame.
///
/// This schedule is run on the main world, but its buffers are not applied
/// via [`Schedule::apply_system_buffers`](bevy_ecs::schedule::Schedule) until it is returned to the render world.
/// via [`Schedule::apply_deferred`](bevy_ecs::schedule::Schedule) until it is returned to the render world.
#[derive(ScheduleLabel, PartialEq, Eq, Debug, Clone, Hash)]
pub struct ExtractSchedule;
@ -269,7 +269,7 @@ impl Plugin for RenderPlugin {
render_app.main_schedule_label = Box::new(Render);
let mut extract_schedule = Schedule::new();
extract_schedule.set_apply_final_buffers(false);
extract_schedule.set_apply_final_deferred(false);
render_app
.add_schedule(ExtractSchedule, extract_schedule)
@ -404,6 +404,6 @@ fn apply_extract_commands(render_world: &mut World) {
schedules
.get_mut(&ExtractSchedule)
.unwrap()
.apply_system_buffers(render_world);
.apply_deferred(render_world);
});
}

View file

@ -214,10 +214,7 @@ impl Plugin for VisibilityPlugin {
app
// We add an AABB component in CalculateBounds, which must be ready on the same frame.
.add_systems(
PostUpdate,
apply_system_buffers.in_set(CalculateBoundsFlush),
)
.add_systems(PostUpdate, apply_deferred.in_set(CalculateBoundsFlush))
.configure_set(PostUpdate, CalculateBoundsFlush.after(CalculateBounds))
.add_systems(
PostUpdate,

View file

@ -74,7 +74,7 @@ pub trait BuildChildrenTransformExt {
///
/// Note that both the hierarchy and transform updates will only execute
/// the next time commands are applied
/// (during [`apply_system_buffers`](bevy_ecs::schedule::apply_system_buffers)).
/// (during [`apply_deferred`](bevy_ecs::schedule::apply_deferred)).
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self;
/// Make this entity parentless while preserving this entity's [`GlobalTransform`]
@ -85,7 +85,7 @@ pub trait BuildChildrenTransformExt {
///
/// Note that both the hierarchy and transform updates will only execute
/// the next time commands are applied
/// (during [`apply_system_buffers`](bevy_ecs::schedule::apply_system_buffers)).
/// (during [`apply_deferred`](bevy_ecs::schedule::apply_deferred)).
fn remove_parent_in_place(&mut self) -> &mut Self;
}
impl<'w, 's, 'a> BuildChildrenTransformExt for EntityCommands<'w, 's, 'a> {

View file

@ -206,7 +206,7 @@ Example | Description
Example | Description
--- | ---
[Apply System Buffers](../examples/ecs/apply_system_buffers.rs) | Show how to use `apply_system_buffers` system
[Apply System Buffers](../examples/ecs/apply_deferred.rs) | Show how to use `apply_deferred` system
[Component Change Detection](../examples/ecs/component_change_detection.rs) | Change detection on components
[Custom Query Parameters](../examples/ecs/custom_query_param.rs) | Groups commonly used compound queries and query filters into a single type
[ECS Guide](../examples/ecs/ecs_guide.rs) | Full guide to Bevy's ECS

View file

@ -1,4 +1,4 @@
//! This example illustrates how to use the `apply_system_buffers` system
//! This example illustrates how to use the `apply_deferred` system
//! to flush commands added by systems that have already run,
//! but have not had their buffers applied yet.
//!
@ -7,7 +7,7 @@
//! added to `CoreSet::Update`) but want to flush commands immediately.
//!
//! It is important that systems are ordered correctly with respect to
//! `apply_system_buffers`, to avoid surprising non-deterministic system execution order.
//! `apply_deferred`, to avoid surprising non-deterministic system execution order.
use bevy::prelude::*;
@ -21,9 +21,9 @@ fn main() {
(
(
despawn_old_and_spawn_new_fruits,
// We encourage adding apply_system_buffers to a custom set
// We encourage adding apply_deferred to a custom set
// to improve diagnostics. This is optional, but useful when debugging!
apply_system_buffers.in_set(CustomFlush),
apply_deferred.in_set(CustomFlush),
count_apple,
)
.chain(),

View file

@ -7,7 +7,7 @@ fn main() {
// to react to the removal before the frame is over.
//
// Also, `Components` are removed via a `Command`, which are not applied immediately.
// So you need to react to the removal at some stage after `apply_system_buffers` has run,
// So you need to react to the removal at some stage after `apply_deferred` has run,
// and the Component` is removed.
//
// With these constraints in mind we make sure to place the system that removes a `Component` in