Rename Add to Queue for methods with deferred semantics (#15234)

# Objective

- Fixes #15106

## Solution

- Trivial refactor to rename the method. The duplicate method `push` was
removed as well. This will simpify the API and make the semantics more
clear. `Add` implies that the action happens immediately, whereas in
reality, the command is queued to be run eventually.
- `ChildBuilder::add_command` has similarly been renamed to
`queue_command`.

## Testing

Unit tests should suffice for this simple refactor.

---

## Migration Guide

- `Commands::add` and `Commands::push` have been replaced with
`Commnads::queue`.
- `ChildBuilder::add_command` has been renamed to
`ChildBuilder::queue_command`.
This commit is contained in:
Benjamin Brienen 2024-09-17 02:17:49 +02:00 committed by GitHub
parent c2d54f5f04
commit b45d83ebda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 113 additions and 118 deletions

View file

@ -146,9 +146,9 @@ pub fn fake_commands(criterion: &mut Criterion) {
let mut commands = Commands::new(&mut command_queue, &world); let mut commands = Commands::new(&mut command_queue, &world);
for i in 0..command_count { for i in 0..command_count {
if black_box(i % 2 == 0) { if black_box(i % 2 == 0) {
commands.add(FakeCommandA); commands.queue(FakeCommandA);
} else { } else {
commands.add(FakeCommandB(0)); commands.queue(FakeCommandB(0));
} }
} }
command_queue.apply(&mut world); command_queue.apply(&mut world);
@ -190,7 +190,7 @@ pub fn sized_commands_impl<T: Default + Command>(criterion: &mut Criterion) {
bencher.iter(|| { bencher.iter(|| {
let mut commands = Commands::new(&mut command_queue, &world); let mut commands = Commands::new(&mut command_queue, &world);
for _ in 0..command_count { for _ in 0..command_count {
commands.add(T::default()); commands.queue(T::default());
} }
command_queue.apply(&mut world); command_queue.apply(&mut world);
}); });

View file

@ -51,7 +51,7 @@ use bevy_ecs::{
/// // /// //
/// // NOTE: the event won't actually be sent until commands get applied during /// // NOTE: the event won't actually be sent until commands get applied during
/// // apply_deferred. /// // apply_deferred.
/// commands.add(|w: &mut World| { /// commands.queue(|w: &mut World| {
/// w.send_event(MyEvent); /// w.send_event(MyEvent);
/// }); /// });
/// } /// }

View file

@ -830,7 +830,7 @@ mod tests {
..Default::default() ..Default::default()
}); });
world.commands().add( world.commands().queue(
// SAFETY: we registered `event_a` above and it matches the type of TriggerA // SAFETY: we registered `event_a` above and it matches the type of TriggerA
unsafe { EmitDynamicTrigger::new_with_id(event_a, EventA, ()) }, unsafe { EmitDynamicTrigger::new_with_id(event_a, EventA, ()) },
); );

View file

@ -65,7 +65,7 @@ impl Component for ObserverState {
fn register_component_hooks(hooks: &mut ComponentHooks) { fn register_component_hooks(hooks: &mut ComponentHooks) {
hooks.on_add(|mut world, entity, _| { hooks.on_add(|mut world, entity, _| {
world.commands().add(move |world: &mut World| { world.commands().queue(move |world: &mut World| {
world.register_observer(entity); world.register_observer(entity);
}); });
}); });
@ -78,7 +78,7 @@ impl Component for ObserverState {
.as_mut() .as_mut()
.descriptor, .descriptor,
); );
world.commands().add(move |world: &mut World| { world.commands().queue(move |world: &mut World| {
world.unregister_observer(entity, descriptor); world.unregister_observer(entity, descriptor);
}); });
}); });
@ -398,7 +398,7 @@ fn hook_on_add<E: Event, B: Bundle, S: ObserverSystem<E, B>>(
entity: Entity, entity: Entity,
_: ComponentId, _: ComponentId,
) { ) {
world.commands().add(move |world: &mut World| { world.commands().queue(move |world: &mut World| {
let event_type = world.init_component::<E>(); let event_type = world.init_component::<E>();
let mut components = Vec::new(); let mut components = Vec::new();
B::component_ids(&mut world.components, &mut world.storages, &mut |id| { B::component_ids(&mut world.components, &mut world.storages, &mut |id| {

View file

@ -79,7 +79,7 @@ pub trait ReflectCommandExt {
/// ///
/// // Or even with BundleA /// // Or even with BundleA
/// prefab.data = boxed_reflect_bundle_a; /// prefab.data = boxed_reflect_bundle_a;
/// ///
/// // No matter which component or bundle is in the resource and without knowing the exact type, you can /// // No matter which component or bundle is in the resource and without knowing the exact type, you can
/// // use the insert_reflect entity command to insert that component/bundle into an entity. /// // use the insert_reflect entity command to insert that component/bundle into an entity.
/// commands /// commands
@ -174,7 +174,7 @@ pub trait ReflectCommandExt {
impl ReflectCommandExt for EntityCommands<'_> { impl ReflectCommandExt for EntityCommands<'_> {
fn insert_reflect(&mut self, component: Box<dyn PartialReflect>) -> &mut Self { fn insert_reflect(&mut self, component: Box<dyn PartialReflect>) -> &mut Self {
self.commands.add(InsertReflect { self.commands.queue(InsertReflect {
entity: self.entity, entity: self.entity,
component, component,
}); });
@ -185,7 +185,7 @@ impl ReflectCommandExt for EntityCommands<'_> {
&mut self, &mut self,
component: Box<dyn PartialReflect>, component: Box<dyn PartialReflect>,
) -> &mut Self { ) -> &mut Self {
self.commands.add(InsertReflectWithRegistry::<T> { self.commands.queue(InsertReflectWithRegistry::<T> {
entity: self.entity, entity: self.entity,
_t: PhantomData, _t: PhantomData,
component, component,
@ -194,7 +194,7 @@ impl ReflectCommandExt for EntityCommands<'_> {
} }
fn remove_reflect(&mut self, component_type_path: impl Into<Cow<'static, str>>) -> &mut Self { fn remove_reflect(&mut self, component_type_path: impl Into<Cow<'static, str>>) -> &mut Self {
self.commands.add(RemoveReflect { self.commands.queue(RemoveReflect {
entity: self.entity, entity: self.entity,
component_type_path: component_type_path.into(), component_type_path: component_type_path.into(),
}); });
@ -205,7 +205,7 @@ impl ReflectCommandExt for EntityCommands<'_> {
&mut self, &mut self,
component_type_name: impl Into<Cow<'static, str>>, component_type_name: impl Into<Cow<'static, str>>,
) -> &mut Self { ) -> &mut Self {
self.commands.add(RemoveReflectWithRegistry::<T> { self.commands.queue(RemoveReflectWithRegistry::<T> {
entity: self.entity, entity: self.entity,
_t: PhantomData, _t: PhantomData,
component_type_name: component_type_name.into(), component_type_name: component_type_name.into(),

View file

@ -54,7 +54,7 @@ pub use parallel_scope::*;
/// ///
/// Each built-in command is implemented as a separate method, e.g. [`Commands::spawn`]. /// Each built-in command is implemented as a separate method, e.g. [`Commands::spawn`].
/// In addition to the pre-defined command methods, you can add commands with any arbitrary /// In addition to the pre-defined command methods, you can add commands with any arbitrary
/// behavior using [`Commands::add`], which accepts any type implementing [`Command`]. /// behavior using [`Commands::queue`], which accepts any type implementing [`Command`].
/// ///
/// Since closures and other functions implement this trait automatically, this allows one-shot, /// Since closures and other functions implement this trait automatically, this allows one-shot,
/// anonymous custom commands. /// anonymous custom commands.
@ -63,7 +63,7 @@ pub use parallel_scope::*;
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// # fn foo(mut commands: Commands) { /// # fn foo(mut commands: Commands) {
/// // NOTE: type inference fails here, so annotations are required on the closure. /// // NOTE: type inference fails here, so annotations are required on the closure.
/// commands.add(|w: &mut World| { /// commands.queue(|w: &mut World| {
/// // Mutate the world however you want... /// // Mutate the world however you want...
/// # todo!(); /// # todo!();
/// }); /// });
@ -303,7 +303,7 @@ impl<'w, 's> Commands<'w, 's> {
/// apps, and only when they have a scheme worked out to share an ID space (which doesn't happen /// apps, and only when they have a scheme worked out to share an ID space (which doesn't happen
/// by default). /// by default).
pub fn get_or_spawn(&mut self, entity: Entity) -> EntityCommands { pub fn get_or_spawn(&mut self, entity: Entity) -> EntityCommands {
self.add(move |world: &mut World| { self.queue(move |world: &mut World| {
world.get_or_spawn(entity); world.get_or_spawn(entity);
}); });
EntityCommands { EntityCommands {
@ -503,11 +503,43 @@ impl<'w, 's> Commands<'w, 's> {
I: IntoIterator + Send + Sync + 'static, I: IntoIterator + Send + Sync + 'static,
I::Item: Bundle, I::Item: Bundle,
{ {
self.push(spawn_batch(bundles_iter)); self.queue(spawn_batch(bundles_iter));
} }
/// Push a [`Command`] onto the queue. /// Pushes a generic [`Command`] to the command queue.
pub fn push<C: Command>(&mut self, command: C) { ///
/// `command` can be a built-in command, custom struct that implements [`Command`] or a closure
/// that takes [`&mut World`](World) as an argument.
/// # Example
///
/// ```
/// # use bevy_ecs::{world::Command, prelude::*};
/// #[derive(Resource, Default)]
/// struct Counter(u64);
///
/// struct AddToCounter(u64);
///
/// impl Command for AddToCounter {
/// fn apply(self, world: &mut World) {
/// let mut counter = world.get_resource_or_insert_with(Counter::default);
/// counter.0 += self.0;
/// }
/// }
///
/// fn add_three_to_counter_system(mut commands: Commands) {
/// commands.queue(AddToCounter(3));
/// }
/// fn add_twenty_five_to_counter_system(mut commands: Commands) {
/// commands.queue(|world: &mut World| {
/// let mut counter = world.get_resource_or_insert_with(Counter::default);
/// counter.0 += 25;
/// });
/// }
/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
/// ```
pub fn queue<C: Command>(&mut self, command: C) {
match &mut self.queue { match &mut self.queue {
InternalQueue::CommandQueue(queue) => { InternalQueue::CommandQueue(queue) => {
queue.push(command); queue.push(command);
@ -549,7 +581,7 @@ impl<'w, 's> Commands<'w, 's> {
I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static, I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
B: Bundle, B: Bundle,
{ {
self.push(insert_or_spawn_batch(bundles_iter)); self.queue(insert_or_spawn_batch(bundles_iter));
} }
/// Pushes a [`Command`] to the queue for inserting a [`Resource`] in the [`World`] with an inferred value. /// Pushes a [`Command`] to the queue for inserting a [`Resource`] in the [`World`] with an inferred value.
@ -578,7 +610,7 @@ impl<'w, 's> Commands<'w, 's> {
/// ``` /// ```
#[track_caller] #[track_caller]
pub fn init_resource<R: Resource + FromWorld>(&mut self) { pub fn init_resource<R: Resource + FromWorld>(&mut self) {
self.push(init_resource::<R>); self.queue(init_resource::<R>);
} }
/// Pushes a [`Command`] to the queue for inserting a [`Resource`] in the [`World`] with a specific value. /// Pushes a [`Command`] to the queue for inserting a [`Resource`] in the [`World`] with a specific value.
@ -608,7 +640,7 @@ impl<'w, 's> Commands<'w, 's> {
/// ``` /// ```
#[track_caller] #[track_caller]
pub fn insert_resource<R: Resource>(&mut self, resource: R) { pub fn insert_resource<R: Resource>(&mut self, resource: R) {
self.push(insert_resource(resource)); self.queue(insert_resource(resource));
} }
/// Pushes a [`Command`] to the queue for removing a [`Resource`] from the [`World`]. /// Pushes a [`Command`] to the queue for removing a [`Resource`] from the [`World`].
@ -632,7 +664,7 @@ impl<'w, 's> Commands<'w, 's> {
/// # bevy_ecs::system::assert_is_system(system); /// # bevy_ecs::system::assert_is_system(system);
/// ``` /// ```
pub fn remove_resource<R: Resource>(&mut self) { pub fn remove_resource<R: Resource>(&mut self) {
self.push(remove_resource::<R>); self.queue(remove_resource::<R>);
} }
/// Runs the system corresponding to the given [`SystemId`]. /// Runs the system corresponding to the given [`SystemId`].
@ -658,7 +690,7 @@ impl<'w, 's> Commands<'w, 's> {
/// execution of the system happens later. To get the output of a system, use /// execution of the system happens later. To get the output of a system, use
/// [`World::run_system`] or [`World::run_system_with_input`] instead of running the system as a command. /// [`World::run_system`] or [`World::run_system_with_input`] instead of running the system as a command.
pub fn run_system_with_input<I: 'static + Send>(&mut self, id: SystemId<I>, input: I) { pub fn run_system_with_input<I: 'static + Send>(&mut self, id: SystemId<I>, input: I) {
self.push(RunSystemWithInput::new_with_input(id, input)); self.queue(RunSystemWithInput::new_with_input(id, input));
} }
/// Registers a system and returns a [`SystemId`] so it can later be called by [`World::run_system`]. /// Registers a system and returns a [`SystemId`] so it can later be called by [`World::run_system`].
@ -720,53 +752,16 @@ impl<'w, 's> Commands<'w, 's> {
system: S, system: S,
) -> SystemId<I, O> { ) -> SystemId<I, O> {
let entity = self.spawn_empty().id(); let entity = self.spawn_empty().id();
self.push(RegisterSystem::new(system, entity)); self.queue(RegisterSystem::new(system, entity));
SystemId::from_entity(entity) SystemId::from_entity(entity)
} }
/// Pushes a generic [`Command`] to the command queue.
///
/// `command` can be a built-in command, custom struct that implements [`Command`] or a closure
/// that takes [`&mut World`](World) as an argument.
/// # Example
///
/// ```
/// # use bevy_ecs::{world::Command, prelude::*};
/// #[derive(Resource, Default)]
/// struct Counter(u64);
///
/// struct AddToCounter(u64);
///
/// impl Command for AddToCounter {
/// fn apply(self, world: &mut World) {
/// let mut counter = world.get_resource_or_insert_with(Counter::default);
/// counter.0 += self.0;
/// }
/// }
///
/// fn add_three_to_counter_system(mut commands: Commands) {
/// commands.add(AddToCounter(3));
/// }
/// fn add_twenty_five_to_counter_system(mut commands: Commands) {
/// commands.add(|world: &mut World| {
/// let mut counter = world.get_resource_or_insert_with(Counter::default);
/// counter.0 += 25;
/// });
/// }
/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
/// ```
pub fn add<C: Command>(&mut self, command: C) {
self.push(command);
}
/// Sends a "global" [`Trigger`] without any targets. This will run any [`Observer`] of the `event` that /// Sends a "global" [`Trigger`] without any targets. This will run any [`Observer`] of the `event` that
/// isn't scoped to specific targets. /// isn't scoped to specific targets.
/// ///
/// [`Trigger`]: crate::observer::Trigger /// [`Trigger`]: crate::observer::Trigger
pub fn trigger(&mut self, event: impl Event) { pub fn trigger(&mut self, event: impl Event) {
self.add(TriggerEvent { event, targets: () }); self.queue(TriggerEvent { event, targets: () });
} }
/// Sends a [`Trigger`] for the given targets. This will run any [`Observer`] of the `event` that /// Sends a [`Trigger`] for the given targets. This will run any [`Observer`] of the `event` that
@ -778,7 +773,7 @@ impl<'w, 's> Commands<'w, 's> {
event: impl Event, event: impl Event,
targets: impl TriggerTargets + Send + Sync + 'static, targets: impl TriggerTargets + Send + Sync + 'static,
) { ) {
self.add(TriggerEvent { event, targets }); self.queue(TriggerEvent { event, targets });
} }
/// Spawns an [`Observer`] and returns the [`EntityCommands`] associated with the entity that stores the observer. /// Spawns an [`Observer`] and returns the [`EntityCommands`] associated with the entity that stores the observer.
@ -800,7 +795,7 @@ impl<'w, 's> Commands<'w, 's> {
/// ///
/// [`EventWriter`]: crate::event::EventWriter /// [`EventWriter`]: crate::event::EventWriter
pub fn send_event<E: Event>(&mut self, event: E) -> &mut Self { pub fn send_event<E: Event>(&mut self, event: E) -> &mut Self {
self.add(SendEvent { event }); self.queue(SendEvent { event });
self self
} }
} }
@ -848,8 +843,8 @@ impl<'w, 's> Commands<'w, 's> {
/// # assert_schedule.run(&mut world); /// # assert_schedule.run(&mut world);
/// ///
/// fn setup(mut commands: Commands) { /// fn setup(mut commands: Commands) {
/// commands.spawn_empty().add(count_name); /// commands.spawn_empty().queue(count_name);
/// commands.spawn_empty().add(count_name); /// commands.spawn_empty().queue(count_name);
/// } /// }
/// ///
/// fn assert_names(named: Query<&Name>) { /// fn assert_names(named: Query<&Name>) {
@ -965,7 +960,7 @@ impl EntityCommands<'_> {
/// ``` /// ```
#[track_caller] #[track_caller]
pub fn insert(self, bundle: impl Bundle) -> Self { pub fn insert(self, bundle: impl Bundle) -> Self {
self.add(insert(bundle, InsertMode::Replace)) self.queue(insert(bundle, InsertMode::Replace))
} }
/// Similar to [`Self::insert`] but will only insert if the predicate returns true. /// Similar to [`Self::insert`] but will only insert if the predicate returns true.
@ -1003,7 +998,7 @@ impl EntityCommands<'_> {
F: FnOnce() -> bool, F: FnOnce() -> bool,
{ {
if condition() { if condition() {
self.add(insert(bundle, InsertMode::Replace)) self.queue(insert(bundle, InsertMode::Replace))
} else { } else {
self self
} }
@ -1021,7 +1016,7 @@ impl EntityCommands<'_> {
/// ///
/// To avoid a panic in this case, use the command [`Self::try_insert_if_new`] instead. /// To avoid a panic in this case, use the command [`Self::try_insert_if_new`] instead.
pub fn insert_if_new(self, bundle: impl Bundle) -> Self { pub fn insert_if_new(self, bundle: impl Bundle) -> Self {
self.add(insert(bundle, InsertMode::Keep)) self.queue(insert(bundle, InsertMode::Keep))
} }
/// Adds a [`Bundle`] of components to the entity without overwriting if the /// Adds a [`Bundle`] of components to the entity without overwriting if the
@ -1071,7 +1066,7 @@ impl EntityCommands<'_> {
) -> Self { ) -> Self {
let caller = Location::caller(); let caller = Location::caller();
// SAFETY: same invariants as parent call // SAFETY: same invariants as parent call
self.add(unsafe {insert_by_id(component_id, value, move |entity| { self.queue(unsafe {insert_by_id(component_id, value, move |entity| {
panic!("error[B0003]: {caller}: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::<T>()); panic!("error[B0003]: {caller}: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003", std::any::type_name::<T>());
})}) })})
} }
@ -1090,7 +1085,7 @@ impl EntityCommands<'_> {
value: T, value: T,
) -> Self { ) -> Self {
// SAFETY: same invariants as parent call // SAFETY: same invariants as parent call
self.add(unsafe { insert_by_id(component_id, value, |_| {}) }) self.queue(unsafe { insert_by_id(component_id, value, |_| {}) })
} }
/// Tries to add a [`Bundle`] of components to the entity. /// Tries to add a [`Bundle`] of components to the entity.
@ -1143,7 +1138,7 @@ impl EntityCommands<'_> {
/// ``` /// ```
#[track_caller] #[track_caller]
pub fn try_insert(self, bundle: impl Bundle) -> Self { pub fn try_insert(self, bundle: impl Bundle) -> Self {
self.add(try_insert(bundle, InsertMode::Replace)) self.queue(try_insert(bundle, InsertMode::Replace))
} }
/// Similar to [`Self::try_insert`] but will only try to insert if the predicate returns true. /// Similar to [`Self::try_insert`] but will only try to insert if the predicate returns true.
@ -1178,7 +1173,7 @@ impl EntityCommands<'_> {
F: FnOnce() -> bool, F: FnOnce() -> bool,
{ {
if condition() { if condition() {
self.add(try_insert(bundle, InsertMode::Replace)) self.queue(try_insert(bundle, InsertMode::Replace))
} else { } else {
self self
} }
@ -1240,7 +1235,7 @@ impl EntityCommands<'_> {
/// ///
/// Unlike [`Self::insert_if_new`], this will not panic if the associated entity does not exist. /// Unlike [`Self::insert_if_new`], this will not panic if the associated entity does not exist.
pub fn try_insert_if_new(self, bundle: impl Bundle) -> Self { pub fn try_insert_if_new(self, bundle: impl Bundle) -> Self {
self.add(try_insert(bundle, InsertMode::Keep)) self.queue(try_insert(bundle, InsertMode::Keep))
} }
/// Removes a [`Bundle`] of components from the entity. /// Removes a [`Bundle`] of components from the entity.
@ -1282,17 +1277,17 @@ impl EntityCommands<'_> {
where where
T: Bundle, T: Bundle,
{ {
self.add(remove::<T>) self.queue(remove::<T>)
} }
/// Removes a component from the entity. /// Removes a component from the entity.
pub fn remove_by_id(self, component_id: ComponentId) -> Self { pub fn remove_by_id(self, component_id: ComponentId) -> Self {
self.add(remove_by_id(component_id)) self.queue(remove_by_id(component_id))
} }
/// Removes all components associated with the entity. /// Removes all components associated with the entity.
pub fn clear(self) -> Self { pub fn clear(self) -> Self {
self.add(clear()) self.queue(clear())
} }
/// Despawns the entity. /// Despawns the entity.
@ -1324,7 +1319,7 @@ impl EntityCommands<'_> {
/// ``` /// ```
#[track_caller] #[track_caller]
pub fn despawn(self) -> Self { pub fn despawn(self) -> Self {
self.add(despawn()) self.queue(despawn())
} }
/// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`]. /// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].
@ -1337,15 +1332,15 @@ impl EntityCommands<'_> {
/// commands /// commands
/// .spawn_empty() /// .spawn_empty()
/// // Closures with this signature implement `EntityCommand`. /// // Closures with this signature implement `EntityCommand`.
/// .add(|entity: EntityWorldMut| { /// .queue(|entity: EntityWorldMut| {
/// println!("Executed an EntityCommand for {:?}", entity.id()); /// println!("Executed an EntityCommand for {:?}", entity.id());
/// }); /// });
/// # } /// # }
/// # bevy_ecs::system::assert_is_system(my_system); /// # bevy_ecs::system::assert_is_system(my_system);
/// ``` /// ```
#[allow(clippy::should_implement_trait)] #[allow(clippy::should_implement_trait)]
pub fn add<M: 'static>(mut self, command: impl EntityCommand<M>) -> Self { pub fn queue<M: 'static>(mut self, command: impl EntityCommand<M>) -> Self {
self.commands.add(command.with_entity(self.entity)); self.commands.queue(command.with_entity(self.entity));
self self
} }
@ -1390,7 +1385,7 @@ impl EntityCommands<'_> {
where where
T: Bundle, T: Bundle,
{ {
self.add(retain::<T>) self.queue(retain::<T>)
} }
/// Logs the components of the entity at the info level. /// Logs the components of the entity at the info level.
@ -1399,7 +1394,7 @@ impl EntityCommands<'_> {
/// ///
/// The command will panic when applied if the associated entity does not exist. /// The command will panic when applied if the associated entity does not exist.
pub fn log_components(self) -> Self { pub fn log_components(self) -> Self {
self.add(log_components) self.queue(log_components)
} }
/// Returns the underlying [`Commands`]. /// Returns the underlying [`Commands`].
@ -1418,7 +1413,7 @@ impl EntityCommands<'_> {
/// Creates an [`Observer`] listening for a trigger of type `T` that targets this entity. /// Creates an [`Observer`] listening for a trigger of type `T` that targets this entity.
pub fn observe<E: Event, B: Bundle, M>(self, system: impl IntoObserverSystem<E, B, M>) -> Self { pub fn observe<E: Event, B: Bundle, M>(self, system: impl IntoObserverSystem<E, B, M>) -> Self {
self.add(observe(system)) self.queue(observe(system))
} }
} }
@ -1736,12 +1731,12 @@ mod tests {
let mut commands = Commands::new(&mut command_queue, &world); let mut commands = Commands::new(&mut command_queue, &world);
// set up a simple command using a closure that adds one additional entity // set up a simple command using a closure that adds one additional entity
commands.add(|world: &mut World| { commands.queue(|world: &mut World| {
world.spawn((W(42u32), W(0u64))); world.spawn((W(42u32), W(0u64)));
}); });
// set up a simple command using a function that adds one additional entity // set up a simple command using a function that adds one additional entity
commands.add(simple_command); commands.queue(simple_command);
} }
command_queue.apply(&mut world); command_queue.apply(&mut world);
let results3 = world let results3 = world

View file

@ -479,20 +479,20 @@ mod test {
fn add_index(index: usize) -> impl Command { fn add_index(index: usize) -> impl Command {
move |world: &mut World| world.resource_mut::<Order>().0.push(index) move |world: &mut World| world.resource_mut::<Order>().0.push(index)
} }
world.commands().add(add_index(1)); world.commands().queue(add_index(1));
world.commands().add(|world: &mut World| { world.commands().queue(|world: &mut World| {
world.commands().add(add_index(2)); world.commands().queue(add_index(2));
world.commands().add(PanicCommand("I panic!".to_owned())); world.commands().queue(PanicCommand("I panic!".to_owned()));
world.commands().add(add_index(3)); world.commands().queue(add_index(3));
world.flush_commands(); world.flush_commands();
}); });
world.commands().add(add_index(4)); world.commands().queue(add_index(4));
let _ = panic::catch_unwind(AssertUnwindSafe(|| { let _ = panic::catch_unwind(AssertUnwindSafe(|| {
world.flush_commands(); world.flush_commands();
})); }));
world.commands().add(add_index(5)); world.commands().queue(add_index(5));
world.flush_commands(); world.flush_commands();
assert_eq!(&world.resource::<Order>().0, &[1, 2, 3, 4, 5]); assert_eq!(&world.resource::<Order>().0, &[1, 2, 3, 4, 5]);
} }

View file

@ -61,7 +61,7 @@ use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};
/// A [`World`] mutation. /// A [`World`] mutation.
/// ///
/// Should be used with [`Commands::add`]. /// Should be used with [`Commands::queue`].
/// ///
/// # Usage /// # Usage
/// ///
@ -83,7 +83,7 @@ use unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell};
/// } /// }
/// ///
/// fn some_system(mut commands: Commands) { /// fn some_system(mut commands: Commands) {
/// commands.add(AddToCounter(42)); /// commands.queue(AddToCounter(42));
/// } /// }
/// ``` /// ```
pub trait Command: Send + 'static { pub trait Command: Send + 'static {

View file

@ -304,8 +304,8 @@ pub trait ChildBuild {
/// Returns the parent entity. /// Returns the parent entity.
fn parent_entity(&self) -> Entity; fn parent_entity(&self) -> Entity;
/// Adds a command to be executed, like [`Commands::add`]. /// Adds a command to be executed, like [`Commands::queue`].
fn add_command<C: Command>(&mut self, command: C) -> &mut Self; fn enqueue_command<C: Command>(&mut self, command: C) -> &mut Self;
} }
impl ChildBuild for ChildBuilder<'_> { impl ChildBuild for ChildBuilder<'_> {
@ -327,8 +327,8 @@ impl ChildBuild for ChildBuilder<'_> {
self.add_children.parent self.add_children.parent
} }
fn add_command<C: Command>(&mut self, command: C) -> &mut Self { fn enqueue_command<C: Command>(&mut self, command: C) -> &mut Self {
self.commands.add(command); self.commands.queue(command);
self self
} }
} }
@ -439,14 +439,14 @@ impl BuildChildren for EntityCommands<'_> {
if children.children.contains(&parent) { if children.children.contains(&parent) {
panic!("Entity cannot be a child of itself."); panic!("Entity cannot be a child of itself.");
} }
self.commands().add(children); self.commands().queue(children);
self self
} }
fn with_child<B: Bundle>(&mut self, bundle: B) -> &mut Self { fn with_child<B: Bundle>(&mut self, bundle: B) -> &mut Self {
let parent = self.id(); let parent = self.id();
let child = self.commands().spawn(bundle).id(); let child = self.commands().spawn(bundle).id();
self.commands().add(AddChild { parent, child }); self.commands().queue(AddChild { parent, child });
self self
} }
@ -455,7 +455,7 @@ impl BuildChildren for EntityCommands<'_> {
if children.contains(&parent) { if children.contains(&parent) {
panic!("Cannot push entity as a child of itself."); panic!("Cannot push entity as a child of itself.");
} }
self.commands().add(AddChildren { self.commands().queue(AddChildren {
children: SmallVec::from(children), children: SmallVec::from(children),
parent, parent,
}); });
@ -467,7 +467,7 @@ impl BuildChildren for EntityCommands<'_> {
if children.contains(&parent) { if children.contains(&parent) {
panic!("Cannot insert entity as a child of itself."); panic!("Cannot insert entity as a child of itself.");
} }
self.commands().add(InsertChildren { self.commands().queue(InsertChildren {
children: SmallVec::from(children), children: SmallVec::from(children),
index, index,
parent, parent,
@ -477,7 +477,7 @@ impl BuildChildren for EntityCommands<'_> {
fn remove_children(&mut self, children: &[Entity]) -> &mut Self { fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
let parent = self.id(); let parent = self.id();
self.commands().add(RemoveChildren { self.commands().queue(RemoveChildren {
children: SmallVec::from(children), children: SmallVec::from(children),
parent, parent,
}); });
@ -489,13 +489,13 @@ impl BuildChildren for EntityCommands<'_> {
if child == parent { if child == parent {
panic!("Cannot add entity as a child of itself."); panic!("Cannot add entity as a child of itself.");
} }
self.commands().add(AddChild { child, parent }); self.commands().queue(AddChild { child, parent });
self self
} }
fn clear_children(&mut self) -> &mut Self { fn clear_children(&mut self) -> &mut Self {
let parent = self.id(); let parent = self.id();
self.commands().add(ClearChildren { parent }); self.commands().queue(ClearChildren { parent });
self self
} }
@ -504,7 +504,7 @@ impl BuildChildren for EntityCommands<'_> {
if children.contains(&parent) { if children.contains(&parent) {
panic!("Cannot replace entity as a child of itself."); panic!("Cannot replace entity as a child of itself.");
} }
self.commands().add(ReplaceChildren { self.commands().queue(ReplaceChildren {
children: SmallVec::from(children), children: SmallVec::from(children),
parent, parent,
}); });
@ -516,13 +516,13 @@ impl BuildChildren for EntityCommands<'_> {
if child == parent { if child == parent {
panic!("Cannot set parent to itself"); panic!("Cannot set parent to itself");
} }
self.commands().add(AddChild { child, parent }); self.commands().queue(AddChild { child, parent });
self self
} }
fn remove_parent(&mut self) -> &mut Self { fn remove_parent(&mut self) -> &mut Self {
let child = self.id(); let child = self.id();
self.commands().add(RemoveParent { child }); self.commands().queue(RemoveParent { child });
self self
} }
} }
@ -567,7 +567,7 @@ impl ChildBuild for WorldChildBuilder<'_> {
self.parent self.parent
} }
fn add_command<C: Command>(&mut self, command: C) -> &mut Self { fn enqueue_command<C: Command>(&mut self, command: C) -> &mut Self {
command.apply(self.world); command.apply(self.world);
self self
} }

View file

@ -94,12 +94,12 @@ impl DespawnRecursiveExt for EntityCommands<'_> {
/// This will emit warnings for any entity that does not exist. /// This will emit warnings for any entity that does not exist.
fn despawn_recursive(mut self) { fn despawn_recursive(mut self) {
let entity = self.id(); let entity = self.id();
self.commands().add(DespawnRecursive { entity }); self.commands().queue(DespawnRecursive { entity });
} }
fn despawn_descendants(&mut self) -> &mut Self { fn despawn_descendants(&mut self) -> &mut Self {
let entity = self.id(); let entity = self.id();
self.commands().add(DespawnChildrenRecursive { entity }); self.commands().queue(DespawnChildrenRecursive { entity });
self self
} }
} }

View file

@ -820,7 +820,7 @@ pub fn check_dir_light_mesh_visibility(
// Defer marking view visibility so this system can run in parallel with check_point_light_mesh_visibility // Defer marking view visibility so this system can run in parallel with check_point_light_mesh_visibility
// TODO: use resource to avoid unnecessary memory alloc // TODO: use resource to avoid unnecessary memory alloc
let mut defer_queue = std::mem::take(defer_visible_entities_queue.deref_mut()); let mut defer_queue = std::mem::take(defer_visible_entities_queue.deref_mut());
commands.add(move |world: &mut World| { commands.queue(move |world: &mut World| {
let mut query = world.query::<&mut ViewVisibility>(); let mut query = world.query::<&mut ViewVisibility>();
for entities in defer_queue.iter_mut() { for entities in defer_queue.iter_mut() {
let mut iter = query.iter_many_mut(world, entities.iter()); let mut iter = query.iter_many_mut(world, entities.iter());

View file

@ -17,7 +17,7 @@ pub trait CommandsStatesExt {
impl CommandsStatesExt for Commands<'_, '_> { impl CommandsStatesExt for Commands<'_, '_> {
fn set_state<S: FreelyMutableState>(&mut self, state: S) { fn set_state<S: FreelyMutableState>(&mut self, state: S) {
self.add(move |w: &mut World| { self.queue(move |w: &mut World| {
let mut next = w.resource_mut::<NextState<S>>(); let mut next = w.resource_mut::<NextState<S>>();
if let NextState::Pending(prev) = &*next { if let NextState::Pending(prev) = &*next {
if *prev != state { if *prev != state {

View file

@ -61,7 +61,7 @@ fn cleanup_state_scoped_event<S: FreelyMutableState>(
return; return;
}; };
c.add(move |w: &mut World| { c.queue(move |w: &mut World| {
w.resource_scope::<StateScopedEvents<S>, ()>(|w, events| { w.resource_scope::<StateScopedEvents<S>, ()>(|w, events| {
events.cleanup(w, exited); events.cleanup(w, exited);
}); });

View file

@ -91,13 +91,13 @@ pub trait BuildChildrenTransformExt {
impl BuildChildrenTransformExt for EntityCommands<'_> { impl BuildChildrenTransformExt for EntityCommands<'_> {
fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self { fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self {
let child = self.id(); let child = self.id();
self.commands().add(AddChildInPlace { child, parent }); self.commands().queue(AddChildInPlace { child, parent });
self self
} }
fn remove_parent_in_place(&mut self) -> &mut Self { fn remove_parent_in_place(&mut self) -> &mut Self {
let child = self.id(); let child = self.id();
self.commands().add(RemoveParentInPlace { child }); self.commands().queue(RemoveParentInPlace { child });
self self
} }
} }