bevy_ecs/system/commands/mod.rs
1pub mod command;
2pub mod entity_command;
3
4#[cfg(feature = "std")]
5mod parallel_scope;
6
7pub use command::Command;
8pub use entity_command::EntityCommand;
9
10#[cfg(feature = "std")]
11pub use parallel_scope::*;
12
13use alloc::boxed::Box;
14use core::marker::PhantomData;
15use log::error;
16
17use crate::{
18 self as bevy_ecs,
19 bundle::{Bundle, InsertMode, NoBundleEffect},
20 change_detection::{MaybeLocation, Mut},
21 component::{Component, ComponentId, Mutable},
22 entity::{Entities, Entity, EntityClonerBuilder, EntityDoesNotExistError},
23 error::{ignore, warn, BevyError, CommandWithEntity, ErrorContext, HandleError},
24 event::Event,
25 observer::{Observer, TriggerTargets},
26 resource::Resource,
27 schedule::ScheduleLabel,
28 system::{
29 Deferred, IntoObserverSystem, IntoSystem, RegisteredSystem, SystemId, SystemInput,
30 SystemParamValidationError,
31 },
32 world::{
33 command_queue::RawCommandQueue, unsafe_world_cell::UnsafeWorldCell, CommandQueue,
34 EntityWorldMut, FromWorld, World,
35 },
36};
37
38/// A [`Command`] queue to perform structural changes to the [`World`].
39///
40/// Since each command requires exclusive access to the `World`,
41/// all queued commands are automatically applied in sequence
42/// when the `ApplyDeferred` system runs (see [`ApplyDeferred`] documentation for more details).
43///
44/// Each command can be used to modify the [`World`] in arbitrary ways:
45/// * spawning or despawning entities
46/// * inserting components on new or existing entities
47/// * inserting resources
48/// * etc.
49///
50/// For a version of [`Commands`] that works in parallel contexts (such as
51/// within [`Query::par_iter`](crate::system::Query::par_iter)) see
52/// [`ParallelCommands`]
53///
54/// # Usage
55///
56/// Add `mut commands: Commands` as a function argument to your system to get a
57/// copy of this struct that will be applied the next time a copy of [`ApplyDeferred`] runs.
58/// Commands are almost always used as a [`SystemParam`](crate::system::SystemParam).
59///
60/// ```
61/// # use bevy_ecs::prelude::*;
62/// fn my_system(mut commands: Commands) {
63/// // ...
64/// }
65/// # bevy_ecs::system::assert_is_system(my_system);
66/// ```
67///
68/// # Implementing
69///
70/// Each built-in command is implemented as a separate method, e.g. [`Commands::spawn`].
71/// In addition to the pre-defined command methods, you can add commands with any arbitrary
72/// behavior using [`Commands::queue`], which accepts any type implementing [`Command`].
73///
74/// Since closures and other functions implement this trait automatically, this allows one-shot,
75/// anonymous custom commands.
76///
77/// ```
78/// # use bevy_ecs::prelude::*;
79/// # fn foo(mut commands: Commands) {
80/// // NOTE: type inference fails here, so annotations are required on the closure.
81/// commands.queue(|w: &mut World| {
82/// // Mutate the world however you want...
83/// });
84/// # }
85/// ```
86///
87/// # Error handling
88///
89/// A [`Command`] can return a [`Result`](crate::error::Result),
90/// which will be passed to an [error handler](crate::error) if the `Result` is an error.
91///
92/// The [default error handler](crate::error::default_error_handler) panics.
93/// It can be configured by setting the `GLOBAL_ERROR_HANDLER`.
94///
95/// Alternatively, you can customize the error handler for a specific command
96/// by calling [`Commands::queue_handled`].
97///
98/// The [`error`](crate::error) module provides some simple error handlers for convenience.
99///
100/// [`ApplyDeferred`]: crate::schedule::ApplyDeferred
101pub struct Commands<'w, 's> {
102 queue: InternalQueue<'s>,
103 entities: &'w Entities,
104}
105
106// SAFETY: All commands [`Command`] implement [`Send`]
107unsafe impl Send for Commands<'_, '_> {}
108
109// SAFETY: `Commands` never gives access to the inner commands.
110unsafe impl Sync for Commands<'_, '_> {}
111
112const _: () = {
113 type __StructFieldsAlias<'w, 's> = (Deferred<'s, CommandQueue>, &'w Entities);
114 #[doc(hidden)]
115 pub struct FetchState {
116 state: <__StructFieldsAlias<'static, 'static> as bevy_ecs::system::SystemParam>::State,
117 }
118 // SAFETY: Only reads Entities
119 unsafe impl bevy_ecs::system::SystemParam for Commands<'_, '_> {
120 type State = FetchState;
121
122 type Item<'w, 's> = Commands<'w, 's>;
123
124 fn init_state(
125 world: &mut World,
126 system_meta: &mut bevy_ecs::system::SystemMeta,
127 ) -> Self::State {
128 FetchState {
129 state: <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_state(
130 world,
131 system_meta,
132 ),
133 }
134 }
135
136 unsafe fn new_archetype(
137 state: &mut Self::State,
138 archetype: &bevy_ecs::archetype::Archetype,
139 system_meta: &mut bevy_ecs::system::SystemMeta,
140 ) {
141 // SAFETY: Caller guarantees the archetype is from the world used in `init_state`
142 unsafe {
143 <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::new_archetype(
144 &mut state.state,
145 archetype,
146 system_meta,
147 );
148 };
149 }
150
151 fn apply(
152 state: &mut Self::State,
153 system_meta: &bevy_ecs::system::SystemMeta,
154 world: &mut World,
155 ) {
156 <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::apply(
157 &mut state.state,
158 system_meta,
159 world,
160 );
161 }
162
163 fn queue(
164 state: &mut Self::State,
165 system_meta: &bevy_ecs::system::SystemMeta,
166 world: bevy_ecs::world::DeferredWorld,
167 ) {
168 <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::queue(
169 &mut state.state,
170 system_meta,
171 world,
172 );
173 }
174
175 #[inline]
176 unsafe fn validate_param(
177 state: &Self::State,
178 system_meta: &bevy_ecs::system::SystemMeta,
179 world: UnsafeWorldCell,
180 ) -> Result<(), SystemParamValidationError> {
181 <(Deferred<CommandQueue>, &Entities) as bevy_ecs::system::SystemParam>::validate_param(
182 &state.state,
183 system_meta,
184 world,
185 )
186 }
187
188 #[inline]
189 unsafe fn get_param<'w, 's>(
190 state: &'s mut Self::State,
191 system_meta: &bevy_ecs::system::SystemMeta,
192 world: UnsafeWorldCell<'w>,
193 change_tick: bevy_ecs::component::Tick,
194 ) -> Self::Item<'w, 's> {
195 let(f0, f1) = <(Deferred<'s, CommandQueue>, &'w Entities) as bevy_ecs::system::SystemParam>::get_param(&mut state.state, system_meta, world, change_tick);
196 Commands {
197 queue: InternalQueue::CommandQueue(f0),
198 entities: f1,
199 }
200 }
201 }
202 // SAFETY: Only reads Entities
203 unsafe impl<'w, 's> bevy_ecs::system::ReadOnlySystemParam for Commands<'w, 's>
204 where
205 Deferred<'s, CommandQueue>: bevy_ecs::system::ReadOnlySystemParam,
206 &'w Entities: bevy_ecs::system::ReadOnlySystemParam,
207 {
208 }
209};
210
211enum InternalQueue<'s> {
212 CommandQueue(Deferred<'s, CommandQueue>),
213 RawCommandQueue(RawCommandQueue),
214}
215
216impl<'w, 's> Commands<'w, 's> {
217 /// Returns a new `Commands` instance from a [`CommandQueue`] and a [`World`].
218 pub fn new(queue: &'s mut CommandQueue, world: &'w World) -> Self {
219 Self::new_from_entities(queue, &world.entities)
220 }
221
222 /// Returns a new `Commands` instance from a [`CommandQueue`] and an [`Entities`] reference.
223 pub fn new_from_entities(queue: &'s mut CommandQueue, entities: &'w Entities) -> Self {
224 Self {
225 queue: InternalQueue::CommandQueue(Deferred(queue)),
226 entities,
227 }
228 }
229
230 /// Returns a new `Commands` instance from a [`RawCommandQueue`] and an [`Entities`] reference.
231 ///
232 /// This is used when constructing [`Commands`] from a [`DeferredWorld`](crate::world::DeferredWorld).
233 ///
234 /// # Safety
235 ///
236 /// * Caller ensures that `queue` must outlive `'w`
237 pub(crate) unsafe fn new_raw_from_entities(
238 queue: RawCommandQueue,
239 entities: &'w Entities,
240 ) -> Self {
241 Self {
242 queue: InternalQueue::RawCommandQueue(queue),
243 entities,
244 }
245 }
246
247 /// Returns a [`Commands`] with a smaller lifetime.
248 ///
249 /// This is useful if you have `&mut Commands` but need `Commands`.
250 ///
251 /// # Example
252 ///
253 /// ```
254 /// # use bevy_ecs::prelude::*;
255 /// fn my_system(mut commands: Commands) {
256 /// // We do our initialization in a separate function,
257 /// // which expects an owned `Commands`.
258 /// do_initialization(commands.reborrow());
259 ///
260 /// // Since we only reborrowed the commands instead of moving them, we can still use them.
261 /// commands.spawn_empty();
262 /// }
263 /// #
264 /// # fn do_initialization(_: Commands) {}
265 /// ```
266 pub fn reborrow(&mut self) -> Commands<'w, '_> {
267 Commands {
268 queue: match &mut self.queue {
269 InternalQueue::CommandQueue(queue) => InternalQueue::CommandQueue(queue.reborrow()),
270 InternalQueue::RawCommandQueue(queue) => {
271 InternalQueue::RawCommandQueue(queue.clone())
272 }
273 },
274 entities: self.entities,
275 }
276 }
277
278 /// Take all commands from `other` and append them to `self`, leaving `other` empty.
279 pub fn append(&mut self, other: &mut CommandQueue) {
280 match &mut self.queue {
281 InternalQueue::CommandQueue(queue) => queue.bytes.append(&mut other.bytes),
282 InternalQueue::RawCommandQueue(queue) => {
283 // SAFETY: Pointers in `RawCommandQueue` are never null
284 unsafe { queue.bytes.as_mut() }.append(&mut other.bytes);
285 }
286 }
287 }
288
289 /// Spawns a new empty [`Entity`] and returns its corresponding [`EntityCommands`].
290 ///
291 /// # Example
292 ///
293 /// ```
294 /// # use bevy_ecs::prelude::*;
295 /// #[derive(Component)]
296 /// struct Label(&'static str);
297 /// #[derive(Component)]
298 /// struct Strength(u32);
299 /// #[derive(Component)]
300 /// struct Agility(u32);
301 ///
302 /// fn example_system(mut commands: Commands) {
303 /// // Create a new empty entity.
304 /// commands.spawn_empty();
305 ///
306 /// // Create another empty entity.
307 /// commands.spawn_empty()
308 /// // Add a new component bundle to the entity.
309 /// .insert((Strength(1), Agility(2)))
310 /// // Add a single component to the entity.
311 /// .insert(Label("hello world"));
312 /// }
313 /// # bevy_ecs::system::assert_is_system(example_system);
314 /// ```
315 ///
316 /// # See also
317 ///
318 /// - [`spawn`](Self::spawn) to spawn an entity with components.
319 /// - [`spawn_batch`](Self::spawn_batch) to spawn many entities
320 /// with the same combination of components.
321 #[track_caller]
322 pub fn spawn_empty(&mut self) -> EntityCommands {
323 let entity = self.entities.reserve_entity();
324 let mut entity_commands = EntityCommands {
325 entity,
326 commands: self.reborrow(),
327 };
328 let caller = MaybeLocation::caller();
329 entity_commands.queue(move |entity: EntityWorldMut| {
330 let index = entity.id().index();
331 let world = entity.into_world_mut();
332 let tick = world.change_tick();
333 // SAFETY: Entity has been flushed
334 unsafe {
335 world.entities_mut().mark_spawn_despawn(index, caller, tick);
336 }
337 });
338 entity_commands
339 }
340
341 /// Spawns a new [`Entity`] with the given components
342 /// and returns the entity's corresponding [`EntityCommands`].
343 ///
344 /// To spawn many entities with the same combination of components,
345 /// [`spawn_batch`](Self::spawn_batch) can be used for better performance.
346 ///
347 /// # Example
348 ///
349 /// ```
350 /// # use bevy_ecs::prelude::*;
351 /// #[derive(Component)]
352 /// struct ComponentA(u32);
353 /// #[derive(Component)]
354 /// struct ComponentB(u32);
355 ///
356 /// #[derive(Bundle)]
357 /// struct ExampleBundle {
358 /// a: ComponentA,
359 /// b: ComponentB,
360 /// }
361 ///
362 /// fn example_system(mut commands: Commands) {
363 /// // Create a new entity with a single component.
364 /// commands.spawn(ComponentA(1));
365 ///
366 /// // Create a new entity with two components using a "tuple bundle".
367 /// commands.spawn((ComponentA(2), ComponentB(1)));
368 ///
369 /// // Create a new entity with a component bundle.
370 /// commands.spawn(ExampleBundle {
371 /// a: ComponentA(3),
372 /// b: ComponentB(2),
373 /// });
374 /// }
375 /// # bevy_ecs::system::assert_is_system(example_system);
376 /// ```
377 ///
378 /// # See also
379 ///
380 /// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.
381 /// - [`spawn_batch`](Self::spawn_batch) to spawn many entities
382 /// with the same combination of components.
383 #[track_caller]
384 pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands {
385 let entity = self.entities.reserve_entity();
386 let mut entity_commands = EntityCommands {
387 entity,
388 commands: self.reborrow(),
389 };
390 let caller = MaybeLocation::caller();
391
392 entity_commands.queue(move |mut entity: EntityWorldMut| {
393 // Store metadata about the spawn operation.
394 // This is the same as in `spawn_empty`, but merged into
395 // the same command for better performance.
396 let index = entity.id().index();
397 entity.world_scope(|world| {
398 let tick = world.change_tick();
399 // SAFETY: Entity has been flushed
400 unsafe {
401 world.entities_mut().mark_spawn_despawn(index, caller, tick);
402 }
403 });
404
405 entity.insert_with_caller(
406 bundle,
407 InsertMode::Replace,
408 caller,
409 crate::relationship::RelationshipHookMode::Run,
410 );
411 });
412 // entity_command::insert(bundle, InsertMode::Replace)
413 entity_commands
414 }
415
416 /// Returns the [`EntityCommands`] for the given [`Entity`].
417 ///
418 /// This method does not guarantee that commands queued by the returned `EntityCommands`
419 /// will be successful, since the entity could be despawned before they are executed.
420 ///
421 /// # Example
422 ///
423 /// ```
424 /// # use bevy_ecs::prelude::*;
425 /// #[derive(Resource)]
426 /// struct PlayerEntity {
427 /// entity: Entity
428 /// }
429 ///
430 /// #[derive(Component)]
431 /// struct Label(&'static str);
432 ///
433 /// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) {
434 /// // Get the entity and add a component.
435 /// commands.entity(player.entity).insert(Label("hello world"));
436 /// }
437 /// # bevy_ecs::system::assert_is_system(example_system);
438 /// ```
439 ///
440 /// # See also
441 ///
442 /// - [`get_entity`](Self::get_entity) for the fallible version.
443 #[inline]
444 #[track_caller]
445 pub fn entity(&mut self, entity: Entity) -> EntityCommands {
446 EntityCommands {
447 entity,
448 commands: self.reborrow(),
449 }
450 }
451
452 /// Returns the [`EntityCommands`] for the requested [`Entity`] if it exists.
453 ///
454 /// This method does not guarantee that commands queued by the returned `EntityCommands`
455 /// will be successful, since the entity could be despawned before they are executed.
456 ///
457 /// # Errors
458 ///
459 /// Returns [`EntityDoesNotExistError`] if the requested entity does not exist.
460 ///
461 /// # Example
462 ///
463 /// ```
464 /// # use bevy_ecs::prelude::*;
465 /// #[derive(Resource)]
466 /// struct PlayerEntity {
467 /// entity: Entity
468 /// }
469 ///
470 /// #[derive(Component)]
471 /// struct Label(&'static str);
472 ///
473 /// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {
474 /// // Get the entity if it still exists and store the `EntityCommands`.
475 /// // If it doesn't exist, the `?` operator will propagate the returned error
476 /// // to the system, and the system will pass it to an error handler.
477 /// let mut entity_commands = commands.get_entity(player.entity)?;
478 ///
479 /// // Add a component to the entity.
480 /// entity_commands.insert(Label("hello world"));
481 ///
482 /// // Return from the system successfully.
483 /// Ok(())
484 /// }
485 /// # bevy_ecs::system::assert_is_system(example_system);
486 /// ```
487 ///
488 /// # See also
489 ///
490 /// - [`entity`](Self::entity) for the infallible version.
491 #[inline]
492 #[track_caller]
493 pub fn get_entity(
494 &mut self,
495 entity: Entity,
496 ) -> Result<EntityCommands, EntityDoesNotExistError> {
497 if self.entities.contains(entity) {
498 Ok(EntityCommands {
499 entity,
500 commands: self.reborrow(),
501 })
502 } else {
503 Err(EntityDoesNotExistError::new(entity, self.entities))
504 }
505 }
506
507 /// Spawns multiple entities with the same combination of components,
508 /// based on a batch of [`Bundles`](Bundle).
509 ///
510 /// A batch can be any type that implements [`IntoIterator`] and contains bundles,
511 /// such as a [`Vec<Bundle>`](alloc::vec::Vec) or an array `[Bundle; N]`.
512 ///
513 /// This method is equivalent to iterating the batch
514 /// and calling [`spawn`](Self::spawn) for each bundle,
515 /// but is faster by pre-allocating memory and having exclusive [`World`] access.
516 ///
517 /// # Example
518 ///
519 /// ```
520 /// use bevy_ecs::prelude::*;
521 ///
522 /// #[derive(Component)]
523 /// struct Score(u32);
524 ///
525 /// fn example_system(mut commands: Commands) {
526 /// commands.spawn_batch([
527 /// (Name::new("Alice"), Score(0)),
528 /// (Name::new("Bob"), Score(0)),
529 /// ]);
530 /// }
531 /// # bevy_ecs::system::assert_is_system(example_system);
532 /// ```
533 ///
534 /// # See also
535 ///
536 /// - [`spawn`](Self::spawn) to spawn an entity with components.
537 /// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without components.
538 #[track_caller]
539 pub fn spawn_batch<I>(&mut self, batch: I)
540 where
541 I: IntoIterator + Send + Sync + 'static,
542 I::Item: Bundle<Effect: NoBundleEffect>,
543 {
544 self.queue(command::spawn_batch(batch));
545 }
546
547 /// Pushes a generic [`Command`] to the command queue.
548 ///
549 /// If the [`Command`] returns a [`Result`],
550 /// it will be handled using the [default error handler](crate::error::default_error_handler).
551 ///
552 /// To use a custom error handler, see [`Commands::queue_handled`].
553 ///
554 /// The command can be:
555 /// - A custom struct that implements [`Command`].
556 /// - A closure or function that matches one of the following signatures:
557 /// - [`(&mut World)`](World)
558 /// - A built-in command from the [`command`] module.
559 ///
560 /// # Example
561 ///
562 /// ```
563 /// # use bevy_ecs::prelude::*;
564 /// #[derive(Resource, Default)]
565 /// struct Counter(u64);
566 ///
567 /// struct AddToCounter(String);
568 ///
569 /// impl Command<Result> for AddToCounter {
570 /// fn apply(self, world: &mut World) -> Result {
571 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
572 /// let amount: u64 = self.0.parse()?;
573 /// counter.0 += amount;
574 /// Ok(())
575 /// }
576 /// }
577 ///
578 /// fn add_three_to_counter_system(mut commands: Commands) {
579 /// commands.queue(AddToCounter("3".to_string()));
580 /// }
581 ///
582 /// fn add_twenty_five_to_counter_system(mut commands: Commands) {
583 /// commands.queue(|world: &mut World| {
584 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
585 /// counter.0 += 25;
586 /// });
587 /// }
588 /// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
589 /// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
590 /// ```
591 pub fn queue<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {
592 self.queue_internal(command.handle_error());
593 }
594
595 /// Pushes a generic [`Command`] to the command queue.
596 ///
597 /// If the [`Command`] returns a [`Result`],
598 /// the given `error_handler` will be used to handle error cases.
599 ///
600 /// To implicitly use the default error handler, see [`Commands::queue`].
601 ///
602 /// The command can be:
603 /// - A custom struct that implements [`Command`].
604 /// - A closure or function that matches one of the following signatures:
605 /// - [`(&mut World)`](World)
606 /// - [`(&mut World)`](World) `->` [`Result`]
607 /// - A built-in command from the [`command`] module.
608 ///
609 /// # Example
610 ///
611 /// ```
612 /// # use bevy_ecs::prelude::*;
613 /// use bevy_ecs::error::warn;
614 ///
615 /// #[derive(Resource, Default)]
616 /// struct Counter(u64);
617 ///
618 /// struct AddToCounter(String);
619 ///
620 /// impl Command<Result> for AddToCounter {
621 /// fn apply(self, world: &mut World) -> Result {
622 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
623 /// let amount: u64 = self.0.parse()?;
624 /// counter.0 += amount;
625 /// Ok(())
626 /// }
627 /// }
628 ///
629 /// fn add_three_to_counter_system(mut commands: Commands) {
630 /// commands.queue_handled(AddToCounter("3".to_string()), warn);
631 /// }
632 ///
633 /// fn add_twenty_five_to_counter_system(mut commands: Commands) {
634 /// commands.queue(|world: &mut World| {
635 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
636 /// counter.0 += 25;
637 /// });
638 /// }
639 /// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
640 /// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
641 /// ```
642 pub fn queue_handled<C: Command<T> + HandleError<T>, T>(
643 &mut self,
644 command: C,
645 error_handler: fn(BevyError, ErrorContext),
646 ) {
647 self.queue_internal(command.handle_error_with(error_handler));
648 }
649
650 fn queue_internal(&mut self, command: impl Command) {
651 match &mut self.queue {
652 InternalQueue::CommandQueue(queue) => {
653 queue.push(command);
654 }
655 InternalQueue::RawCommandQueue(queue) => {
656 // SAFETY: `RawCommandQueue` is only every constructed in `Commands::new_raw_from_entities`
657 // where the caller of that has ensured that `queue` outlives `self`
658 unsafe {
659 queue.push(command);
660 }
661 }
662 }
663 }
664
665 /// Pushes a [`Command`] to the queue for creating entities, if needed,
666 /// and for adding a bundle to each entity.
667 ///
668 /// `bundles_iter` is a type that can be converted into an ([`Entity`], [`Bundle`]) iterator
669 /// (it can also be a collection).
670 ///
671 /// When the command is applied,
672 /// for each (`Entity`, `Bundle`) pair in the given `bundles_iter`,
673 /// the `Entity` is spawned, if it does not exist already.
674 /// Then, the `Bundle` is added to the entity.
675 ///
676 /// This method is equivalent to iterating `bundles_iter`,
677 /// calling [`spawn`](Self::spawn) for each bundle,
678 /// and passing it to [`insert`](EntityCommands::insert),
679 /// but it is faster due to memory pre-allocation.
680 ///
681 /// # Note
682 ///
683 /// Spawning a specific `entity` value is rarely the right choice. Most apps should use [`Commands::spawn_batch`].
684 /// This method should generally only be used for sharing entities across apps, and only when they have a scheme
685 /// worked out to share an ID space (which doesn't happen by default).
686 #[track_caller]
687 #[deprecated(
688 since = "0.16.0",
689 note = "This can cause extreme performance problems when used with lots of arbitrary free entities. See #18054 on GitHub."
690 )]
691 pub fn insert_or_spawn_batch<I, B>(&mut self, bundles_iter: I)
692 where
693 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
694 B: Bundle<Effect: NoBundleEffect>,
695 {
696 let caller = MaybeLocation::caller();
697 self.queue(move |world: &mut World| {
698
699 #[expect(
700 deprecated,
701 reason = "This needs to be supported for now, and the outer item is deprecated too."
702 )]
703 if let Err(invalid_entities) = world.insert_or_spawn_batch_with_caller(
704 bundles_iter,
705 caller,
706 ) {
707 error!(
708 "{caller}: Failed to 'insert or spawn' bundle of type {} into the following invalid entities: {:?}",
709 core::any::type_name::<B>(),
710 invalid_entities
711 );
712 }
713 });
714 }
715
716 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
717 /// based on a batch of `(Entity, Bundle)` pairs.
718 ///
719 /// A batch can be any type that implements [`IntoIterator`]
720 /// and contains `(Entity, Bundle)` tuples,
721 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
722 /// or an array `[(Entity, Bundle); N]`.
723 ///
724 /// This will overwrite any pre-existing components shared by the [`Bundle`] type.
725 /// Use [`Commands::insert_batch_if_new`] to keep the pre-existing components instead.
726 ///
727 /// This method is equivalent to iterating the batch
728 /// and calling [`insert`](EntityCommands::insert) for each pair,
729 /// but is faster by caching data that is shared between entities.
730 ///
731 /// # Fallible
732 ///
733 /// This command will fail if any of the given entities do not exist.
734 ///
735 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
736 /// which will be handled by the [default error handler](crate::error::default_error_handler).
737 #[track_caller]
738 pub fn insert_batch<I, B>(&mut self, batch: I)
739 where
740 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
741 B: Bundle<Effect: NoBundleEffect>,
742 {
743 self.queue(command::insert_batch(batch, InsertMode::Replace));
744 }
745
746 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
747 /// based on a batch of `(Entity, Bundle)` pairs.
748 ///
749 /// A batch can be any type that implements [`IntoIterator`]
750 /// and contains `(Entity, Bundle)` tuples,
751 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
752 /// or an array `[(Entity, Bundle); N]`.
753 ///
754 /// This will keep any pre-existing components shared by the [`Bundle`] type
755 /// and discard the new values.
756 /// Use [`Commands::insert_batch`] to overwrite the pre-existing components instead.
757 ///
758 /// This method is equivalent to iterating the batch
759 /// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,
760 /// but is faster by caching data that is shared between entities.
761 ///
762 /// # Fallible
763 ///
764 /// This command will fail if any of the given entities do not exist.
765 ///
766 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
767 /// which will be handled by the [default error handler](crate::error::default_error_handler).
768 #[track_caller]
769 pub fn insert_batch_if_new<I, B>(&mut self, batch: I)
770 where
771 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
772 B: Bundle<Effect: NoBundleEffect>,
773 {
774 self.queue(command::insert_batch(batch, InsertMode::Keep));
775 }
776
777 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
778 /// based on a batch of `(Entity, Bundle)` pairs.
779 ///
780 /// A batch can be any type that implements [`IntoIterator`]
781 /// and contains `(Entity, Bundle)` tuples,
782 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
783 /// or an array `[(Entity, Bundle); N]`.
784 ///
785 /// This will overwrite any pre-existing components shared by the [`Bundle`] type.
786 /// Use [`Commands::try_insert_batch_if_new`] to keep the pre-existing components instead.
787 ///
788 /// This method is equivalent to iterating the batch
789 /// and calling [`insert`](EntityCommands::insert) for each pair,
790 /// but is faster by caching data that is shared between entities.
791 ///
792 /// # Fallible
793 ///
794 /// This command will fail if any of the given entities do not exist.
795 ///
796 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
797 /// which will be handled by [logging the error at the `warn` level](warn).
798 #[track_caller]
799 pub fn try_insert_batch<I, B>(&mut self, batch: I)
800 where
801 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
802 B: Bundle<Effect: NoBundleEffect>,
803 {
804 self.queue(command::insert_batch(batch, InsertMode::Replace).handle_error_with(warn));
805 }
806
807 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
808 /// based on a batch of `(Entity, Bundle)` pairs.
809 ///
810 /// A batch can be any type that implements [`IntoIterator`]
811 /// and contains `(Entity, Bundle)` tuples,
812 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
813 /// or an array `[(Entity, Bundle); N]`.
814 ///
815 /// This will keep any pre-existing components shared by the [`Bundle`] type
816 /// and discard the new values.
817 /// Use [`Commands::try_insert_batch`] to overwrite the pre-existing components instead.
818 ///
819 /// This method is equivalent to iterating the batch
820 /// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,
821 /// but is faster by caching data that is shared between entities.
822 ///
823 /// # Fallible
824 ///
825 /// This command will fail if any of the given entities do not exist.
826 ///
827 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
828 /// which will be handled by [logging the error at the `warn` level](warn).
829 #[track_caller]
830 pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I)
831 where
832 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
833 B: Bundle<Effect: NoBundleEffect>,
834 {
835 self.queue(command::insert_batch(batch, InsertMode::Keep).handle_error_with(warn));
836 }
837
838 /// Inserts a [`Resource`] into the [`World`] with an inferred value.
839 ///
840 /// The inferred value is determined by the [`FromWorld`] trait of the resource.
841 /// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],
842 /// and those default values will be used.
843 ///
844 /// If the resource already exists when the command is applied, nothing happens.
845 ///
846 /// # Example
847 ///
848 /// ```
849 /// # use bevy_ecs::prelude::*;
850 /// #[derive(Resource, Default)]
851 /// struct Scoreboard {
852 /// current_score: u32,
853 /// high_score: u32,
854 /// }
855 ///
856 /// fn initialize_scoreboard(mut commands: Commands) {
857 /// commands.init_resource::<Scoreboard>();
858 /// }
859 /// # bevy_ecs::system::assert_is_system(initialize_scoreboard);
860 /// ```
861 #[track_caller]
862 pub fn init_resource<R: Resource + FromWorld>(&mut self) {
863 self.queue(command::init_resource::<R>());
864 }
865
866 /// Inserts a [`Resource`] into the [`World`] with a specific value.
867 ///
868 /// This will overwrite any previous value of the same resource type.
869 ///
870 /// # Example
871 ///
872 /// ```
873 /// # use bevy_ecs::prelude::*;
874 /// #[derive(Resource)]
875 /// struct Scoreboard {
876 /// current_score: u32,
877 /// high_score: u32,
878 /// }
879 ///
880 /// fn system(mut commands: Commands) {
881 /// commands.insert_resource(Scoreboard {
882 /// current_score: 0,
883 /// high_score: 0,
884 /// });
885 /// }
886 /// # bevy_ecs::system::assert_is_system(system);
887 /// ```
888 #[track_caller]
889 pub fn insert_resource<R: Resource>(&mut self, resource: R) {
890 self.queue(command::insert_resource(resource));
891 }
892
893 /// Removes a [`Resource`] from the [`World`].
894 ///
895 /// # Example
896 ///
897 /// ```
898 /// # use bevy_ecs::prelude::*;
899 /// #[derive(Resource)]
900 /// struct Scoreboard {
901 /// current_score: u32,
902 /// high_score: u32,
903 /// }
904 ///
905 /// fn system(mut commands: Commands) {
906 /// commands.remove_resource::<Scoreboard>();
907 /// }
908 /// # bevy_ecs::system::assert_is_system(system);
909 /// ```
910 pub fn remove_resource<R: Resource>(&mut self) {
911 self.queue(command::remove_resource::<R>());
912 }
913
914 /// Runs the system corresponding to the given [`SystemId`].
915 /// Before running a system, it must first be registered via
916 /// [`Commands::register_system`] or [`World::register_system`].
917 ///
918 /// The system is run in an exclusive and single-threaded way.
919 /// Running slow systems can become a bottleneck.
920 ///
921 /// There is no way to get the output of a system when run as a command, because the
922 /// execution of the system happens later. To get the output of a system, use
923 /// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.
924 ///
925 /// # Fallible
926 ///
927 /// This command will fail if the given [`SystemId`]
928 /// does not correspond to a [`System`](crate::system::System).
929 ///
930 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
931 /// which will be handled by [logging the error at the `warn` level](warn).
932 pub fn run_system(&mut self, id: SystemId) {
933 self.queue(command::run_system(id).handle_error_with(warn));
934 }
935
936 /// Runs the system corresponding to the given [`SystemId`] with input.
937 /// Before running a system, it must first be registered via
938 /// [`Commands::register_system`] or [`World::register_system`].
939 ///
940 /// The system is run in an exclusive and single-threaded way.
941 /// Running slow systems can become a bottleneck.
942 ///
943 /// There is no way to get the output of a system when run as a command, because the
944 /// execution of the system happens later. To get the output of a system, use
945 /// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.
946 ///
947 /// # Fallible
948 ///
949 /// This command will fail if the given [`SystemId`]
950 /// does not correspond to a [`System`](crate::system::System).
951 ///
952 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
953 /// which will be handled by [logging the error at the `warn` level](warn).
954 pub fn run_system_with<I>(&mut self, id: SystemId<I>, input: I::Inner<'static>)
955 where
956 I: SystemInput<Inner<'static>: Send> + 'static,
957 {
958 self.queue(command::run_system_with(id, input).handle_error_with(warn));
959 }
960
961 /// Registers a system and returns its [`SystemId`] so it can later be called by
962 /// [`Commands::run_system`] or [`World::run_system`].
963 ///
964 /// This is different from adding systems to a [`Schedule`](crate::schedule::Schedule),
965 /// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.
966 ///
967 /// Using a [`Schedule`](crate::schedule::Schedule) is still preferred for most cases
968 /// due to its better performance and ability to run non-conflicting systems simultaneously.
969 ///
970 /// # Note
971 ///
972 /// If the same system is registered more than once,
973 /// each registration will be considered a different system,
974 /// and they will each be given their own [`SystemId`].
975 ///
976 /// If you want to avoid registering the same system multiple times,
977 /// consider using [`Commands::run_system_cached`] or storing the [`SystemId`]
978 /// in a [`Local`](crate::system::Local).
979 ///
980 /// # Example
981 ///
982 /// ```
983 /// # use bevy_ecs::{prelude::*, world::CommandQueue, system::SystemId};
984 /// #[derive(Resource)]
985 /// struct Counter(i32);
986 ///
987 /// fn register_system(
988 /// mut commands: Commands,
989 /// mut local_system: Local<Option<SystemId>>,
990 /// ) {
991 /// if let Some(system) = *local_system {
992 /// commands.run_system(system);
993 /// } else {
994 /// *local_system = Some(commands.register_system(increment_counter));
995 /// }
996 /// }
997 ///
998 /// fn increment_counter(mut value: ResMut<Counter>) {
999 /// value.0 += 1;
1000 /// }
1001 ///
1002 /// # let mut world = World::default();
1003 /// # world.insert_resource(Counter(0));
1004 /// # let mut queue_1 = CommandQueue::default();
1005 /// # let systemid = {
1006 /// # let mut commands = Commands::new(&mut queue_1, &world);
1007 /// # commands.register_system(increment_counter)
1008 /// # };
1009 /// # let mut queue_2 = CommandQueue::default();
1010 /// # {
1011 /// # let mut commands = Commands::new(&mut queue_2, &world);
1012 /// # commands.run_system(systemid);
1013 /// # }
1014 /// # queue_1.append(&mut queue_2);
1015 /// # queue_1.apply(&mut world);
1016 /// # assert_eq!(1, world.resource::<Counter>().0);
1017 /// # bevy_ecs::system::assert_is_system(register_system);
1018 /// ```
1019 pub fn register_system<I, O, M>(
1020 &mut self,
1021 system: impl IntoSystem<I, O, M> + 'static,
1022 ) -> SystemId<I, O>
1023 where
1024 I: SystemInput + Send + 'static,
1025 O: Send + 'static,
1026 {
1027 let entity = self.spawn_empty().id();
1028 let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));
1029 self.entity(entity).insert(system);
1030 SystemId::from_entity(entity)
1031 }
1032
1033 /// Removes a system previously registered with [`Commands::register_system`]
1034 /// or [`World::register_system`].
1035 ///
1036 /// After removing a system, the [`SystemId`] becomes invalid
1037 /// and attempting to use it afterwards will result in an error.
1038 /// Re-adding the removed system will register it with a new `SystemId`.
1039 ///
1040 /// # Fallible
1041 ///
1042 /// This command will fail if the given [`SystemId`]
1043 /// does not correspond to a [`System`](crate::system::System).
1044 ///
1045 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
1046 /// which will be handled by [logging the error at the `warn` level](warn).
1047 pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)
1048 where
1049 I: SystemInput + Send + 'static,
1050 O: Send + 'static,
1051 {
1052 self.queue(command::unregister_system(system_id).handle_error_with(warn));
1053 }
1054
1055 /// Removes a system previously registered with one of the following:
1056 /// - [`Commands::run_system_cached`]
1057 /// - [`World::run_system_cached`]
1058 /// - [`World::register_system_cached`]
1059 ///
1060 /// # Fallible
1061 ///
1062 /// This command will fail if the given system
1063 /// is not currently cached in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
1064 ///
1065 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
1066 /// which will be handled by [logging the error at the `warn` level](warn).
1067 pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)
1068 where
1069 I: SystemInput + Send + 'static,
1070 O: 'static,
1071 M: 'static,
1072 S: IntoSystem<I, O, M> + Send + 'static,
1073 {
1074 self.queue(command::unregister_system_cached(system).handle_error_with(warn));
1075 }
1076
1077 /// Runs a cached system, registering it if necessary.
1078 ///
1079 /// Unlike [`Commands::run_system`], this method does not require manual registration.
1080 ///
1081 /// The first time this method is called for a particular system,
1082 /// it will register the system and store its [`SystemId`] in a
1083 /// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.
1084 ///
1085 /// If you would rather manage the [`SystemId`] yourself,
1086 /// or register multiple copies of the same system,
1087 /// use [`Commands::register_system`] instead.
1088 ///
1089 /// # Limitations
1090 ///
1091 /// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of
1092 /// the same type must be equal. This means that closures that capture the environment, and
1093 /// function pointers, are not accepted.
1094 ///
1095 /// If you want to access values from the environment within a system,
1096 /// consider passing them in as inputs via [`Commands::run_system_cached_with`].
1097 ///
1098 /// If that's not an option, consider [`Commands::register_system`] instead.
1099 pub fn run_system_cached<M, S>(&mut self, system: S)
1100 where
1101 M: 'static,
1102 S: IntoSystem<(), (), M> + Send + 'static,
1103 {
1104 self.queue(command::run_system_cached(system).handle_error_with(warn));
1105 }
1106
1107 /// Runs a cached system with an input, registering it if necessary.
1108 ///
1109 /// Unlike [`Commands::run_system_with`], this method does not require manual registration.
1110 ///
1111 /// The first time this method is called for a particular system,
1112 /// it will register the system and store its [`SystemId`] in a
1113 /// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.
1114 ///
1115 /// If you would rather manage the [`SystemId`] yourself,
1116 /// or register multiple copies of the same system,
1117 /// use [`Commands::register_system`] instead.
1118 ///
1119 /// # Limitations
1120 ///
1121 /// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of
1122 /// the same type must be equal. This means that closures that capture the environment, and
1123 /// function pointers, are not accepted.
1124 ///
1125 /// If you want to access values from the environment within a system,
1126 /// consider passing them in as inputs.
1127 ///
1128 /// If that's not an option, consider [`Commands::register_system`] instead.
1129 pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)
1130 where
1131 I: SystemInput<Inner<'static>: Send> + Send + 'static,
1132 M: 'static,
1133 S: IntoSystem<I, (), M> + Send + 'static,
1134 {
1135 self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));
1136 }
1137
1138 /// Sends a "global" [`Trigger`](crate::observer::Trigger) without any targets.
1139 ///
1140 /// This will run any [`Observer`] of the given [`Event`] that isn't scoped to specific targets.
1141 #[track_caller]
1142 pub fn trigger(&mut self, event: impl Event) {
1143 self.queue(command::trigger(event));
1144 }
1145
1146 /// Sends a [`Trigger`](crate::observer::Trigger) for the given targets.
1147 ///
1148 /// This will run any [`Observer`] of the given [`Event`] watching those targets.
1149 #[track_caller]
1150 pub fn trigger_targets(
1151 &mut self,
1152 event: impl Event,
1153 targets: impl TriggerTargets + Send + Sync + 'static,
1154 ) {
1155 self.queue(command::trigger_targets(event, targets));
1156 }
1157
1158 /// Spawns an [`Observer`] and returns the [`EntityCommands`] associated
1159 /// with the entity that stores the observer.
1160 ///
1161 /// **Calling [`observe`](EntityCommands::observe) on the returned
1162 /// [`EntityCommands`] will observe the observer itself, which you very
1163 /// likely do not want.**
1164 pub fn add_observer<E: Event, B: Bundle, M>(
1165 &mut self,
1166 observer: impl IntoObserverSystem<E, B, M>,
1167 ) -> EntityCommands {
1168 self.spawn(Observer::new(observer))
1169 }
1170
1171 /// Sends an arbitrary [`Event`].
1172 ///
1173 /// This is a convenience method for sending events
1174 /// without requiring an [`EventWriter`](crate::event::EventWriter).
1175 ///
1176 /// # Performance
1177 ///
1178 /// Since this is a command, exclusive world access is used, which means that it will not profit from
1179 /// system-level parallelism on supported platforms.
1180 ///
1181 /// If these events are performance-critical or very frequently sent,
1182 /// consider using a typed [`EventWriter`](crate::event::EventWriter) instead.
1183 #[track_caller]
1184 pub fn send_event<E: Event>(&mut self, event: E) -> &mut Self {
1185 self.queue(command::send_event(event));
1186 self
1187 }
1188
1189 /// Runs the schedule corresponding to the given [`ScheduleLabel`].
1190 ///
1191 /// Calls [`World::try_run_schedule`](World::try_run_schedule).
1192 ///
1193 /// # Fallible
1194 ///
1195 /// This command will fail if the given [`ScheduleLabel`]
1196 /// does not correspond to a [`Schedule`](crate::schedule::Schedule).
1197 ///
1198 /// It will internally return a [`TryRunScheduleError`](crate::world::error::TryRunScheduleError),
1199 /// which will be handled by [logging the error at the `warn` level](warn).
1200 ///
1201 /// # Example
1202 ///
1203 /// ```
1204 /// # use bevy_ecs::prelude::*;
1205 /// # use bevy_ecs::schedule::ScheduleLabel;
1206 /// # #[derive(Default, Resource)]
1207 /// # struct Counter(u32);
1208 /// #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]
1209 /// struct FooSchedule;
1210 ///
1211 /// # fn foo_system(mut counter: ResMut<Counter>) {
1212 /// # counter.0 += 1;
1213 /// # }
1214 /// #
1215 /// # let mut schedule = Schedule::new(FooSchedule);
1216 /// # schedule.add_systems(foo_system);
1217 /// #
1218 /// # let mut world = World::default();
1219 /// #
1220 /// # world.init_resource::<Counter>();
1221 /// # world.add_schedule(schedule);
1222 /// #
1223 /// # assert_eq!(world.resource::<Counter>().0, 0);
1224 /// #
1225 /// # let mut commands = world.commands();
1226 /// commands.run_schedule(FooSchedule);
1227 /// #
1228 /// # world.flush();
1229 /// #
1230 /// # assert_eq!(world.resource::<Counter>().0, 1);
1231 /// ```
1232 pub fn run_schedule(&mut self, label: impl ScheduleLabel) {
1233 self.queue(command::run_schedule(label).handle_error_with(warn));
1234 }
1235}
1236
1237/// A list of commands that will be run to modify an [`Entity`].
1238///
1239/// # Note
1240///
1241/// Most [`Commands`] (and thereby [`EntityCommands`]) are deferred:
1242/// when you call the command, if it requires mutable access to the [`World`]
1243/// (that is, if it removes, adds, or changes something), it's not executed immediately.
1244///
1245/// Instead, the command is added to a "command queue."
1246/// The command queue is applied later
1247/// when the [`ApplyDeferred`](crate::schedule::ApplyDeferred) system runs.
1248/// Commands are executed one-by-one so that
1249/// each command can have exclusive access to the `World`.
1250///
1251/// # Fallible
1252///
1253/// Due to their deferred nature, an entity you're trying to change with an [`EntityCommand`]
1254/// can be despawned by the time the command is executed.
1255///
1256/// All deferred entity commands will check whether the entity exists at the time of execution
1257/// and will return an error if it doesn't.
1258///
1259/// # Error handling
1260///
1261/// An [`EntityCommand`] can return a [`Result`](crate::error::Result),
1262/// which will be passed to an [error handler](crate::error) if the `Result` is an error.
1263///
1264/// The [default error handler](crate::error::default_error_handler) panics.
1265/// It can be configured by setting the `GLOBAL_ERROR_HANDLER`.
1266///
1267/// Alternatively, you can customize the error handler for a specific command
1268/// by calling [`EntityCommands::queue_handled`].
1269///
1270/// The [`error`](crate::error) module provides some simple error handlers for convenience.
1271pub struct EntityCommands<'a> {
1272 pub(crate) entity: Entity,
1273 pub(crate) commands: Commands<'a, 'a>,
1274}
1275
1276impl<'a> EntityCommands<'a> {
1277 /// Returns the [`Entity`] id of the entity.
1278 ///
1279 /// # Example
1280 ///
1281 /// ```
1282 /// # use bevy_ecs::prelude::*;
1283 /// #
1284 /// fn my_system(mut commands: Commands) {
1285 /// let entity_id = commands.spawn_empty().id();
1286 /// }
1287 /// # bevy_ecs::system::assert_is_system(my_system);
1288 /// ```
1289 #[inline]
1290 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
1291 pub fn id(&self) -> Entity {
1292 self.entity
1293 }
1294
1295 /// Returns an [`EntityCommands`] with a smaller lifetime.
1296 ///
1297 /// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`.
1298 pub fn reborrow(&mut self) -> EntityCommands {
1299 EntityCommands {
1300 entity: self.entity,
1301 commands: self.commands.reborrow(),
1302 }
1303 }
1304
1305 /// Get an [`EntityEntryCommands`] for the [`Component`] `T`,
1306 /// allowing you to modify it or insert it if it isn't already present.
1307 ///
1308 /// See also [`insert_if_new`](Self::insert_if_new),
1309 /// which lets you insert a [`Bundle`] without overwriting it.
1310 ///
1311 /// # Example
1312 ///
1313 /// ```
1314 /// # use bevy_ecs::prelude::*;
1315 /// # #[derive(Resource)]
1316 /// # struct PlayerEntity { entity: Entity }
1317 /// #[derive(Component)]
1318 /// struct Level(u32);
1319 ///
1320 /// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {
1321 /// commands
1322 /// .entity(player.entity)
1323 /// .entry::<Level>()
1324 /// // Modify the component if it exists.
1325 /// .and_modify(|mut lvl| lvl.0 += 1)
1326 /// // Otherwise, insert a default value.
1327 /// .or_insert(Level(0));
1328 /// }
1329 /// # bevy_ecs::system::assert_is_system(level_up_system);
1330 /// ```
1331 pub fn entry<T: Component>(&mut self) -> EntityEntryCommands<T> {
1332 EntityEntryCommands {
1333 entity_commands: self.reborrow(),
1334 marker: PhantomData,
1335 }
1336 }
1337
1338 /// Adds a [`Bundle`] of components to the entity.
1339 ///
1340 /// This will overwrite any previous value(s) of the same component type.
1341 /// See [`EntityCommands::insert_if_new`] to keep the old value instead.
1342 ///
1343 /// # Example
1344 ///
1345 /// ```
1346 /// # use bevy_ecs::prelude::*;
1347 /// # #[derive(Resource)]
1348 /// # struct PlayerEntity { entity: Entity }
1349 /// #[derive(Component)]
1350 /// struct Health(u32);
1351 /// #[derive(Component)]
1352 /// struct Strength(u32);
1353 /// #[derive(Component)]
1354 /// struct Defense(u32);
1355 ///
1356 /// #[derive(Bundle)]
1357 /// struct CombatBundle {
1358 /// health: Health,
1359 /// strength: Strength,
1360 /// }
1361 ///
1362 /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1363 /// commands
1364 /// .entity(player.entity)
1365 /// // You can insert individual components:
1366 /// .insert(Defense(10))
1367 /// // You can also insert pre-defined bundles of components:
1368 /// .insert(CombatBundle {
1369 /// health: Health(100),
1370 /// strength: Strength(40),
1371 /// })
1372 /// // You can also insert tuples of components and bundles.
1373 /// // This is equivalent to the calls above:
1374 /// .insert((
1375 /// Defense(10),
1376 /// CombatBundle {
1377 /// health: Health(100),
1378 /// strength: Strength(40),
1379 /// },
1380 /// ));
1381 /// }
1382 /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
1383 /// ```
1384 #[track_caller]
1385 pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
1386 self.queue(entity_command::insert(bundle, InsertMode::Replace))
1387 }
1388
1389 /// Adds a [`Bundle`] of components to the entity if the predicate returns true.
1390 ///
1391 /// This is useful for chaining method calls.
1392 ///
1393 /// # Example
1394 ///
1395 /// ```
1396 /// # use bevy_ecs::prelude::*;
1397 /// # #[derive(Resource)]
1398 /// # struct PlayerEntity { entity: Entity }
1399 /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }
1400 /// #[derive(Component)]
1401 /// struct StillLoadingStats;
1402 /// #[derive(Component)]
1403 /// struct Health(u32);
1404 ///
1405 /// fn add_health_system(mut commands: Commands, player: Res<PlayerEntity>) {
1406 /// commands
1407 /// .entity(player.entity)
1408 /// .insert_if(Health(10), || !player.is_spectator())
1409 /// .remove::<StillLoadingStats>();
1410 /// }
1411 /// # bevy_ecs::system::assert_is_system(add_health_system);
1412 /// ```
1413 #[track_caller]
1414 pub fn insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1415 where
1416 F: FnOnce() -> bool,
1417 {
1418 if condition() {
1419 self.insert(bundle)
1420 } else {
1421 self
1422 }
1423 }
1424
1425 /// Adds a [`Bundle`] of components to the entity without overwriting.
1426 ///
1427 /// This is the same as [`EntityCommands::insert`], but in case of duplicate
1428 /// components will leave the old values instead of replacing them with new ones.
1429 ///
1430 /// See also [`entry`](Self::entry), which lets you modify a [`Component`] if it's present,
1431 /// as well as initialize it with a default value.
1432 #[track_caller]
1433 pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {
1434 self.queue(entity_command::insert(bundle, InsertMode::Keep))
1435 }
1436
1437 /// Adds a [`Bundle`] of components to the entity without overwriting if the
1438 /// predicate returns true.
1439 ///
1440 /// This is the same as [`EntityCommands::insert_if`], but in case of duplicate
1441 /// components will leave the old values instead of replacing them with new ones.
1442 #[track_caller]
1443 pub fn insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1444 where
1445 F: FnOnce() -> bool,
1446 {
1447 if condition() {
1448 self.insert_if_new(bundle)
1449 } else {
1450 self
1451 }
1452 }
1453
1454 /// Adds a dynamic [`Component`] to the entity.
1455 ///
1456 /// This will overwrite any previous value(s) of the same component type.
1457 ///
1458 /// You should prefer to use the typed API [`EntityCommands::insert`] where possible.
1459 ///
1460 /// # Safety
1461 ///
1462 /// - [`ComponentId`] must be from the same world as `self`.
1463 /// - `T` must have the same layout as the one passed during `component_id` creation.
1464 #[track_caller]
1465 pub unsafe fn insert_by_id<T: Send + 'static>(
1466 &mut self,
1467 component_id: ComponentId,
1468 value: T,
1469 ) -> &mut Self {
1470 self.queue(
1471 // SAFETY:
1472 // - `ComponentId` safety is ensured by the caller.
1473 // - `T` safety is ensured by the caller.
1474 unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },
1475 )
1476 }
1477
1478 /// Adds a dynamic [`Component`] to the entity.
1479 ///
1480 /// This will overwrite any previous value(s) of the same component type.
1481 ///
1482 /// You should prefer to use the typed API [`EntityCommands::try_insert`] where possible.
1483 ///
1484 /// # Note
1485 ///
1486 /// If the entity does not exist when this command is executed,
1487 /// the resulting error will be ignored.
1488 ///
1489 /// # Safety
1490 ///
1491 /// - [`ComponentId`] must be from the same world as `self`.
1492 /// - `T` must have the same layout as the one passed during `component_id` creation.
1493 #[track_caller]
1494 pub unsafe fn try_insert_by_id<T: Send + 'static>(
1495 &mut self,
1496 component_id: ComponentId,
1497 value: T,
1498 ) -> &mut Self {
1499 self.queue_handled(
1500 // SAFETY:
1501 // - `ComponentId` safety is ensured by the caller.
1502 // - `T` safety is ensured by the caller.
1503 unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },
1504 ignore,
1505 )
1506 }
1507
1508 /// Adds a [`Bundle`] of components to the entity.
1509 ///
1510 /// This will overwrite any previous value(s) of the same component type.
1511 ///
1512 /// # Note
1513 ///
1514 /// If the entity does not exist when this command is executed,
1515 /// the resulting error will be ignored.
1516 ///
1517 /// # Example
1518 ///
1519 /// ```
1520 /// # use bevy_ecs::prelude::*;
1521 /// # #[derive(Resource)]
1522 /// # struct PlayerEntity { entity: Entity }
1523 /// #[derive(Component)]
1524 /// struct Health(u32);
1525 /// #[derive(Component)]
1526 /// struct Strength(u32);
1527 /// #[derive(Component)]
1528 /// struct Defense(u32);
1529 ///
1530 /// #[derive(Bundle)]
1531 /// struct CombatBundle {
1532 /// health: Health,
1533 /// strength: Strength,
1534 /// }
1535 ///
1536 /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1537 /// commands.entity(player.entity)
1538 /// // You can insert individual components:
1539 /// .try_insert(Defense(10))
1540 /// // You can also insert tuples of components:
1541 /// .try_insert(CombatBundle {
1542 /// health: Health(100),
1543 /// strength: Strength(40),
1544 /// });
1545 ///
1546 /// // Suppose this occurs in a parallel adjacent system or process.
1547 /// commands.entity(player.entity).despawn();
1548 ///
1549 /// // This will not panic nor will it add the component.
1550 /// commands.entity(player.entity).try_insert(Defense(5));
1551 /// }
1552 /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
1553 /// ```
1554 #[track_caller]
1555 pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self {
1556 self.queue_handled(entity_command::insert(bundle, InsertMode::Replace), ignore)
1557 }
1558
1559 /// Adds a [`Bundle`] of components to the entity if the predicate returns true.
1560 ///
1561 /// This is useful for chaining method calls.
1562 ///
1563 /// # Note
1564 ///
1565 /// If the entity does not exist when this command is executed,
1566 /// the resulting error will be ignored.
1567 #[track_caller]
1568 pub fn try_insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1569 where
1570 F: FnOnce() -> bool,
1571 {
1572 if condition() {
1573 self.try_insert(bundle)
1574 } else {
1575 self
1576 }
1577 }
1578
1579 /// Adds a [`Bundle`] of components to the entity without overwriting if the
1580 /// predicate returns true.
1581 ///
1582 /// This is the same as [`EntityCommands::try_insert_if`], but in case of duplicate
1583 /// components will leave the old values instead of replacing them with new ones.
1584 ///
1585 /// # Note
1586 ///
1587 /// If the entity does not exist when this command is executed,
1588 /// the resulting error will be ignored.
1589 #[track_caller]
1590 pub fn try_insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1591 where
1592 F: FnOnce() -> bool,
1593 {
1594 if condition() {
1595 self.try_insert_if_new(bundle)
1596 } else {
1597 self
1598 }
1599 }
1600
1601 /// Adds a [`Bundle`] of components to the entity without overwriting.
1602 ///
1603 /// This is the same as [`EntityCommands::try_insert`], but in case of duplicate
1604 /// components will leave the old values instead of replacing them with new ones.
1605 ///
1606 /// # Note
1607 ///
1608 /// If the entity does not exist when this command is executed,
1609 /// the resulting error will be ignored.
1610 #[track_caller]
1611 pub fn try_insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {
1612 self.queue_handled(entity_command::insert(bundle, InsertMode::Keep), ignore)
1613 }
1614
1615 /// Removes a [`Bundle`] of components from the entity.
1616 ///
1617 /// This will remove all components that intersect with the provided bundle;
1618 /// the entity does not need to have all the components in the bundle.
1619 ///
1620 /// This will emit a warning if the entity does not exist.
1621 ///
1622 /// # Example
1623 ///
1624 /// ```
1625 /// # use bevy_ecs::prelude::*;
1626 /// # #[derive(Resource)]
1627 /// # struct PlayerEntity { entity: Entity }
1628 /// #[derive(Component)]
1629 /// struct Health(u32);
1630 /// #[derive(Component)]
1631 /// struct Strength(u32);
1632 /// #[derive(Component)]
1633 /// struct Defense(u32);
1634 ///
1635 /// #[derive(Bundle)]
1636 /// struct CombatBundle {
1637 /// health: Health,
1638 /// strength: Strength,
1639 /// }
1640 ///
1641 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1642 /// commands
1643 /// .entity(player.entity)
1644 /// // You can remove individual components:
1645 /// .remove::<Defense>()
1646 /// // You can also remove pre-defined bundles of components:
1647 /// .remove::<CombatBundle>()
1648 /// // You can also remove tuples of components and bundles.
1649 /// // This is equivalent to the calls above:
1650 /// .remove::<(Defense, CombatBundle)>();
1651 /// }
1652 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1653 /// ```
1654 #[track_caller]
1655 pub fn remove<B: Bundle>(&mut self) -> &mut Self {
1656 self.queue_handled(entity_command::remove::<B>(), warn)
1657 }
1658
1659 /// Removes a [`Bundle`] of components from the entity.
1660 ///
1661 /// This will remove all components that intersect with the provided bundle;
1662 /// the entity does not need to have all the components in the bundle.
1663 ///
1664 /// Unlike [`Self::remove`],
1665 /// this will not emit a warning if the entity does not exist.
1666 ///
1667 /// # Example
1668 ///
1669 /// ```
1670 /// # use bevy_ecs::prelude::*;
1671 /// # #[derive(Resource)]
1672 /// # struct PlayerEntity { entity: Entity }
1673 /// #[derive(Component)]
1674 /// struct Health(u32);
1675 /// #[derive(Component)]
1676 /// struct Strength(u32);
1677 /// #[derive(Component)]
1678 /// struct Defense(u32);
1679 ///
1680 /// #[derive(Bundle)]
1681 /// struct CombatBundle {
1682 /// health: Health,
1683 /// strength: Strength,
1684 /// }
1685 ///
1686 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1687 /// commands
1688 /// .entity(player.entity)
1689 /// // You can remove individual components:
1690 /// .try_remove::<Defense>()
1691 /// // You can also remove pre-defined bundles of components:
1692 /// .try_remove::<CombatBundle>()
1693 /// // You can also remove tuples of components and bundles.
1694 /// // This is equivalent to the calls above:
1695 /// .try_remove::<(Defense, CombatBundle)>();
1696 /// }
1697 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1698 /// ```
1699 pub fn try_remove<B: Bundle>(&mut self) -> &mut Self {
1700 self.queue_handled(entity_command::remove::<B>(), ignore)
1701 }
1702
1703 /// Removes a [`Bundle`] of components from the entity,
1704 /// and also removes any components required by the components in the bundle.
1705 ///
1706 /// This will remove all components that intersect with the provided bundle;
1707 /// the entity does not need to have all the components in the bundle.
1708 ///
1709 /// # Example
1710 ///
1711 /// ```
1712 /// # use bevy_ecs::prelude::*;
1713 /// # #[derive(Resource)]
1714 /// # struct PlayerEntity { entity: Entity }
1715 /// #
1716 /// #[derive(Component)]
1717 /// #[require(B)]
1718 /// struct A;
1719 /// #[derive(Component, Default)]
1720 /// struct B;
1721 ///
1722 /// fn remove_with_requires_system(mut commands: Commands, player: Res<PlayerEntity>) {
1723 /// commands
1724 /// .entity(player.entity)
1725 /// // Removes both A and B from the entity, because B is required by A.
1726 /// .remove_with_requires::<A>();
1727 /// }
1728 /// # bevy_ecs::system::assert_is_system(remove_with_requires_system);
1729 /// ```
1730 #[track_caller]
1731 pub fn remove_with_requires<B: Bundle>(&mut self) -> &mut Self {
1732 self.queue(entity_command::remove_with_requires::<B>())
1733 }
1734
1735 /// Removes a dynamic [`Component`] from the entity if it exists.
1736 ///
1737 /// # Panics
1738 ///
1739 /// Panics if the provided [`ComponentId`] does not exist in the [`World`].
1740 #[track_caller]
1741 pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {
1742 self.queue(entity_command::remove_by_id(component_id))
1743 }
1744
1745 /// Removes all components associated with the entity.
1746 #[track_caller]
1747 pub fn clear(&mut self) -> &mut Self {
1748 self.queue(entity_command::clear())
1749 }
1750
1751 /// Despawns the entity.
1752 ///
1753 /// This will emit a warning if the entity does not exist.
1754 ///
1755 /// # Note
1756 ///
1757 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)
1758 /// that is configured to despawn descendants.
1759 ///
1760 /// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1761 ///
1762 /// # Example
1763 ///
1764 /// ```
1765 /// # use bevy_ecs::prelude::*;
1766 /// # #[derive(Resource)]
1767 /// # struct CharacterToRemove { entity: Entity }
1768 /// #
1769 /// fn remove_character_system(
1770 /// mut commands: Commands,
1771 /// character_to_remove: Res<CharacterToRemove>
1772 /// ) {
1773 /// commands.entity(character_to_remove.entity).despawn();
1774 /// }
1775 /// # bevy_ecs::system::assert_is_system(remove_character_system);
1776 /// ```
1777 #[track_caller]
1778 pub fn despawn(&mut self) {
1779 self.queue_handled(entity_command::despawn(), warn);
1780 }
1781 /// Despawns the provided entity and its descendants.
1782 #[deprecated(
1783 since = "0.16.0",
1784 note = "Use entity.despawn(), which now automatically despawns recursively."
1785 )]
1786 pub fn despawn_recursive(&mut self) {
1787 self.despawn();
1788 }
1789
1790 /// Despawns the entity.
1791 ///
1792 /// Unlike [`Self::despawn`],
1793 /// this will not emit a warning if the entity does not exist.
1794 ///
1795 /// # Note
1796 ///
1797 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)
1798 /// that is configured to despawn descendants.
1799 ///
1800 /// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1801 pub fn try_despawn(&mut self) {
1802 self.queue_handled(entity_command::despawn(), ignore);
1803 }
1804
1805 /// Pushes an [`EntityCommand`] to the queue,
1806 /// which will get executed for the current [`Entity`].
1807 ///
1808 /// The [default error handler](crate::error::default_error_handler)
1809 /// will be used to handle error cases.
1810 /// Every [`EntityCommand`] checks whether the entity exists at the time of execution
1811 /// and returns an error if it does not.
1812 ///
1813 /// To use a custom error handler, see [`EntityCommands::queue_handled`].
1814 ///
1815 /// The command can be:
1816 /// - A custom struct that implements [`EntityCommand`].
1817 /// - A closure or function that matches the following signature:
1818 /// - [`(EntityWorldMut)`](EntityWorldMut)
1819 /// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]
1820 /// - A built-in command from the [`entity_command`] module.
1821 ///
1822 /// # Example
1823 ///
1824 /// ```
1825 /// # use bevy_ecs::prelude::*;
1826 /// # fn my_system(mut commands: Commands) {
1827 /// commands
1828 /// .spawn_empty()
1829 /// // Closures with this signature implement `EntityCommand`.
1830 /// .queue(|entity: EntityWorldMut| {
1831 /// println!("Executed an EntityCommand for {}", entity.id());
1832 /// });
1833 /// # }
1834 /// # bevy_ecs::system::assert_is_system(my_system);
1835 /// ```
1836 pub fn queue<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(
1837 &mut self,
1838 command: C,
1839 ) -> &mut Self {
1840 self.commands.queue(command.with_entity(self.entity));
1841 self
1842 }
1843
1844 /// Pushes an [`EntityCommand`] to the queue,
1845 /// which will get executed for the current [`Entity`].
1846 ///
1847 /// The given `error_handler` will be used to handle error cases.
1848 /// Every [`EntityCommand`] checks whether the entity exists at the time of execution
1849 /// and returns an error if it does not.
1850 ///
1851 /// To implicitly use the default error handler, see [`EntityCommands::queue`].
1852 ///
1853 /// The command can be:
1854 /// - A custom struct that implements [`EntityCommand`].
1855 /// - A closure or function that matches the following signature:
1856 /// - [`(EntityWorldMut)`](EntityWorldMut)
1857 /// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]
1858 /// - A built-in command from the [`entity_command`] module.
1859 ///
1860 /// # Example
1861 ///
1862 /// ```
1863 /// # use bevy_ecs::prelude::*;
1864 /// # fn my_system(mut commands: Commands) {
1865 /// use bevy_ecs::error::warn;
1866 ///
1867 /// commands
1868 /// .spawn_empty()
1869 /// // Closures with this signature implement `EntityCommand`.
1870 /// .queue_handled(
1871 /// |entity: EntityWorldMut| -> Result {
1872 /// let value: usize = "100".parse()?;
1873 /// println!("Successfully parsed the value {} for entity {}", value, entity.id());
1874 /// Ok(())
1875 /// },
1876 /// warn
1877 /// );
1878 /// # }
1879 /// # bevy_ecs::system::assert_is_system(my_system);
1880 /// ```
1881 pub fn queue_handled<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(
1882 &mut self,
1883 command: C,
1884 error_handler: fn(BevyError, ErrorContext),
1885 ) -> &mut Self {
1886 self.commands
1887 .queue_handled(command.with_entity(self.entity), error_handler);
1888 self
1889 }
1890
1891 /// Removes all components except the given [`Bundle`] from the entity.
1892 ///
1893 /// # Example
1894 ///
1895 /// ```
1896 /// # use bevy_ecs::prelude::*;
1897 /// # #[derive(Resource)]
1898 /// # struct PlayerEntity { entity: Entity }
1899 /// #[derive(Component)]
1900 /// struct Health(u32);
1901 /// #[derive(Component)]
1902 /// struct Strength(u32);
1903 /// #[derive(Component)]
1904 /// struct Defense(u32);
1905 ///
1906 /// #[derive(Bundle)]
1907 /// struct CombatBundle {
1908 /// health: Health,
1909 /// strength: Strength,
1910 /// }
1911 ///
1912 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1913 /// commands
1914 /// .entity(player.entity)
1915 /// // You can retain a pre-defined Bundle of components,
1916 /// // with this removing only the Defense component.
1917 /// .retain::<CombatBundle>()
1918 /// // You can also retain only a single component.
1919 /// .retain::<Health>();
1920 /// }
1921 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1922 /// ```
1923 #[track_caller]
1924 pub fn retain<B: Bundle>(&mut self) -> &mut Self {
1925 self.queue(entity_command::retain::<B>())
1926 }
1927
1928 /// Logs the components of the entity at the [`info`](log::info) level.
1929 pub fn log_components(&mut self) -> &mut Self {
1930 self.queue(entity_command::log_components())
1931 }
1932
1933 /// Returns the underlying [`Commands`].
1934 pub fn commands(&mut self) -> Commands {
1935 self.commands.reborrow()
1936 }
1937
1938 /// Returns a mutable reference to the underlying [`Commands`].
1939 pub fn commands_mut(&mut self) -> &mut Commands<'a, 'a> {
1940 &mut self.commands
1941 }
1942
1943 /// Sends a [`Trigger`](crate::observer::Trigger) targeting the entity.
1944 ///
1945 /// This will run any [`Observer`] of the given [`Event`] watching this entity.
1946 #[track_caller]
1947 pub fn trigger(&mut self, event: impl Event) -> &mut Self {
1948 self.queue(entity_command::trigger(event))
1949 }
1950
1951 /// Creates an [`Observer`] listening for events of type `E` targeting this entity.
1952 pub fn observe<E: Event, B: Bundle, M>(
1953 &mut self,
1954 observer: impl IntoObserverSystem<E, B, M>,
1955 ) -> &mut Self {
1956 self.queue(entity_command::observe(observer))
1957 }
1958
1959 /// Clones parts of an entity (components, observers, etc.) onto another entity,
1960 /// configured through [`EntityClonerBuilder`].
1961 ///
1962 /// By default, the other entity will receive all the components of the original that implement
1963 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
1964 ///
1965 /// # Panics
1966 ///
1967 /// The command will panic when applied if the target entity does not exist.
1968 ///
1969 /// # Example
1970 ///
1971 /// Configure through [`EntityClonerBuilder`] as follows:
1972 /// ```
1973 /// # use bevy_ecs::prelude::*;
1974 /// #[derive(Component, Clone)]
1975 /// struct ComponentA(u32);
1976 /// #[derive(Component, Clone)]
1977 /// struct ComponentB(u32);
1978 ///
1979 /// fn example_system(mut commands: Commands) {
1980 /// // Create an empty entity.
1981 /// let target = commands.spawn_empty().id();
1982 ///
1983 /// // Create a new entity and keep its EntityCommands.
1984 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
1985 ///
1986 /// // Clone only ComponentA onto the target.
1987 /// entity.clone_with(target, |builder| {
1988 /// builder.deny::<ComponentB>();
1989 /// });
1990 /// }
1991 /// # bevy_ecs::system::assert_is_system(example_system);
1992 /// ```
1993 ///
1994 /// See [`EntityClonerBuilder`] for more options.
1995 pub fn clone_with(
1996 &mut self,
1997 target: Entity,
1998 config: impl FnOnce(&mut EntityClonerBuilder) + Send + Sync + 'static,
1999 ) -> &mut Self {
2000 self.queue(entity_command::clone_with(target, config))
2001 }
2002
2003 /// Spawns a clone of this entity and returns the [`EntityCommands`] of the clone.
2004 ///
2005 /// The clone will receive all the components of the original that implement
2006 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2007 ///
2008 /// To configure cloning behavior (such as only cloning certain components),
2009 /// use [`EntityCommands::clone_and_spawn_with`].
2010 ///
2011 /// # Note
2012 ///
2013 /// If the original entity does not exist when this command is applied,
2014 /// the returned entity will have no components.
2015 ///
2016 /// # Example
2017 ///
2018 /// ```
2019 /// # use bevy_ecs::prelude::*;
2020 /// #[derive(Component, Clone)]
2021 /// struct ComponentA(u32);
2022 /// #[derive(Component, Clone)]
2023 /// struct ComponentB(u32);
2024 ///
2025 /// fn example_system(mut commands: Commands) {
2026 /// // Create a new entity and store its EntityCommands.
2027 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2028 ///
2029 /// // Create a clone of the first entity.
2030 /// let mut entity_clone = entity.clone_and_spawn();
2031 /// }
2032 /// # bevy_ecs::system::assert_is_system(example_system);
2033 pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> {
2034 self.clone_and_spawn_with(|_| {})
2035 }
2036
2037 /// Spawns a clone of this entity and allows configuring cloning behavior
2038 /// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.
2039 ///
2040 /// By default, the clone will receive all the components of the original that implement
2041 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2042 ///
2043 /// To exclude specific components, use [`EntityClonerBuilder::deny`].
2044 /// To only include specific components, use [`EntityClonerBuilder::deny_all`]
2045 /// followed by [`EntityClonerBuilder::allow`].
2046 ///
2047 /// See the methods on [`EntityClonerBuilder`] for more options.
2048 ///
2049 /// # Note
2050 ///
2051 /// If the original entity does not exist when this command is applied,
2052 /// the returned entity will have no components.
2053 ///
2054 /// # Example
2055 ///
2056 /// ```
2057 /// # use bevy_ecs::prelude::*;
2058 /// #[derive(Component, Clone)]
2059 /// struct ComponentA(u32);
2060 /// #[derive(Component, Clone)]
2061 /// struct ComponentB(u32);
2062 ///
2063 /// fn example_system(mut commands: Commands) {
2064 /// // Create a new entity and store its EntityCommands.
2065 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2066 ///
2067 /// // Create a clone of the first entity, but without ComponentB.
2068 /// let mut entity_clone = entity.clone_and_spawn_with(|builder| {
2069 /// builder.deny::<ComponentB>();
2070 /// });
2071 /// }
2072 /// # bevy_ecs::system::assert_is_system(example_system);
2073 pub fn clone_and_spawn_with(
2074 &mut self,
2075 config: impl FnOnce(&mut EntityClonerBuilder) + Send + Sync + 'static,
2076 ) -> EntityCommands<'_> {
2077 let entity_clone = self.commands().spawn_empty().id();
2078 self.clone_with(entity_clone, config);
2079 EntityCommands {
2080 commands: self.commands_mut().reborrow(),
2081 entity: entity_clone,
2082 }
2083 }
2084
2085 /// Clones the specified components of this entity and inserts them into another entity.
2086 ///
2087 /// Components can only be cloned if they implement
2088 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2089 ///
2090 /// # Panics
2091 ///
2092 /// The command will panic when applied if the target entity does not exist.
2093 pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
2094 self.queue(entity_command::clone_components::<B>(target))
2095 }
2096
2097 /// Clones the specified components of this entity and inserts them into another entity,
2098 /// then removes the components from this entity.
2099 ///
2100 /// Components can only be cloned if they implement
2101 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2102 ///
2103 /// # Panics
2104 ///
2105 /// The command will panic when applied if the target entity does not exist.
2106 pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
2107 self.queue(entity_command::move_components::<B>(target))
2108 }
2109}
2110
2111/// A wrapper around [`EntityCommands`] with convenience methods for working with a specified component type.
2112pub struct EntityEntryCommands<'a, T> {
2113 entity_commands: EntityCommands<'a>,
2114 marker: PhantomData<T>,
2115}
2116
2117impl<'a, T: Component<Mutability = Mutable>> EntityEntryCommands<'a, T> {
2118 /// Modify the component `T` if it exists, using the function `modify`.
2119 pub fn and_modify(&mut self, modify: impl FnOnce(Mut<T>) + Send + Sync + 'static) -> &mut Self {
2120 self.entity_commands
2121 .queue(move |mut entity: EntityWorldMut| {
2122 if let Some(value) = entity.get_mut() {
2123 modify(value);
2124 }
2125 });
2126 self
2127 }
2128}
2129
2130impl<'a, T: Component> EntityEntryCommands<'a, T> {
2131 /// [Insert](EntityCommands::insert) `default` into this entity,
2132 /// if `T` is not already present.
2133 #[track_caller]
2134 pub fn or_insert(&mut self, default: T) -> &mut Self {
2135 self.entity_commands.insert_if_new(default);
2136 self
2137 }
2138
2139 /// [Insert](EntityCommands::insert) `default` into this entity,
2140 /// if `T` is not already present.
2141 ///
2142 /// # Note
2143 ///
2144 /// If the entity does not exist when this command is executed,
2145 /// the resulting error will be ignored.
2146 #[track_caller]
2147 pub fn or_try_insert(&mut self, default: T) -> &mut Self {
2148 self.entity_commands.try_insert_if_new(default);
2149 self
2150 }
2151
2152 /// [Insert](EntityCommands::insert) the value returned from `default` into this entity,
2153 /// if `T` is not already present.
2154 #[track_caller]
2155 pub fn or_insert_with(&mut self, default: impl Fn() -> T) -> &mut Self {
2156 self.or_insert(default())
2157 }
2158
2159 /// [Insert](EntityCommands::insert) the value returned from `default` into this entity,
2160 /// if `T` is not already present.
2161 ///
2162 /// # Note
2163 ///
2164 /// If the entity does not exist when this command is executed,
2165 /// the resulting error will be ignored.
2166 #[track_caller]
2167 pub fn or_try_insert_with(&mut self, default: impl Fn() -> T) -> &mut Self {
2168 self.or_try_insert(default())
2169 }
2170
2171 /// [Insert](EntityCommands::insert) `T::default` into this entity,
2172 /// if `T` is not already present.
2173 #[track_caller]
2174 pub fn or_default(&mut self) -> &mut Self
2175 where
2176 T: Default,
2177 {
2178 self.or_insert(T::default())
2179 }
2180
2181 /// [Insert](EntityCommands::insert) `T::from_world` into this entity,
2182 /// if `T` is not already present.
2183 #[track_caller]
2184 pub fn or_from_world(&mut self) -> &mut Self
2185 where
2186 T: FromWorld,
2187 {
2188 self.entity_commands
2189 .queue(entity_command::insert_from_world::<T>(InsertMode::Keep));
2190 self
2191 }
2192
2193 /// Get the [`EntityCommands`] from which the [`EntityEntryCommands`] was initiated.
2194 ///
2195 /// This allows you to continue chaining method calls after calling [`EntityCommands::entry`].
2196 ///
2197 /// # Example
2198 ///
2199 /// ```
2200 /// # use bevy_ecs::prelude::*;
2201 /// # #[derive(Resource)]
2202 /// # struct PlayerEntity { entity: Entity }
2203 /// #[derive(Component)]
2204 /// struct Level(u32);
2205 ///
2206 /// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {
2207 /// commands
2208 /// .entity(player.entity)
2209 /// .entry::<Level>()
2210 /// // Modify the component if it exists.
2211 /// .and_modify(|mut lvl| lvl.0 += 1)
2212 /// // Otherwise, insert a default value.
2213 /// .or_insert(Level(0))
2214 /// // Return the EntityCommands for the entity.
2215 /// .entity()
2216 /// // Continue chaining method calls.
2217 /// .insert(Name::new("Player"));
2218 /// }
2219 /// # bevy_ecs::system::assert_is_system(level_up_system);
2220 /// ```
2221 pub fn entity(&mut self) -> EntityCommands {
2222 self.entity_commands.reborrow()
2223 }
2224}
2225
2226#[cfg(test)]
2227mod tests {
2228 use crate::{
2229 component::Component,
2230 resource::Resource,
2231 system::Commands,
2232 world::{CommandQueue, FromWorld, World},
2233 };
2234 use alloc::{string::String, sync::Arc, vec, vec::Vec};
2235 use core::{
2236 any::TypeId,
2237 sync::atomic::{AtomicUsize, Ordering},
2238 };
2239
2240 #[expect(
2241 dead_code,
2242 reason = "This struct is used to test how `Drop` behavior works in regards to SparseSet storage, and as such is solely a wrapper around `DropCk` to make it use the SparseSet storage. Because of this, the inner field is intentionally never read."
2243 )]
2244 #[derive(Component)]
2245 #[component(storage = "SparseSet")]
2246 struct SparseDropCk(DropCk);
2247
2248 #[derive(Component)]
2249 struct DropCk(Arc<AtomicUsize>);
2250 impl DropCk {
2251 fn new_pair() -> (Self, Arc<AtomicUsize>) {
2252 let atomic = Arc::new(AtomicUsize::new(0));
2253 (DropCk(atomic.clone()), atomic)
2254 }
2255 }
2256
2257 impl Drop for DropCk {
2258 fn drop(&mut self) {
2259 self.0.as_ref().fetch_add(1, Ordering::Relaxed);
2260 }
2261 }
2262
2263 #[derive(Component, Resource)]
2264 struct W<T>(T);
2265
2266 fn simple_command(world: &mut World) {
2267 world.spawn((W(0u32), W(42u64)));
2268 }
2269
2270 impl FromWorld for W<String> {
2271 fn from_world(world: &mut World) -> Self {
2272 let v = world.resource::<W<usize>>();
2273 Self("*".repeat(v.0))
2274 }
2275 }
2276
2277 #[test]
2278 fn entity_commands_entry() {
2279 let mut world = World::default();
2280 let mut queue = CommandQueue::default();
2281 let mut commands = Commands::new(&mut queue, &world);
2282 let entity = commands.spawn_empty().id();
2283 commands
2284 .entity(entity)
2285 .entry::<W<u32>>()
2286 .and_modify(|_| unreachable!());
2287 queue.apply(&mut world);
2288 assert!(!world.entity(entity).contains::<W<u32>>());
2289 let mut commands = Commands::new(&mut queue, &world);
2290 commands
2291 .entity(entity)
2292 .entry::<W<u32>>()
2293 .or_insert(W(0))
2294 .and_modify(|mut val| {
2295 val.0 = 21;
2296 });
2297 queue.apply(&mut world);
2298 assert_eq!(21, world.get::<W<u32>>(entity).unwrap().0);
2299 let mut commands = Commands::new(&mut queue, &world);
2300 commands
2301 .entity(entity)
2302 .entry::<W<u64>>()
2303 .and_modify(|_| unreachable!())
2304 .or_insert(W(42));
2305 queue.apply(&mut world);
2306 assert_eq!(42, world.get::<W<u64>>(entity).unwrap().0);
2307 world.insert_resource(W(5_usize));
2308 let mut commands = Commands::new(&mut queue, &world);
2309 commands.entity(entity).entry::<W<String>>().or_from_world();
2310 queue.apply(&mut world);
2311 assert_eq!("*****", &world.get::<W<String>>(entity).unwrap().0);
2312 let mut commands = Commands::new(&mut queue, &world);
2313 let id = commands.entity(entity).entry::<W<u64>>().entity().id();
2314 queue.apply(&mut world);
2315 assert_eq!(id, entity);
2316 }
2317
2318 #[test]
2319 fn commands() {
2320 let mut world = World::default();
2321 let mut command_queue = CommandQueue::default();
2322 let entity = Commands::new(&mut command_queue, &world)
2323 .spawn((W(1u32), W(2u64)))
2324 .id();
2325 command_queue.apply(&mut world);
2326 assert_eq!(world.entities().len(), 1);
2327 let results = world
2328 .query::<(&W<u32>, &W<u64>)>()
2329 .iter(&world)
2330 .map(|(a, b)| (a.0, b.0))
2331 .collect::<Vec<_>>();
2332 assert_eq!(results, vec![(1u32, 2u64)]);
2333 // test entity despawn
2334 {
2335 let mut commands = Commands::new(&mut command_queue, &world);
2336 commands.entity(entity).despawn();
2337 commands.entity(entity).despawn(); // double despawn shouldn't panic
2338 }
2339 command_queue.apply(&mut world);
2340 let results2 = world
2341 .query::<(&W<u32>, &W<u64>)>()
2342 .iter(&world)
2343 .map(|(a, b)| (a.0, b.0))
2344 .collect::<Vec<_>>();
2345 assert_eq!(results2, vec![]);
2346
2347 // test adding simple (FnOnce) commands
2348 {
2349 let mut commands = Commands::new(&mut command_queue, &world);
2350
2351 // set up a simple command using a closure that adds one additional entity
2352 commands.queue(|world: &mut World| {
2353 world.spawn((W(42u32), W(0u64)));
2354 });
2355
2356 // set up a simple command using a function that adds one additional entity
2357 commands.queue(simple_command);
2358 }
2359 command_queue.apply(&mut world);
2360 let results3 = world
2361 .query::<(&W<u32>, &W<u64>)>()
2362 .iter(&world)
2363 .map(|(a, b)| (a.0, b.0))
2364 .collect::<Vec<_>>();
2365
2366 assert_eq!(results3, vec![(42u32, 0u64), (0u32, 42u64)]);
2367 }
2368
2369 #[test]
2370 fn insert_components() {
2371 let mut world = World::default();
2372 let mut command_queue1 = CommandQueue::default();
2373
2374 // insert components
2375 let entity = Commands::new(&mut command_queue1, &world)
2376 .spawn(())
2377 .insert_if(W(1u8), || true)
2378 .insert_if(W(2u8), || false)
2379 .insert_if_new(W(1u16))
2380 .insert_if_new(W(2u16))
2381 .insert_if_new_and(W(1u32), || false)
2382 .insert_if_new_and(W(2u32), || true)
2383 .insert_if_new_and(W(3u32), || true)
2384 .id();
2385 command_queue1.apply(&mut world);
2386
2387 let results = world
2388 .query::<(&W<u8>, &W<u16>, &W<u32>)>()
2389 .iter(&world)
2390 .map(|(a, b, c)| (a.0, b.0, c.0))
2391 .collect::<Vec<_>>();
2392 assert_eq!(results, vec![(1u8, 1u16, 2u32)]);
2393
2394 // try to insert components after despawning entity
2395 // in another command queue
2396 Commands::new(&mut command_queue1, &world)
2397 .entity(entity)
2398 .try_insert_if_new_and(W(1u64), || true);
2399
2400 let mut command_queue2 = CommandQueue::default();
2401 Commands::new(&mut command_queue2, &world)
2402 .entity(entity)
2403 .despawn();
2404 command_queue2.apply(&mut world);
2405 command_queue1.apply(&mut world);
2406 }
2407
2408 #[test]
2409 fn remove_components() {
2410 let mut world = World::default();
2411
2412 let mut command_queue = CommandQueue::default();
2413 let (dense_dropck, dense_is_dropped) = DropCk::new_pair();
2414 let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();
2415 let sparse_dropck = SparseDropCk(sparse_dropck);
2416
2417 let entity = Commands::new(&mut command_queue, &world)
2418 .spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
2419 .id();
2420 command_queue.apply(&mut world);
2421 let results_before = world
2422 .query::<(&W<u32>, &W<u64>)>()
2423 .iter(&world)
2424 .map(|(a, b)| (a.0, b.0))
2425 .collect::<Vec<_>>();
2426 assert_eq!(results_before, vec![(1u32, 2u64)]);
2427
2428 // test component removal
2429 Commands::new(&mut command_queue, &world)
2430 .entity(entity)
2431 .remove::<W<u32>>()
2432 .remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();
2433
2434 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
2435 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);
2436 command_queue.apply(&mut world);
2437 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);
2438 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);
2439
2440 let results_after = world
2441 .query::<(&W<u32>, &W<u64>)>()
2442 .iter(&world)
2443 .map(|(a, b)| (a.0, b.0))
2444 .collect::<Vec<_>>();
2445 assert_eq!(results_after, vec![]);
2446 let results_after_u64 = world
2447 .query::<&W<u64>>()
2448 .iter(&world)
2449 .map(|v| v.0)
2450 .collect::<Vec<_>>();
2451 assert_eq!(results_after_u64, vec![]);
2452 }
2453
2454 #[test]
2455 fn remove_components_by_id() {
2456 let mut world = World::default();
2457
2458 let mut command_queue = CommandQueue::default();
2459 let (dense_dropck, dense_is_dropped) = DropCk::new_pair();
2460 let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();
2461 let sparse_dropck = SparseDropCk(sparse_dropck);
2462
2463 let entity = Commands::new(&mut command_queue, &world)
2464 .spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
2465 .id();
2466 command_queue.apply(&mut world);
2467 let results_before = world
2468 .query::<(&W<u32>, &W<u64>)>()
2469 .iter(&world)
2470 .map(|(a, b)| (a.0, b.0))
2471 .collect::<Vec<_>>();
2472 assert_eq!(results_before, vec![(1u32, 2u64)]);
2473
2474 // test component removal
2475 Commands::new(&mut command_queue, &world)
2476 .entity(entity)
2477 .remove_by_id(world.components().get_id(TypeId::of::<W<u32>>()).unwrap())
2478 .remove_by_id(world.components().get_id(TypeId::of::<W<u64>>()).unwrap())
2479 .remove_by_id(world.components().get_id(TypeId::of::<DropCk>()).unwrap())
2480 .remove_by_id(
2481 world
2482 .components()
2483 .get_id(TypeId::of::<SparseDropCk>())
2484 .unwrap(),
2485 );
2486
2487 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
2488 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);
2489 command_queue.apply(&mut world);
2490 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);
2491 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);
2492
2493 let results_after = world
2494 .query::<(&W<u32>, &W<u64>)>()
2495 .iter(&world)
2496 .map(|(a, b)| (a.0, b.0))
2497 .collect::<Vec<_>>();
2498 assert_eq!(results_after, vec![]);
2499 let results_after_u64 = world
2500 .query::<&W<u64>>()
2501 .iter(&world)
2502 .map(|v| v.0)
2503 .collect::<Vec<_>>();
2504 assert_eq!(results_after_u64, vec![]);
2505 }
2506
2507 #[test]
2508 fn remove_resources() {
2509 let mut world = World::default();
2510 let mut queue = CommandQueue::default();
2511 {
2512 let mut commands = Commands::new(&mut queue, &world);
2513 commands.insert_resource(W(123i32));
2514 commands.insert_resource(W(456.0f64));
2515 }
2516
2517 queue.apply(&mut world);
2518 assert!(world.contains_resource::<W<i32>>());
2519 assert!(world.contains_resource::<W<f64>>());
2520
2521 {
2522 let mut commands = Commands::new(&mut queue, &world);
2523 // test resource removal
2524 commands.remove_resource::<W<i32>>();
2525 }
2526 queue.apply(&mut world);
2527 assert!(!world.contains_resource::<W<i32>>());
2528 assert!(world.contains_resource::<W<f64>>());
2529 }
2530
2531 #[test]
2532 fn remove_component_with_required_components() {
2533 #[derive(Component)]
2534 #[require(Y)]
2535 struct X;
2536
2537 #[derive(Component, Default)]
2538 struct Y;
2539
2540 #[derive(Component)]
2541 struct Z;
2542
2543 let mut world = World::default();
2544 let mut queue = CommandQueue::default();
2545 let e = {
2546 let mut commands = Commands::new(&mut queue, &world);
2547 commands.spawn((X, Z)).id()
2548 };
2549 queue.apply(&mut world);
2550
2551 assert!(world.get::<Y>(e).is_some());
2552 assert!(world.get::<X>(e).is_some());
2553 assert!(world.get::<Z>(e).is_some());
2554
2555 {
2556 let mut commands = Commands::new(&mut queue, &world);
2557 commands.entity(e).remove_with_requires::<X>();
2558 }
2559 queue.apply(&mut world);
2560
2561 assert!(world.get::<Y>(e).is_none());
2562 assert!(world.get::<X>(e).is_none());
2563
2564 assert!(world.get::<Z>(e).is_some());
2565 }
2566
2567 #[test]
2568 fn unregister_system_cached_commands() {
2569 let mut world = World::default();
2570 let mut queue = CommandQueue::default();
2571
2572 fn nothing() {}
2573
2574 let resources = world.iter_resources().count();
2575 let id = world.register_system_cached(nothing);
2576 assert_eq!(world.iter_resources().count(), resources + 1);
2577 assert!(world.get_entity(id.entity).is_ok());
2578
2579 let mut commands = Commands::new(&mut queue, &world);
2580 commands.unregister_system_cached(nothing);
2581 queue.apply(&mut world);
2582 assert_eq!(world.iter_resources().count(), resources);
2583 assert!(world.get_entity(id.entity).is_err());
2584 }
2585
2586 fn is_send<T: Send>() {}
2587 fn is_sync<T: Sync>() {}
2588
2589 #[test]
2590 fn test_commands_are_send_and_sync() {
2591 is_send::<Commands>();
2592 is_sync::<Commands>();
2593 }
2594
2595 #[test]
2596 fn append() {
2597 let mut world = World::default();
2598 let mut queue_1 = CommandQueue::default();
2599 {
2600 let mut commands = Commands::new(&mut queue_1, &world);
2601 commands.insert_resource(W(123i32));
2602 }
2603 let mut queue_2 = CommandQueue::default();
2604 {
2605 let mut commands = Commands::new(&mut queue_2, &world);
2606 commands.insert_resource(W(456.0f64));
2607 }
2608 queue_1.append(&mut queue_2);
2609 queue_1.apply(&mut world);
2610 assert!(world.contains_resource::<W<i32>>());
2611 assert!(world.contains_resource::<W<f64>>());
2612 }
2613}