bevy_ecs/system/commands/mod.rs
1pub mod command;
2pub mod entity_command;
3
4#[cfg(feature = "std")]
5mod parallel_scope;
6
7use bevy_ecs_macros::SystemParam;
8use bevy_ptr::move_as_ptr;
9pub use command::Command;
10pub use entity_command::EntityCommand;
11
12#[cfg(feature = "std")]
13pub use parallel_scope::*;
14
15use alloc::boxed::Box;
16use core::marker::PhantomData;
17
18use crate::{
19 bundle::{Bundle, InsertMode, NoBundleEffect},
20 change_detection::{MaybeLocation, Mut},
21 component::{Component, ComponentId, Mutable},
22 entity::{
23 Entities, Entity, EntityAllocator, EntityClonerBuilder, EntityNotSpawnedError,
24 InvalidEntityError, OptIn, OptOut,
25 },
26 error::{warn, BevyError, ErrorContext},
27 event::{EntityEvent, Event},
28 message::Message,
29 observer::{IntoEntityObserver, IntoObserver},
30 query::{QueryData, QueryFilter},
31 relationship::RelationshipHookMode,
32 resource::Resource,
33 schedule::ScheduleLabel,
34 system::{BoxedSystem, Deferred, IntoSystem, RegisteredSystem, SystemId, SystemInput},
35 world::{CommandQueue, EntityWorldMut, FromWorld, World},
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 fallback error handler panics. It can be configured via
93/// the [`FallbackErrorHandler`](crate::error::FallbackErrorHandler) resource.
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
101#[derive(SystemParam)]
102pub struct Commands<'w, 's> {
103 /// The command queue that commands will be pushed to.
104 ///
105 /// This must not be exposed as a `&mut` to untrusted code,
106 /// as calling `apply()` on it could execute commands before [`World::command_queue_start`].
107 queue: Deferred<'s, CommandQueue>,
108 entities: &'w Entities,
109 allocator: &'w EntityAllocator,
110}
111
112// SAFETY: All commands [`Command`] implement [`Send`]
113unsafe impl Send for Commands<'_, '_> {}
114
115// SAFETY: `Commands` never gives access to the inner commands.
116unsafe impl Sync for Commands<'_, '_> {}
117
118impl<'w, 's> Commands<'w, 's> {
119 /// Returns a new `Commands` instance from a [`CommandQueue`] and a [`World`].
120 pub fn new(queue: &'s mut CommandQueue, world: &'w World) -> Self {
121 Self::new_from_entities(queue, &world.entity_allocator, &world.entities)
122 }
123
124 /// Returns a new `Commands` instance from a [`CommandQueue`] and an [`Entities`] reference.
125 pub fn new_from_entities(
126 queue: &'s mut CommandQueue,
127 allocator: &'w EntityAllocator,
128 entities: &'w Entities,
129 ) -> Self {
130 Self {
131 queue: Deferred(queue),
132 allocator,
133 entities,
134 }
135 }
136
137 /// Returns a new [`Commands`] that writes commands to the provided [`CommandQueue`] instead of the one from `self`.
138 ///
139 /// This is useful if you have a `Commands` that writes to one queue and you want one that writes to another.
140 ///
141 /// Note that you're responsible for ensuring the queue eventually writes its commands to the world. One way to
142 /// do this is calling [`Commands::append`] on a `Commands` that writes to the world queue. Failure to write a
143 /// queue may result in entities being allocated but never spawned, which means those entity IDs are never
144 /// freed for reuse.
145 ///
146 /// The original `Commands` isn't mutated or borrowed after this returns, so you can keep using it.
147 pub fn rebound_to<'q>(&self, queue: &'q mut CommandQueue) -> Commands<'w, 'q> {
148 Commands::new_from_entities(queue, self.allocator, self.entities)
149 }
150
151 /// Returns a [`Commands`] with a smaller lifetime.
152 ///
153 /// This is useful if you have `&mut Commands` but need `Commands`.
154 ///
155 /// # Example
156 ///
157 /// ```
158 /// # use bevy_ecs::prelude::*;
159 /// fn my_system(mut commands: Commands) {
160 /// // We do our initialization in a separate function,
161 /// // which expects an owned `Commands`.
162 /// do_initialization(commands.reborrow());
163 ///
164 /// // Since we only reborrowed the commands instead of moving them, we can still use them.
165 /// commands.spawn_empty();
166 /// }
167 /// #
168 /// # fn do_initialization(_: Commands) {}
169 /// ```
170 pub fn reborrow(&mut self) -> Commands<'w, '_> {
171 Commands {
172 queue: self.queue.reborrow(),
173 allocator: self.allocator,
174 entities: self.entities,
175 }
176 }
177
178 /// Take all commands from `other` and append them to `self`, leaving `other` empty.
179 pub fn append(&mut self, other: &mut CommandQueue) {
180 self.queue.bytes.append(&mut other.bytes);
181 }
182
183 /// Spawns a new empty [`Entity`] and returns its corresponding [`EntityCommands`].
184 ///
185 /// # Example
186 ///
187 /// ```
188 /// # use bevy_ecs::prelude::*;
189 /// #[derive(Component)]
190 /// struct Label(&'static str);
191 /// #[derive(Component)]
192 /// struct Strength(u32);
193 /// #[derive(Component)]
194 /// struct Agility(u32);
195 ///
196 /// fn example_system(mut commands: Commands) {
197 /// // Create a new empty entity.
198 /// commands.spawn_empty();
199 ///
200 /// // Create another empty entity.
201 /// commands.spawn_empty()
202 /// // Add a new component bundle to the entity.
203 /// .insert((Strength(1), Agility(2)))
204 /// // Add a single component to the entity.
205 /// .insert(Label("hello world"));
206 /// }
207 /// # bevy_ecs::system::assert_is_system(example_system);
208 /// ```
209 ///
210 /// # See also
211 ///
212 /// - [`spawn`](Self::spawn) to spawn an entity with components.
213 /// - [`spawn_batch`](Self::spawn_batch) to spawn many entities
214 /// with the same combination of components.
215 #[track_caller]
216 pub fn spawn_empty(&mut self) -> EntityCommands<'_> {
217 let entity = self.allocator.alloc();
218 let caller = MaybeLocation::caller();
219 self.queue(move |world: &mut World| {
220 world.spawn_empty_at_with_caller(entity, caller).map(|_| ())
221 });
222 self.entity(entity)
223 }
224
225 /// Spawns a new [`Entity`] with the given components
226 /// and returns the entity's corresponding [`EntityCommands`].
227 ///
228 /// To spawn many entities with the same combination of components,
229 /// [`spawn_batch`](Self::spawn_batch) can be used for better performance.
230 ///
231 /// # Example
232 ///
233 /// ```
234 /// # use bevy_ecs::prelude::*;
235 /// #[derive(Component)]
236 /// struct ComponentA(u32);
237 /// #[derive(Component)]
238 /// struct ComponentB(u32);
239 ///
240 /// #[derive(Bundle)]
241 /// struct ExampleBundle {
242 /// a: ComponentA,
243 /// b: ComponentB,
244 /// }
245 ///
246 /// fn example_system(mut commands: Commands) {
247 /// // Create a new entity with a single component.
248 /// commands.spawn(ComponentA(1));
249 ///
250 /// // Create a new entity with two components using a "tuple bundle".
251 /// commands.spawn((ComponentA(2), ComponentB(1)));
252 ///
253 /// // Create a new entity with a component bundle.
254 /// commands.spawn(ExampleBundle {
255 /// a: ComponentA(3),
256 /// b: ComponentB(2),
257 /// });
258 /// }
259 /// # bevy_ecs::system::assert_is_system(example_system);
260 /// ```
261 ///
262 /// # See also
263 ///
264 /// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.
265 /// - [`spawn_batch`](Self::spawn_batch) to spawn many entities
266 /// with the same combination of components.
267 #[track_caller]
268 pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands<'_> {
269 let entity = self.allocator.alloc();
270 let caller = MaybeLocation::caller();
271 self.queue(move |world: &mut World| {
272 move_as_ptr!(bundle);
273 world
274 .spawn_at_with_caller(entity, bundle, caller)
275 .map(|_| ())
276 });
277 self.entity(entity)
278 }
279
280 /// Returns the [`EntityCommands`] for the given [`Entity`].
281 ///
282 /// This method does not guarantee that commands queued by the returned `EntityCommands`
283 /// will be successful, since the entity could be despawned before they are executed.
284 ///
285 /// # Example
286 ///
287 /// ```
288 /// # use bevy_ecs::prelude::*;
289 /// #[derive(Resource)]
290 /// struct PlayerEntity {
291 /// entity: Entity
292 /// }
293 ///
294 /// #[derive(Component)]
295 /// struct Label(&'static str);
296 ///
297 /// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) {
298 /// // Get the entity and add a component.
299 /// commands.entity(player.entity).insert(Label("hello world"));
300 /// }
301 /// # bevy_ecs::system::assert_is_system(example_system);
302 /// ```
303 ///
304 /// # See also
305 ///
306 /// - [`get_entity`](Self::get_entity) for the fallible version.
307 #[inline]
308 #[track_caller]
309 pub fn entity(&mut self, entity: Entity) -> EntityCommands<'_> {
310 EntityCommands {
311 entity,
312 commands: self.reborrow(),
313 }
314 }
315
316 /// Returns the [`EntityCommands`] for the requested [`Entity`] if it is valid.
317 /// This method does not guarantee that commands queued by the returned `EntityCommands`
318 /// will be successful, since the entity could be despawned before they are executed.
319 /// This also does not error when the entity has not been spawned.
320 /// For that behavior, see [`get_spawned_entity`](Self::get_spawned_entity),
321 /// which should be preferred for accessing entities you expect to already be spawned, like those found from a query.
322 /// For details on entity spawning vs validity, see [`entity`](crate::entity) module docs.
323 ///
324 /// # Errors
325 ///
326 /// Returns [`InvalidEntityError`] if the requested entity does not exist.
327 ///
328 /// # Example
329 ///
330 /// ```
331 /// # use bevy_ecs::prelude::*;
332 /// #[derive(Resource)]
333 /// struct PlayerEntity {
334 /// entity: Entity
335 /// }
336 ///
337 /// #[derive(Component)]
338 /// struct Label(&'static str);
339 ///
340 /// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {
341 /// // Get the entity if it still exists and store the `EntityCommands`.
342 /// // If it doesn't exist, the `?` operator will propagate the returned error
343 /// // to the system, and the system will pass it to an error handler.
344 /// let mut entity_commands = commands.get_entity(player.entity)?;
345 ///
346 /// // Add a component to the entity.
347 /// entity_commands.insert(Label("hello world"));
348 ///
349 /// // Return from the system successfully.
350 /// Ok(())
351 /// }
352 /// # bevy_ecs::system::assert_is_system::<(), (), _>(example_system);
353 /// ```
354 ///
355 /// # See also
356 ///
357 /// - [`entity`](Self::entity) for the infallible version.
358 #[inline]
359 #[track_caller]
360 pub fn get_entity(&mut self, entity: Entity) -> Result<EntityCommands<'_>, InvalidEntityError> {
361 let _location = self.entities.get(entity)?;
362 Ok(EntityCommands {
363 entity,
364 commands: self.reborrow(),
365 })
366 }
367
368 /// Returns the [`EntityCommands`] for the requested [`Entity`] if it spawned in the world *now*.
369 /// Note that for entities that have not been spawned *yet*, like ones from [`spawn`](Self::spawn), this will error.
370 /// If that is not desired, try [`get_entity`](Self::get_entity).
371 /// This should be used over [`get_entity`](Self::get_entity) when you expect the entity to already be spawned in the world.
372 /// If the entity is valid but not yet spawned, this will error that information, where [`get_entity`](Self::get_entity) would succeed, leading to potentially surprising results.
373 /// For details on entity spawning vs validity, see [`entity`](crate::entity) module docs.
374 ///
375 /// This method does not guarantee that commands queued by the returned `EntityCommands`
376 /// will be successful, since the entity could be despawned before they are executed.
377 ///
378 /// # Errors
379 ///
380 /// Returns [`EntityNotSpawnedError`] if the requested entity does not exist.
381 ///
382 /// # Example
383 ///
384 /// ```
385 /// # use bevy_ecs::prelude::*;
386 /// #[derive(Resource)]
387 /// struct PlayerEntity {
388 /// entity: Entity
389 /// }
390 ///
391 /// #[derive(Component)]
392 /// struct Label(&'static str);
393 ///
394 /// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {
395 /// // Get the entity if it still exists and store the `EntityCommands`.
396 /// // If it doesn't exist, the `?` operator will propagate the returned error
397 /// // to the system, and the system will pass it to an error handler.
398 /// let mut entity_commands = commands.get_spawned_entity(player.entity)?;
399 ///
400 /// // Add a component to the entity.
401 /// entity_commands.insert(Label("hello world"));
402 ///
403 /// // Return from the system successfully.
404 /// Ok(())
405 /// }
406 /// # bevy_ecs::system::assert_is_system::<(), (), _>(example_system);
407 /// ```
408 ///
409 /// # See also
410 ///
411 /// - [`entity`](Self::entity) for the infallible version.
412 #[inline]
413 #[track_caller]
414 pub fn get_spawned_entity(
415 &mut self,
416 entity: Entity,
417 ) -> Result<EntityCommands<'_>, EntityNotSpawnedError> {
418 let _location = self.entities.get_spawned(entity)?;
419 Ok(EntityCommands {
420 entity,
421 commands: self.reborrow(),
422 })
423 }
424
425 /// Spawns multiple entities with the same combination of components,
426 /// based on a batch of [`Bundles`](Bundle).
427 ///
428 /// A batch can be any type that implements [`IntoIterator`] and contains bundles,
429 /// such as a [`Vec<Bundle>`](alloc::vec::Vec) or an array `[Bundle; N]`.
430 ///
431 /// This method is equivalent to iterating the batch
432 /// and calling [`spawn`](Self::spawn) for each bundle,
433 /// but is faster by pre-allocating memory and having exclusive [`World`] access.
434 ///
435 /// # Example
436 ///
437 /// ```
438 /// use bevy_ecs::prelude::*;
439 ///
440 /// #[derive(Component)]
441 /// struct Score(u32);
442 ///
443 /// fn example_system(mut commands: Commands) {
444 /// commands.spawn_batch([
445 /// (Name::new("Alice"), Score(0)),
446 /// (Name::new("Bob"), Score(0)),
447 /// ]);
448 /// }
449 /// # bevy_ecs::system::assert_is_system(example_system);
450 /// ```
451 ///
452 /// # See also
453 ///
454 /// - [`spawn`](Self::spawn) to spawn an entity with components.
455 /// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without components.
456 #[track_caller]
457 pub fn spawn_batch<I>(&mut self, batch: I)
458 where
459 I: IntoIterator + Send + Sync + 'static,
460 I::Item: Bundle<Effect: NoBundleEffect>,
461 {
462 self.queue(command::spawn_batch(batch));
463 }
464
465 /// Despawns all entities matching the given [`QueryFilter`].
466 ///
467 /// This method is equivalent to iterating over all the filtered entities
468 /// and [despawning](EntityCommands::despawn) them one by one, but is faster by allocating far fewer commands.
469 ///
470 /// ```
471 /// use bevy_ecs::prelude::*;
472 ///
473 ///
474 /// #[derive(Component)]
475 /// struct PleaseDespawn;
476 ///
477 /// fn despawn_entities(mut commands: Commands) {
478 /// commands.despawn_all::<With<PleaseDespawn>>();
479 /// }
480 ///
481 /// # bevy_ecs::system::assert_is_system(despawn_entities);
482 /// ```
483 pub fn despawn_all<F: QueryFilter>(&mut self) {
484 self.queue(command::despawn_all::<F>());
485 }
486
487 /// Despawns all entities matching the given [`QueryFilter`] and condition.
488 ///
489 /// This method is equivalent to iterating over all the filtered entities
490 /// and [despawning](EntityCommands::despawn) them one by one, but is faster by allocating far fewer commands.
491 ///
492 /// ```
493 /// use bevy_ecs::prelude::*;
494 ///
495 ///
496 /// #[derive(Component)]
497 /// struct Health(f32);
498 ///
499 /// fn despawn_dead(mut commands: Commands) {
500 /// commands.despawn_all_where::<&Health, ()>(|health| health.0 <= 0.0);
501 /// }
502 ///
503 /// # bevy_ecs::system::assert_is_system(despawn_dead);
504 /// ```
505 pub fn despawn_all_where<D: QueryData, F: QueryFilter>(
506 &mut self,
507 cond: impl FnMut(D::Item<'_, '_>) -> bool + Send + 'static,
508 ) {
509 self.queue(command::despawn_all_where::<D, F>(cond));
510 }
511
512 /// Pushes a generic [`Command`] to the command queue.
513 ///
514 /// If the [`Command`] returns a [`Result`],
515 /// it will be handled using the [fallback error handler](crate::error::FallbackErrorHandler).
516 ///
517 /// To use a custom error handler, see [`Commands::queue_handled`].
518 ///
519 /// The command can be:
520 /// - A custom struct that implements [`Command`].
521 /// - A closure or function that matches one of the following signatures:
522 /// - [`(&mut World)`](World)
523 /// - A built-in command from the [`command`] module.
524 ///
525 /// # Example
526 ///
527 /// ```
528 /// # use bevy_ecs::prelude::*;
529 /// #[derive(Resource, Default)]
530 /// struct Counter(u64);
531 ///
532 /// struct AddToCounter(String);
533 ///
534 /// impl Command for AddToCounter {
535 /// type Out = Result;
536 ///
537 /// fn apply(self, world: &mut World) -> Result {
538 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
539 /// let amount: u64 = self.0.parse()?;
540 /// counter.0 += amount;
541 /// Ok(())
542 /// }
543 /// }
544 ///
545 /// fn add_three_to_counter_system(mut commands: Commands) {
546 /// commands.queue(AddToCounter("3".to_string()));
547 /// }
548 ///
549 /// fn add_twenty_five_to_counter_system(mut commands: Commands) {
550 /// commands.queue(|world: &mut World| {
551 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
552 /// counter.0 += 25;
553 /// });
554 /// }
555 /// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
556 /// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
557 /// ```
558 pub fn queue(&mut self, command: impl Command) {
559 self.queue_internal(command.handle_error());
560 }
561
562 /// Pushes a generic [`Command`] to the command queue.
563 ///
564 /// If the [`Command`] returns a [`Result`],
565 /// the given `error_handler` will be used to handle error cases.
566 ///
567 /// To implicitly use the fallback error handler, see [`Commands::queue`].
568 ///
569 /// The command can be:
570 /// - A custom struct that implements [`Command`].
571 /// - A closure or function that matches one of the following signatures:
572 /// - [`(&mut World)`](World)
573 /// - [`(&mut World)`](World) `->` [`Result`]
574 /// - A built-in command from the [`command`] module.
575 ///
576 /// # Example
577 ///
578 /// ```
579 /// # use bevy_ecs::prelude::*;
580 /// use bevy_ecs::error::warn;
581 ///
582 /// #[derive(Resource, Default)]
583 /// struct Counter(u64);
584 ///
585 /// struct AddToCounter(String);
586 ///
587 /// impl Command for AddToCounter {
588 /// type Out = Result;
589 ///
590 /// fn apply(self, world: &mut World) -> Result {
591 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
592 /// let amount: u64 = self.0.parse()?;
593 /// counter.0 += amount;
594 /// Ok(())
595 /// }
596 /// }
597 ///
598 /// fn add_three_to_counter_system(mut commands: Commands) {
599 /// commands.queue_handled(AddToCounter("3".to_string()), warn);
600 /// }
601 ///
602 /// fn add_twenty_five_to_counter_system(mut commands: Commands) {
603 /// commands.queue(|world: &mut World| {
604 /// let mut counter = world.get_resource_or_insert_with(Counter::default);
605 /// counter.0 += 25;
606 /// });
607 /// }
608 /// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);
609 /// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);
610 /// ```
611 pub fn queue_handled(
612 &mut self,
613 command: impl Command,
614 error_handler: impl FnOnce(BevyError, ErrorContext) + Send + 'static,
615 ) {
616 self.queue_internal(command.handle_error_with(error_handler));
617 }
618
619 /// Pushes a generic [`Command`] to the queue like [`Commands::queue_handled`], but instead silently ignores any errors.
620 pub fn queue_silenced(&mut self, command: impl Command) {
621 self.queue_internal(command.ignore_error());
622 }
623
624 fn queue_internal(&mut self, command: impl Command<Out = ()>) {
625 self.queue.push(command);
626 }
627
628 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
629 /// based on a batch of `(Entity, Bundle)` pairs.
630 ///
631 /// A batch can be any type that implements [`IntoIterator`]
632 /// and contains `(Entity, Bundle)` tuples,
633 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
634 /// or an array `[(Entity, Bundle); N]`.
635 ///
636 /// This will overwrite any pre-existing components shared by the [`Bundle`] type.
637 /// Use [`Commands::insert_batch_if_new`] to keep the pre-existing components instead.
638 ///
639 /// This method is equivalent to iterating the batch
640 /// and calling [`insert`](EntityCommands::insert) for each pair,
641 /// but is faster by caching data that is shared between entities.
642 ///
643 /// # Fallible
644 ///
645 /// This command will fail if any of the given entities do not exist.
646 ///
647 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
648 /// which will be handled by the [fallback error handler](crate::error::FallbackErrorHandler).
649 #[track_caller]
650 pub fn insert_batch<I, B>(&mut self, batch: I)
651 where
652 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
653 B: Bundle<Effect: NoBundleEffect>,
654 {
655 self.queue(command::insert_batch(batch, InsertMode::Replace));
656 }
657
658 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
659 /// based on a batch of `(Entity, Bundle)` pairs.
660 ///
661 /// A batch can be any type that implements [`IntoIterator`]
662 /// and contains `(Entity, Bundle)` tuples,
663 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
664 /// or an array `[(Entity, Bundle); N]`.
665 ///
666 /// This will keep any pre-existing components shared by the [`Bundle`] type
667 /// and discard the new values.
668 /// Use [`Commands::insert_batch`] to overwrite the pre-existing components instead.
669 ///
670 /// This method is equivalent to iterating the batch
671 /// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,
672 /// but is faster by caching data that is shared between entities.
673 ///
674 /// # Fallible
675 ///
676 /// This command will fail if any of the given entities do not exist.
677 ///
678 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
679 /// which will be handled by the [fallback error handler](crate::error::FallbackErrorHandler).
680 #[track_caller]
681 pub fn insert_batch_if_new<I, B>(&mut self, batch: I)
682 where
683 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
684 B: Bundle<Effect: NoBundleEffect>,
685 {
686 self.queue(command::insert_batch(batch, InsertMode::Keep));
687 }
688
689 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
690 /// based on a batch of `(Entity, Bundle)` pairs.
691 ///
692 /// A batch can be any type that implements [`IntoIterator`]
693 /// and contains `(Entity, Bundle)` tuples,
694 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
695 /// or an array `[(Entity, Bundle); N]`.
696 ///
697 /// This will overwrite any pre-existing components shared by the [`Bundle`] type.
698 /// Use [`Commands::try_insert_batch_if_new`] to keep the pre-existing components instead.
699 ///
700 /// This method is equivalent to iterating the batch
701 /// and calling [`insert`](EntityCommands::insert) for each pair,
702 /// but is faster by caching data that is shared between entities.
703 ///
704 /// # Fallible
705 ///
706 /// This command will fail if any of the given entities do not exist.
707 ///
708 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
709 /// which will be handled by [logging the error at the `warn` level](warn).
710 #[track_caller]
711 pub fn try_insert_batch<I, B>(&mut self, batch: I)
712 where
713 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
714 B: Bundle<Effect: NoBundleEffect>,
715 {
716 self.queue(command::insert_batch(batch, InsertMode::Replace).handle_error_with(warn));
717 }
718
719 /// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,
720 /// based on a batch of `(Entity, Bundle)` pairs.
721 ///
722 /// A batch can be any type that implements [`IntoIterator`]
723 /// and contains `(Entity, Bundle)` tuples,
724 /// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)
725 /// or an array `[(Entity, Bundle); N]`.
726 ///
727 /// This will keep any pre-existing components shared by the [`Bundle`] type
728 /// and discard the new values.
729 /// Use [`Commands::try_insert_batch`] to overwrite the pre-existing components instead.
730 ///
731 /// This method is equivalent to iterating the batch
732 /// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,
733 /// but is faster by caching data that is shared between entities.
734 ///
735 /// # Fallible
736 ///
737 /// This command will fail if any of the given entities do not exist.
738 ///
739 /// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),
740 /// which will be handled by [logging the error at the `warn` level](warn).
741 #[track_caller]
742 pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I)
743 where
744 I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,
745 B: Bundle<Effect: NoBundleEffect>,
746 {
747 self.queue(command::insert_batch(batch, InsertMode::Keep).handle_error_with(warn));
748 }
749
750 /// Inserts a [`Resource`] into the [`World`] with an inferred value.
751 ///
752 /// The inferred value is determined by the [`FromWorld`] trait of the resource.
753 /// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],
754 /// and those default values will be used.
755 ///
756 /// If the resource already exists when the command is applied, nothing happens.
757 ///
758 /// # Example
759 ///
760 /// ```
761 /// # use bevy_ecs::prelude::*;
762 /// #[derive(Resource, Default)]
763 /// struct Scoreboard {
764 /// current_score: u32,
765 /// high_score: u32,
766 /// }
767 ///
768 /// fn initialize_scoreboard(mut commands: Commands) {
769 /// commands.init_resource::<Scoreboard>();
770 /// }
771 /// # bevy_ecs::system::assert_is_system(initialize_scoreboard);
772 /// ```
773 #[track_caller]
774 pub fn init_resource<R: Resource + FromWorld>(&mut self) {
775 self.queue(command::init_resource::<R>());
776 }
777
778 /// Inserts a [`Resource`] into the [`World`] with a specific value.
779 ///
780 /// This will overwrite any previous value of the same resource type.
781 ///
782 /// # Example
783 ///
784 /// ```
785 /// # use bevy_ecs::prelude::*;
786 /// #[derive(Resource)]
787 /// struct Scoreboard {
788 /// current_score: u32,
789 /// high_score: u32,
790 /// }
791 ///
792 /// fn system(mut commands: Commands) {
793 /// commands.insert_resource(Scoreboard {
794 /// current_score: 0,
795 /// high_score: 0,
796 /// });
797 /// }
798 /// # bevy_ecs::system::assert_is_system(system);
799 /// ```
800 #[track_caller]
801 pub fn insert_resource<R: Resource>(&mut self, resource: R) {
802 self.queue(command::insert_resource(resource));
803 }
804
805 /// Inserts a [`Resource`] into the [`World`] with a specific value
806 /// if the resource is different or missing.
807 #[track_caller]
808 pub fn insert_resource_if_neq<R: Resource + PartialEq>(&mut self, resource: R) {
809 let caller = MaybeLocation::caller();
810
811 self.queue(move |world: &mut World| {
812 if world
813 .get_resource::<R>()
814 .is_none_or(|old_resource| *old_resource != resource)
815 {
816 world.insert_resource_with_caller(resource, caller);
817 }
818 });
819 }
820
821 /// Removes a [`Resource`] from the [`World`].
822 ///
823 /// # Example
824 ///
825 /// ```
826 /// # use bevy_ecs::prelude::*;
827 /// #[derive(Resource)]
828 /// struct Scoreboard {
829 /// current_score: u32,
830 /// high_score: u32,
831 /// }
832 ///
833 /// fn system(mut commands: Commands) {
834 /// commands.remove_resource::<Scoreboard>();
835 /// }
836 /// # bevy_ecs::system::assert_is_system(system);
837 /// ```
838 pub fn remove_resource<R: Resource>(&mut self) {
839 self.queue(command::remove_resource::<R>());
840 }
841
842 /// Runs the system corresponding to the given [`SystemId`].
843 /// Before running a system, it must first be registered via
844 /// [`Commands::register_system`] or [`World::register_system`].
845 ///
846 /// The system is run in an exclusive and single-threaded way.
847 /// Running slow systems can become a bottleneck.
848 ///
849 /// There is no way to get the output of a system when run as a command, because the
850 /// execution of the system happens later. To get the output of a system, use
851 /// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.
852 ///
853 /// # Fallible
854 ///
855 /// This command will fail if the given [`SystemId`]
856 /// does not correspond to a [`System`](crate::system::System).
857 ///
858 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
859 /// which will be handled by [logging the error at the `warn` level](warn).
860 pub fn run_system(&mut self, id: impl Into<SystemId> + Send) {
861 self.queue(command::run_system(id).handle_error_with(warn));
862 }
863
864 /// Runs the system corresponding to the given [`SystemId`] with input.
865 /// Before running a system, it must first be registered via
866 /// [`Commands::register_system`] or [`World::register_system`].
867 ///
868 /// The system is run in an exclusive and single-threaded way.
869 /// Running slow systems can become a bottleneck.
870 ///
871 /// There is no way to get the output of a system when run as a command, because the
872 /// execution of the system happens later. To get the output of a system, use
873 /// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.
874 ///
875 /// # Fallible
876 ///
877 /// This command will fail if the given [`SystemId`]
878 /// does not correspond to a [`System`](crate::system::System).
879 ///
880 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
881 /// which will be handled by [logging the error at the `warn` level](warn).
882 pub fn run_system_with<I>(
883 &mut self,
884 id: impl Into<SystemId<I>> + Send,
885 input: I::Inner<'static>,
886 ) where
887 I: SystemInput<Inner<'static>: Send> + 'static,
888 {
889 self.queue(command::run_system_with(id, input).handle_error_with(warn));
890 }
891
892 /// Registers a system and returns its [`SystemId`] so it can later be called by
893 /// [`Commands::run_system`] or [`World::run_system`].
894 ///
895 /// This is different from adding systems to a [`Schedule`](crate::schedule::Schedule),
896 /// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.
897 ///
898 /// Using a [`Schedule`](crate::schedule::Schedule) is still preferred for most cases
899 /// due to its better performance and ability to run non-conflicting systems simultaneously.
900 ///
901 /// # Note
902 ///
903 /// If the same system is registered more than once,
904 /// each registration will be considered a different system,
905 /// and they will each be given their own [`SystemId`].
906 ///
907 /// If you want to avoid registering the same system multiple times,
908 /// consider using [`Commands::run_system_cached`] or storing the [`SystemId`]
909 /// in a [`Local`](crate::system::Local).
910 ///
911 /// # Example
912 ///
913 /// ```
914 /// # use bevy_ecs::{prelude::*, world::CommandQueue, system::SystemId};
915 /// #[derive(Resource)]
916 /// struct Counter(i32);
917 ///
918 /// fn register_system(
919 /// mut commands: Commands,
920 /// mut local_system: Local<Option<SystemId>>,
921 /// ) {
922 /// if let Some(system) = *local_system {
923 /// commands.run_system(system);
924 /// } else {
925 /// *local_system = Some(commands.register_system(increment_counter));
926 /// }
927 /// }
928 ///
929 /// fn increment_counter(mut value: ResMut<Counter>) {
930 /// value.0 += 1;
931 /// }
932 ///
933 /// # let mut world = World::default();
934 /// # world.insert_resource(Counter(0));
935 /// # let mut queue_1 = CommandQueue::default();
936 /// # let systemid = {
937 /// # let mut commands = Commands::new(&mut queue_1, &world);
938 /// # commands.register_system(increment_counter)
939 /// # };
940 /// # let mut queue_2 = CommandQueue::default();
941 /// # {
942 /// # let mut commands = Commands::new(&mut queue_2, &world);
943 /// # commands.run_system(systemid);
944 /// # }
945 /// # queue_1.append(&mut queue_2);
946 /// # queue_1.apply(&mut world);
947 /// # assert_eq!(1, world.resource::<Counter>().0);
948 /// # bevy_ecs::system::assert_is_system(register_system);
949 /// ```
950 pub fn register_system<I, O, M>(
951 &mut self,
952 system: impl IntoSystem<I, O, M> + 'static,
953 ) -> SystemId<I, O>
954 where
955 I: SystemInput + Send + 'static,
956 O: Send + 'static,
957 {
958 self.register_boxed_system(Box::new(IntoSystem::into_system(system)))
959 }
960
961 /// Registers a [`BoxedSystem`] 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 /// let boxed_system = Box::new(IntoSystem::into_system(increment_counter));
995 /// *local_system = Some(commands.register_boxed_system(boxed_system));
996 /// }
997 /// }
998 ///
999 /// fn increment_counter(mut value: ResMut<Counter>) {
1000 /// value.0 += 1;
1001 /// }
1002 ///
1003 /// # let mut world = World::default();
1004 /// # world.insert_resource(Counter(0));
1005 /// # let mut queue_1 = CommandQueue::default();
1006 /// # let systemid = {
1007 /// # let mut commands = Commands::new(&mut queue_1, &world);
1008 /// # let boxed_system = Box::new(IntoSystem::into_system(increment_counter));
1009 /// # commands.register_boxed_system(boxed_system)
1010 /// # };
1011 /// # let mut queue_2 = CommandQueue::default();
1012 /// # {
1013 /// # let mut commands = Commands::new(&mut queue_2, &world);
1014 /// # commands.run_system(systemid);
1015 /// # }
1016 /// # queue_1.append(&mut queue_2);
1017 /// # queue_1.apply(&mut world);
1018 /// # assert_eq!(1, world.resource::<Counter>().0);
1019 /// # bevy_ecs::system::assert_is_system(register_system);
1020 /// ```
1021 ///
1022 /// # See also
1023 ///
1024 /// - [`register_system`](Self::register_system) to register a system that has not been boxed.
1025 pub fn register_boxed_system<I, O>(&mut self, system: BoxedSystem<I, O>) -> SystemId<I, O>
1026 where
1027 I: SystemInput + Send + 'static,
1028 O: Send + 'static,
1029 {
1030 let entity = self.spawn(RegisteredSystem::new(system)).id();
1031 SystemId::from_entity(entity)
1032 }
1033
1034 /// Removes a system previously registered with [`Commands::register_system`]
1035 /// or [`World::register_system`].
1036 ///
1037 /// After removing a system, the [`SystemId`] becomes invalid
1038 /// and attempting to use it afterwards will result in an error.
1039 /// Re-adding the removed system will register it with a new `SystemId`.
1040 ///
1041 /// # Fallible
1042 ///
1043 /// This command will fail if the given [`SystemId`]
1044 /// does not correspond to a [`System`](crate::system::System).
1045 ///
1046 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
1047 /// which will be handled by [logging the error at the `warn` level](warn).
1048 pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)
1049 where
1050 I: SystemInput + Send + 'static,
1051 O: Send + 'static,
1052 {
1053 self.queue(command::unregister_system(system_id).handle_error_with(warn));
1054 }
1055
1056 /// Removes a system previously registered with one of the following:
1057 /// - [`Commands::run_system_cached`]
1058 /// - [`World::run_system_cached`]
1059 /// - [`World::register_system_cached`]
1060 ///
1061 /// # Fallible
1062 ///
1063 /// This command will fail if the given system
1064 /// is not currently cached in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
1065 ///
1066 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
1067 /// which will be handled by [logging the error at the `warn` level](warn).
1068 pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)
1069 where
1070 I: SystemInput + Send + 'static,
1071 O: 'static,
1072 M: 'static,
1073 S: IntoSystem<I, O, M> + Send + 'static,
1074 {
1075 self.queue(command::unregister_system_cached(system).handle_error_with(warn));
1076 }
1077
1078 /// Runs a cached system, registering it if necessary.
1079 ///
1080 /// Unlike [`Commands::run_system`], this method does not require manual registration.
1081 ///
1082 /// The first time this method is called for a particular system,
1083 /// it will register the system and store its [`SystemId`] in a
1084 /// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.
1085 ///
1086 /// If you would rather manage the [`SystemId`] yourself,
1087 /// or register multiple copies of the same system,
1088 /// use [`Commands::register_system`] instead.
1089 ///
1090 /// # Limitations
1091 ///
1092 /// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of
1093 /// the same type must be equal. This means that closures that capture the environment, and
1094 /// function pointers, are not accepted.
1095 ///
1096 /// If you want to access values from the environment within a system,
1097 /// consider passing them in as inputs via [`Commands::run_system_cached_with`].
1098 ///
1099 /// If that's not an option, consider [`Commands::register_system`] instead.
1100 pub fn run_system_cached<M, S>(&mut self, system: S)
1101 where
1102 M: 'static,
1103 S: IntoSystem<(), (), M> + Send + 'static,
1104 {
1105 self.queue(command::run_system_cached(system).handle_error_with(warn));
1106 }
1107
1108 /// Runs a cached system with an input, registering it if necessary.
1109 ///
1110 /// Unlike [`Commands::run_system_with`], this method does not require manual registration.
1111 ///
1112 /// To use the supplied input, the system should have a [`SystemInput`] as the first parameter.
1113 ///
1114 /// The first time this method is called for a particular system,
1115 /// it will register the system and store its [`SystemId`] in a
1116 /// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.
1117 ///
1118 /// If you would rather manage the [`SystemId`] yourself,
1119 /// or register multiple copies of the same system,
1120 /// use [`Commands::register_system`] instead.
1121 ///
1122 /// # Limitations
1123 ///
1124 /// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of
1125 /// the same type must be equal. This means that closures that capture the environment, and
1126 /// function pointers, are not accepted.
1127 ///
1128 /// If you want to access values from the environment within a system,
1129 /// consider passing them in as inputs.
1130 ///
1131 /// If that's not an option, consider [`Commands::register_system`] instead.
1132 pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)
1133 where
1134 I: SystemInput<Inner<'static>: Send> + Send + 'static,
1135 M: 'static,
1136 S: IntoSystem<I, (), M> + Send + 'static,
1137 {
1138 self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));
1139 }
1140
1141 /// Triggers the given [`Event`], which will run any [`Observer`]s watching for it.
1142 ///
1143 /// [`Observer`]: crate::observer::Observer
1144 #[track_caller]
1145 pub fn trigger<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {
1146 self.queue(command::trigger(event));
1147 }
1148
1149 /// Triggers the given [`Event`] using the given [`Trigger`], which will run any [`Observer`]s watching for it.
1150 ///
1151 /// [`Trigger`]: crate::event::Trigger
1152 /// [`Observer`]: crate::observer::Observer
1153 #[track_caller]
1154 pub fn trigger_with<E: Event<Trigger<'static>: Send + Sync>>(
1155 &mut self,
1156 event: E,
1157 trigger: E::Trigger<'static>,
1158 ) {
1159 self.queue(command::trigger_with(event, trigger));
1160 }
1161
1162 /// Spawns an [`Observer`](crate::observer::Observer) and returns the [`EntityCommands`] associated
1163 /// with the entity that stores the observer.
1164 ///
1165 /// `observer` can be any system whose first parameter is [`On`].
1166 ///
1167 /// **Calling [`observe`](EntityCommands::observe) on the returned
1168 /// [`EntityCommands`] will observe the observer itself, which you very
1169 /// likely do not want.**
1170 ///
1171 /// # Panics
1172 ///
1173 /// Panics if the given system is an exclusive system.
1174 ///
1175 /// [`On`]: crate::observer::On
1176 pub fn add_observer<M>(&mut self, observer: impl IntoObserver<M>) -> EntityCommands<'_> {
1177 self.spawn(observer.into_observer())
1178 }
1179
1180 /// Writes an arbitrary [`Message`].
1181 ///
1182 /// This is a convenience method for writing messages
1183 /// without requiring a [`MessageWriter`](crate::message::MessageWriter).
1184 ///
1185 /// # Performance
1186 ///
1187 /// Since this is a command, exclusive world access is used, which means that it will not profit from
1188 /// system-level parallelism on supported platforms.
1189 ///
1190 /// If these messages are performance-critical or very frequently sent,
1191 /// consider using a [`MessageWriter`](crate::message::MessageWriter) instead.
1192 #[track_caller]
1193 pub fn write_message<M: Message>(&mut self, message: M) -> &mut Self {
1194 self.queue(command::write_message(message));
1195 self
1196 }
1197
1198 /// Runs the schedule corresponding to the given [`ScheduleLabel`].
1199 ///
1200 /// Calls [`World::try_run_schedule`](World::try_run_schedule).
1201 ///
1202 /// # Fallible
1203 ///
1204 /// This command will fail if the given [`ScheduleLabel`]
1205 /// does not correspond to a [`Schedule`](crate::schedule::Schedule).
1206 ///
1207 /// It will internally return a [`TryRunScheduleError`](crate::world::error::TryRunScheduleError),
1208 /// which will be handled by [logging the error at the `warn` level](warn).
1209 ///
1210 /// # Example
1211 ///
1212 /// ```
1213 /// # use bevy_ecs::prelude::*;
1214 /// # use bevy_ecs::schedule::ScheduleLabel;
1215 /// # #[derive(Default, Resource)]
1216 /// # struct Counter(u32);
1217 /// #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]
1218 /// struct FooSchedule;
1219 ///
1220 /// # fn foo_system(mut counter: ResMut<Counter>) {
1221 /// # counter.0 += 1;
1222 /// # }
1223 /// #
1224 /// # let mut schedule = Schedule::new(FooSchedule);
1225 /// # schedule.add_systems(foo_system);
1226 /// #
1227 /// # let mut world = World::default();
1228 /// #
1229 /// # world.init_resource::<Counter>();
1230 /// # world.add_schedule(schedule);
1231 /// #
1232 /// # assert_eq!(world.resource::<Counter>().0, 0);
1233 /// #
1234 /// # let mut commands = world.commands();
1235 /// commands.run_schedule(FooSchedule);
1236 /// #
1237 /// # world.flush();
1238 /// #
1239 /// # assert_eq!(world.resource::<Counter>().0, 1);
1240 /// ```
1241 pub fn run_schedule(&mut self, label: impl ScheduleLabel) {
1242 self.queue(command::run_schedule(label).handle_error_with(warn));
1243 }
1244}
1245
1246/// A list of commands that will be run to modify an [`Entity`].
1247///
1248/// # Note
1249///
1250/// Most [`Commands`] (and thereby [`EntityCommands`]) are deferred:
1251/// when you call the command, if it requires mutable access to the [`World`]
1252/// (that is, if it removes, adds, or changes something), it's not executed immediately.
1253///
1254/// Instead, the command is added to a "command queue."
1255/// The command queue is applied later
1256/// when the [`ApplyDeferred`](crate::schedule::ApplyDeferred) system runs.
1257/// Commands are executed one-by-one so that
1258/// each command can have exclusive access to the `World`.
1259///
1260/// # Fallible
1261///
1262/// Due to their deferred nature, an entity you're trying to change with an [`EntityCommand`]
1263/// can be despawned by the time the command is executed.
1264///
1265/// All deferred entity commands will check whether the entity exists at the time of execution
1266/// and will return an error if it doesn't.
1267///
1268/// # Error handling
1269///
1270/// An [`EntityCommand`] can return a [`Result`](crate::error::Result),
1271/// which will be passed to an [error handler](crate::error) if the `Result` is an error.
1272///
1273/// The fallback error handler panics. It can be configured via
1274/// the [`FallbackErrorHandler`](crate::error::FallbackErrorHandler) resource.
1275///
1276/// Alternatively, you can customize the error handler for a specific command
1277/// by calling [`EntityCommands::queue_handled`].
1278///
1279/// The [`error`](crate::error) module provides some simple error handlers for convenience.
1280pub struct EntityCommands<'a> {
1281 pub(crate) entity: Entity,
1282 pub(crate) commands: Commands<'a, 'a>,
1283}
1284
1285impl<'a> EntityCommands<'a> {
1286 /// Returns the [`Entity`] id of the entity.
1287 ///
1288 /// # Example
1289 ///
1290 /// ```
1291 /// # use bevy_ecs::prelude::*;
1292 /// #
1293 /// fn my_system(mut commands: Commands) {
1294 /// let entity_id = commands.spawn_empty().id();
1295 /// }
1296 /// # bevy_ecs::system::assert_is_system(my_system);
1297 /// ```
1298 #[inline]
1299 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
1300 pub fn id(&self) -> Entity {
1301 self.entity
1302 }
1303
1304 /// Returns an [`EntityCommands`] with a smaller lifetime.
1305 ///
1306 /// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`.
1307 pub fn reborrow(&mut self) -> EntityCommands<'_> {
1308 EntityCommands {
1309 entity: self.entity,
1310 commands: self.commands.reborrow(),
1311 }
1312 }
1313
1314 /// Get an [`EntityEntryCommands`] for the [`Component`] `T`,
1315 /// allowing you to modify it or insert it if it isn't already present.
1316 ///
1317 /// See also [`insert_if_new`](Self::insert_if_new),
1318 /// which lets you insert a [`Bundle`] without overwriting it.
1319 ///
1320 /// # Example
1321 ///
1322 /// ```
1323 /// # use bevy_ecs::prelude::*;
1324 /// # #[derive(Resource)]
1325 /// # struct PlayerEntity { entity: Entity }
1326 /// #[derive(Component)]
1327 /// struct Level(u32);
1328 ///
1329 ///
1330 /// #[derive(Component, Default)]
1331 /// struct Mana {
1332 /// max: u32,
1333 /// current: u32,
1334 /// }
1335 ///
1336 /// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {
1337 /// // If a component already exists then modify it, otherwise insert a default value
1338 /// commands
1339 /// .entity(player.entity)
1340 /// .entry::<Level>()
1341 /// .and_modify(|mut lvl| lvl.0 += 1)
1342 /// .or_insert(Level(0));
1343 ///
1344 /// // Add a default value if none exists, and then modify the existing or new value
1345 /// commands
1346 /// .entity(player.entity)
1347 /// .entry::<Mana>()
1348 /// .or_default()
1349 /// .and_modify(|mut mana| {
1350 /// mana.max += 10;
1351 /// mana.current = mana.max;
1352 /// });
1353 /// }
1354 ///
1355 /// # bevy_ecs::system::assert_is_system(level_up_system);
1356 /// ```
1357 pub fn entry<T: Component>(&mut self) -> EntityEntryCommands<'_, T> {
1358 EntityEntryCommands {
1359 entity_commands: self.reborrow(),
1360 marker: PhantomData,
1361 }
1362 }
1363
1364 /// Adds a [`Bundle`] of components to the entity.
1365 ///
1366 /// This will overwrite any previous value(s) of the same component type.
1367 /// See [`EntityCommands::insert_if_new`] to keep the old value instead.
1368 ///
1369 /// # Example
1370 ///
1371 /// ```
1372 /// # use bevy_ecs::prelude::*;
1373 /// # #[derive(Resource)]
1374 /// # struct PlayerEntity { entity: Entity }
1375 /// #[derive(Component)]
1376 /// struct Health(u32);
1377 /// #[derive(Component)]
1378 /// struct Strength(u32);
1379 /// #[derive(Component)]
1380 /// struct Defense(u32);
1381 ///
1382 /// #[derive(Bundle)]
1383 /// struct CombatBundle {
1384 /// health: Health,
1385 /// strength: Strength,
1386 /// }
1387 ///
1388 /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1389 /// commands
1390 /// .entity(player.entity)
1391 /// // You can insert individual components:
1392 /// .insert(Defense(10))
1393 /// // You can also insert pre-defined bundles of components:
1394 /// .insert(CombatBundle {
1395 /// health: Health(100),
1396 /// strength: Strength(40),
1397 /// })
1398 /// // You can also insert tuples of components and bundles.
1399 /// // This is equivalent to the calls above:
1400 /// .insert((
1401 /// Defense(10),
1402 /// CombatBundle {
1403 /// health: Health(100),
1404 /// strength: Strength(40),
1405 /// },
1406 /// ));
1407 /// }
1408 /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
1409 /// ```
1410 #[track_caller]
1411 pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
1412 self.queue(entity_command::insert(bundle, InsertMode::Replace))
1413 }
1414
1415 /// Adds a [`Bundle`] of components to the entity if the predicate returns true.
1416 ///
1417 /// This is useful for chaining method calls.
1418 ///
1419 /// # Example
1420 ///
1421 /// ```
1422 /// # use bevy_ecs::prelude::*;
1423 /// # #[derive(Resource)]
1424 /// # struct PlayerEntity { entity: Entity }
1425 /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }
1426 /// #[derive(Component)]
1427 /// struct StillLoadingStats;
1428 /// #[derive(Component)]
1429 /// struct Health(u32);
1430 ///
1431 /// fn add_health_system(mut commands: Commands, player: Res<PlayerEntity>) {
1432 /// commands
1433 /// .entity(player.entity)
1434 /// .insert_if(Health(10), || !player.is_spectator())
1435 /// .remove::<StillLoadingStats>();
1436 /// }
1437 /// # bevy_ecs::system::assert_is_system(add_health_system);
1438 /// ```
1439 #[track_caller]
1440 pub fn insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1441 where
1442 F: FnOnce() -> bool,
1443 {
1444 if condition() {
1445 self.insert(bundle)
1446 } else {
1447 self
1448 }
1449 }
1450
1451 /// Adds a [`Bundle`] of components to the entity without overwriting.
1452 ///
1453 /// This is the same as [`EntityCommands::insert`], but in case of duplicate
1454 /// components will leave the old values instead of replacing them with new ones.
1455 ///
1456 /// See also [`entry`](Self::entry), which lets you modify a [`Component`] if it's present,
1457 /// as well as initialize it with a default value.
1458 #[track_caller]
1459 pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {
1460 self.queue(entity_command::insert(bundle, InsertMode::Keep))
1461 }
1462
1463 /// Adds a [`Bundle`] of components to the entity without overwriting if the
1464 /// predicate returns true.
1465 ///
1466 /// This is the same as [`EntityCommands::insert_if`], but in case of duplicate
1467 /// components will leave the old values instead of replacing them with new ones.
1468 #[track_caller]
1469 pub fn insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1470 where
1471 F: FnOnce() -> bool,
1472 {
1473 if condition() {
1474 self.insert_if_new(bundle)
1475 } else {
1476 self
1477 }
1478 }
1479
1480 /// Adds a [`Component`] to the entity if the component is different or
1481 /// missing.
1482 #[track_caller]
1483 pub fn insert_if_neq<T: Component + PartialEq>(&mut self, component: T) -> &mut Self {
1484 let caller = MaybeLocation::caller();
1485
1486 self.queue(move |mut entity: EntityWorldMut| {
1487 if entity
1488 .get::<T>()
1489 .is_none_or(|old_component| *old_component != component)
1490 {
1491 move_as_ptr!(component);
1492 entity.insert_with_caller(
1493 component,
1494 InsertMode::Replace,
1495 caller,
1496 RelationshipHookMode::Run,
1497 );
1498 }
1499 })
1500 }
1501
1502 /// Adds a dynamic [`Component`] to the entity.
1503 ///
1504 /// This will overwrite any previous value(s) of the same component type.
1505 ///
1506 /// You should prefer to use the typed API [`EntityCommands::insert`] where possible.
1507 ///
1508 /// # Safety
1509 ///
1510 /// - [`ComponentId`] must be from the same world as `self`.
1511 /// - `T` must have the same layout as the one passed during `component_id` creation.
1512 #[track_caller]
1513 pub unsafe fn insert_by_id<T: Send + 'static>(
1514 &mut self,
1515 component_id: ComponentId,
1516 value: T,
1517 ) -> &mut Self {
1518 self.queue(
1519 // SAFETY:
1520 // - `ComponentId` safety is ensured by the caller.
1521 // - `T` safety is ensured by the caller.
1522 unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },
1523 )
1524 }
1525
1526 /// Adds a dynamic [`Component`] to the entity.
1527 ///
1528 /// This will overwrite any previous value(s) of the same component type.
1529 ///
1530 /// You should prefer to use the typed API [`EntityCommands::try_insert`] where possible.
1531 ///
1532 /// # Note
1533 ///
1534 /// If the entity does not exist when this command is executed,
1535 /// the resulting error will be ignored.
1536 ///
1537 /// # Safety
1538 ///
1539 /// - [`ComponentId`] must be from the same world as `self`.
1540 /// - `T` must have the same layout as the one passed during `component_id` creation.
1541 #[track_caller]
1542 pub unsafe fn try_insert_by_id<T: Send + 'static>(
1543 &mut self,
1544 component_id: ComponentId,
1545 value: T,
1546 ) -> &mut Self {
1547 self.queue_silenced(
1548 // SAFETY:
1549 // - `ComponentId` safety is ensured by the caller.
1550 // - `T` safety is ensured by the caller.
1551 unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },
1552 )
1553 }
1554
1555 /// Adds a [`Bundle`] of components to the entity.
1556 ///
1557 /// This will overwrite any previous value(s) of the same component type.
1558 ///
1559 /// # Note
1560 ///
1561 /// If the entity does not exist when this command is executed,
1562 /// the resulting error will be ignored.
1563 ///
1564 /// # Example
1565 ///
1566 /// ```
1567 /// # use bevy_ecs::prelude::*;
1568 /// # #[derive(Resource)]
1569 /// # struct PlayerEntity { entity: Entity }
1570 /// #[derive(Component)]
1571 /// struct Health(u32);
1572 /// #[derive(Component)]
1573 /// struct Strength(u32);
1574 /// #[derive(Component)]
1575 /// struct Defense(u32);
1576 ///
1577 /// #[derive(Bundle)]
1578 /// struct CombatBundle {
1579 /// health: Health,
1580 /// strength: Strength,
1581 /// }
1582 ///
1583 /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1584 /// commands.entity(player.entity)
1585 /// // You can insert individual components:
1586 /// .try_insert(Defense(10))
1587 /// // You can also insert tuples of components:
1588 /// .try_insert(CombatBundle {
1589 /// health: Health(100),
1590 /// strength: Strength(40),
1591 /// });
1592 ///
1593 /// // Suppose this occurs in a parallel adjacent system or process.
1594 /// commands.entity(player.entity).despawn();
1595 ///
1596 /// // This will not panic nor will it add the component.
1597 /// commands.entity(player.entity).try_insert(Defense(5));
1598 /// }
1599 /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
1600 /// ```
1601 #[track_caller]
1602 pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self {
1603 self.queue_silenced(entity_command::insert(bundle, InsertMode::Replace))
1604 }
1605
1606 /// Adds a [`Bundle`] of components to the entity if the predicate returns true.
1607 ///
1608 /// This is useful for chaining method calls.
1609 ///
1610 /// # Note
1611 ///
1612 /// If the entity does not exist when this command is executed,
1613 /// the resulting error will be ignored.
1614 #[track_caller]
1615 pub fn try_insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1616 where
1617 F: FnOnce() -> bool,
1618 {
1619 if condition() {
1620 self.try_insert(bundle)
1621 } else {
1622 self
1623 }
1624 }
1625
1626 /// Adds a [`Bundle`] of components to the entity without overwriting if the
1627 /// predicate returns true.
1628 ///
1629 /// This is the same as [`EntityCommands::try_insert_if`], but in case of duplicate
1630 /// components will leave the old values instead of replacing them with new ones.
1631 ///
1632 /// # Note
1633 ///
1634 /// If the entity does not exist when this command is executed,
1635 /// the resulting error will be ignored.
1636 #[track_caller]
1637 pub fn try_insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1638 where
1639 F: FnOnce() -> bool,
1640 {
1641 if condition() {
1642 self.try_insert_if_new(bundle)
1643 } else {
1644 self
1645 }
1646 }
1647
1648 /// Adds a [`Bundle`] of components to the entity without overwriting.
1649 ///
1650 /// This is the same as [`EntityCommands::try_insert`], but in case of duplicate
1651 /// components will leave the old values instead of replacing them with new ones.
1652 ///
1653 /// # Note
1654 ///
1655 /// If the entity does not exist when this command is executed,
1656 /// the resulting error will be ignored.
1657 #[track_caller]
1658 pub fn try_insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {
1659 self.queue_silenced(entity_command::insert(bundle, InsertMode::Keep))
1660 }
1661
1662 /// Removes a [`Bundle`] of components from the entity.
1663 ///
1664 /// This will remove all components that intersect with the provided bundle;
1665 /// the entity does not need to have all the components in the bundle.
1666 ///
1667 /// This will emit a warning if the entity does not exist.
1668 ///
1669 /// # Example
1670 ///
1671 /// ```
1672 /// # use bevy_ecs::prelude::*;
1673 /// # #[derive(Resource)]
1674 /// # struct PlayerEntity { entity: Entity }
1675 /// #[derive(Component)]
1676 /// struct Health(u32);
1677 /// #[derive(Component)]
1678 /// struct Strength(u32);
1679 /// #[derive(Component)]
1680 /// struct Defense(u32);
1681 ///
1682 /// #[derive(Bundle)]
1683 /// struct CombatBundle {
1684 /// health: Health,
1685 /// strength: Strength,
1686 /// }
1687 ///
1688 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1689 /// commands
1690 /// .entity(player.entity)
1691 /// // You can remove individual components:
1692 /// .remove::<Defense>()
1693 /// // You can also remove pre-defined bundles of components:
1694 /// .remove::<CombatBundle>()
1695 /// // You can also remove tuples of components and bundles.
1696 /// // This is equivalent to the calls above:
1697 /// .remove::<(Defense, CombatBundle)>();
1698 /// }
1699 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1700 /// ```
1701 #[track_caller]
1702 pub fn remove<B: Bundle>(&mut self) -> &mut Self {
1703 self.queue_handled(entity_command::remove::<B>(), warn)
1704 }
1705
1706 /// Removes a [`Bundle`] of components from the entity if the predicate returns true.
1707 ///
1708 /// This is useful for chaining method calls.
1709 ///
1710 /// # Example
1711 ///
1712 /// ```
1713 /// # use bevy_ecs::prelude::*;
1714 /// # #[derive(Resource)]
1715 /// # struct PlayerEntity { entity: Entity }
1716 /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }
1717 /// #[derive(Component)]
1718 /// struct Health(u32);
1719 /// #[derive(Component)]
1720 /// struct Strength(u32);
1721 /// #[derive(Component)]
1722 /// struct Defense(u32);
1723 ///
1724 /// #[derive(Bundle)]
1725 /// struct CombatBundle {
1726 /// health: Health,
1727 /// strength: Strength,
1728 /// }
1729 ///
1730 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1731 /// commands
1732 /// .entity(player.entity)
1733 /// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator());
1734 /// }
1735 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1736 /// ```
1737 #[track_caller]
1738 pub fn remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {
1739 if condition() {
1740 self.remove::<B>()
1741 } else {
1742 self
1743 }
1744 }
1745
1746 /// Removes a [`Bundle`] of components from the entity if the predicate returns true.
1747 ///
1748 /// This is useful for chaining method calls.
1749 ///
1750 /// # Note
1751 ///
1752 /// If the entity does not exist when this command is executed,
1753 /// the resulting error will be ignored.
1754 #[track_caller]
1755 pub fn try_remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {
1756 if condition() {
1757 self.try_remove::<B>()
1758 } else {
1759 self
1760 }
1761 }
1762
1763 /// Removes a [`Bundle`] of components from the entity.
1764 ///
1765 /// This will remove all components that intersect with the provided bundle;
1766 /// the entity does not need to have all the components in the bundle.
1767 ///
1768 /// Unlike [`Self::remove`],
1769 /// this will not emit a warning if the entity does not exist.
1770 ///
1771 /// # Example
1772 ///
1773 /// ```
1774 /// # use bevy_ecs::prelude::*;
1775 /// # #[derive(Resource)]
1776 /// # struct PlayerEntity { entity: Entity }
1777 /// #[derive(Component)]
1778 /// struct Health(u32);
1779 /// #[derive(Component)]
1780 /// struct Strength(u32);
1781 /// #[derive(Component)]
1782 /// struct Defense(u32);
1783 ///
1784 /// #[derive(Bundle)]
1785 /// struct CombatBundle {
1786 /// health: Health,
1787 /// strength: Strength,
1788 /// }
1789 ///
1790 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1791 /// commands
1792 /// .entity(player.entity)
1793 /// // You can remove individual components:
1794 /// .try_remove::<Defense>()
1795 /// // You can also remove pre-defined bundles of components:
1796 /// .try_remove::<CombatBundle>()
1797 /// // You can also remove tuples of components and bundles.
1798 /// // This is equivalent to the calls above:
1799 /// .try_remove::<(Defense, CombatBundle)>();
1800 /// }
1801 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1802 /// ```
1803 pub fn try_remove<B: Bundle>(&mut self) -> &mut Self {
1804 self.queue_silenced(entity_command::remove::<B>())
1805 }
1806
1807 /// Removes a [`Bundle`] of components from the entity,
1808 /// and also removes any components required by the components in the bundle.
1809 ///
1810 /// This will remove all components that intersect with the provided bundle;
1811 /// the entity does not need to have all the components in the bundle.
1812 ///
1813 /// # Example
1814 ///
1815 /// ```
1816 /// # use bevy_ecs::prelude::*;
1817 /// # #[derive(Resource)]
1818 /// # struct PlayerEntity { entity: Entity }
1819 /// #
1820 /// #[derive(Component)]
1821 /// #[require(B)]
1822 /// struct A;
1823 /// #[derive(Component, Default)]
1824 /// struct B;
1825 ///
1826 /// fn remove_with_requires_system(mut commands: Commands, player: Res<PlayerEntity>) {
1827 /// commands
1828 /// .entity(player.entity)
1829 /// // Removes both A and B from the entity, because B is required by A.
1830 /// .remove_with_requires::<A>();
1831 /// }
1832 /// # bevy_ecs::system::assert_is_system(remove_with_requires_system);
1833 /// ```
1834 #[track_caller]
1835 pub fn remove_with_requires<B: Bundle>(&mut self) -> &mut Self {
1836 self.queue(entity_command::remove_with_requires::<B>())
1837 }
1838
1839 /// Removes a dynamic [`Component`] from the entity if it exists.
1840 ///
1841 /// # Panics
1842 ///
1843 /// Panics if the provided [`ComponentId`] does not exist in the [`World`].
1844 #[track_caller]
1845 pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {
1846 self.queue(entity_command::remove_by_id(component_id))
1847 }
1848
1849 /// Removes all components associated with the entity.
1850 #[track_caller]
1851 pub fn clear(&mut self) -> &mut Self {
1852 self.queue(entity_command::clear())
1853 }
1854
1855 /// Despawns the entity.
1856 ///
1857 /// This will emit a warning if the entity does not exist.
1858 ///
1859 /// # Note
1860 ///
1861 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)
1862 /// that is configured to despawn descendants.
1863 ///
1864 /// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1865 ///
1866 /// # Example
1867 ///
1868 /// ```
1869 /// # use bevy_ecs::prelude::*;
1870 /// # #[derive(Resource)]
1871 /// # struct CharacterToRemove { entity: Entity }
1872 /// #
1873 /// fn remove_character_system(
1874 /// mut commands: Commands,
1875 /// character_to_remove: Res<CharacterToRemove>
1876 /// ) {
1877 /// commands.entity(character_to_remove.entity).despawn();
1878 /// }
1879 /// # bevy_ecs::system::assert_is_system(remove_character_system);
1880 /// ```
1881 #[track_caller]
1882 pub fn despawn(&mut self) {
1883 self.queue_handled(entity_command::despawn(), warn);
1884 }
1885
1886 /// Despawns the entity.
1887 ///
1888 /// Unlike [`Self::despawn`],
1889 /// this will not emit a warning if the entity does not exist.
1890 ///
1891 /// # Note
1892 ///
1893 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)
1894 /// that is configured to despawn descendants.
1895 ///
1896 /// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1897 pub fn try_despawn(&mut self) {
1898 self.queue_silenced(entity_command::despawn());
1899 }
1900
1901 /// Pushes an [`EntityCommand`] to the queue,
1902 /// which will get executed for the current [`Entity`].
1903 ///
1904 /// The [fallback error handler](crate::error::FallbackErrorHandler)
1905 /// will be used to handle error cases.
1906 /// Every [`EntityCommand`] checks whether the entity exists at the time of execution
1907 /// and returns an error if it does not.
1908 ///
1909 /// To use a custom error handler, see [`EntityCommands::queue_handled`].
1910 ///
1911 /// The command can be:
1912 /// - A custom struct that implements [`EntityCommand`].
1913 /// - A closure or function that matches the following signature:
1914 /// - [`(EntityWorldMut)`](EntityWorldMut)
1915 /// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]
1916 /// - A built-in command from the [`entity_command`] module.
1917 ///
1918 /// # Example
1919 ///
1920 /// ```
1921 /// # use bevy_ecs::prelude::*;
1922 /// # fn my_system(mut commands: Commands) {
1923 /// commands
1924 /// .spawn_empty()
1925 /// // Closures with this signature implement `EntityCommand`.
1926 /// .queue(|entity: EntityWorldMut| {
1927 /// println!("Executed an EntityCommand for {}", entity.id());
1928 /// });
1929 /// # }
1930 /// # bevy_ecs::system::assert_is_system(my_system);
1931 /// ```
1932 pub fn queue(&mut self, command: impl EntityCommand) -> &mut Self {
1933 self.commands.queue(command.with_entity(self.entity));
1934 self
1935 }
1936
1937 /// Pushes an [`EntityCommand`] to the queue,
1938 /// which will get executed for the current [`Entity`].
1939 ///
1940 /// The given `error_handler` will be used to handle error cases.
1941 /// Every [`EntityCommand`] checks whether the entity exists at the time of execution
1942 /// and returns an error if it does not.
1943 ///
1944 /// To implicitly use the fallback error handler, see [`EntityCommands::queue`].
1945 ///
1946 /// The command can be:
1947 /// - A custom struct that implements [`EntityCommand`].
1948 /// - A closure or function that matches the following signature:
1949 /// - [`(EntityWorldMut)`](EntityWorldMut)
1950 /// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]
1951 /// - A built-in command from the [`entity_command`] module.
1952 ///
1953 /// # Example
1954 ///
1955 /// ```
1956 /// # use bevy_ecs::prelude::*;
1957 /// # fn my_system(mut commands: Commands) {
1958 /// use bevy_ecs::error::warn;
1959 ///
1960 /// commands
1961 /// .spawn_empty()
1962 /// // Closures with this signature implement `EntityCommand`.
1963 /// .queue_handled(
1964 /// |entity: EntityWorldMut| -> Result {
1965 /// let value: usize = "100".parse()?;
1966 /// println!("Successfully parsed the value {} for entity {}", value, entity.id());
1967 /// Ok(())
1968 /// },
1969 /// warn
1970 /// );
1971 /// # }
1972 /// # bevy_ecs::system::assert_is_system(my_system);
1973 /// ```
1974 pub fn queue_handled(
1975 &mut self,
1976 command: impl EntityCommand,
1977 error_handler: impl FnOnce(BevyError, ErrorContext) + Send + 'static,
1978 ) -> &mut Self {
1979 self.commands
1980 .queue_handled(command.with_entity(self.entity), error_handler);
1981 self
1982 }
1983
1984 /// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].
1985 ///
1986 /// Unlike [`EntityCommands::queue_handled`], this will completely ignore any errors that occur.
1987 pub fn queue_silenced(&mut self, command: impl EntityCommand) -> &mut Self {
1988 self.commands
1989 .queue_silenced(command.with_entity(self.entity));
1990 self
1991 }
1992
1993 /// Removes all components except the given [`Bundle`] from the entity.
1994 ///
1995 /// # Example
1996 ///
1997 /// ```
1998 /// # use bevy_ecs::prelude::*;
1999 /// # #[derive(Resource)]
2000 /// # struct PlayerEntity { entity: Entity }
2001 /// #[derive(Component)]
2002 /// struct Health(u32);
2003 /// #[derive(Component)]
2004 /// struct Strength(u32);
2005 /// #[derive(Component)]
2006 /// struct Defense(u32);
2007 ///
2008 /// #[derive(Bundle)]
2009 /// struct CombatBundle {
2010 /// health: Health,
2011 /// strength: Strength,
2012 /// }
2013 ///
2014 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
2015 /// commands
2016 /// .entity(player.entity)
2017 /// // You can retain a pre-defined Bundle of components,
2018 /// // with this removing only the Defense component.
2019 /// .retain::<CombatBundle>()
2020 /// // You can also retain only a single component.
2021 /// .retain::<Health>();
2022 /// }
2023 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
2024 /// ```
2025 #[track_caller]
2026 pub fn retain<B: Bundle>(&mut self) -> &mut Self {
2027 self.queue(entity_command::retain::<B>())
2028 }
2029
2030 /// Logs the components of the entity at the [`info`](log::info) level.
2031 pub fn log_components(&mut self) -> &mut Self {
2032 self.queue(entity_command::log_components())
2033 }
2034
2035 /// Returns the underlying [`Commands`].
2036 pub fn commands(&mut self) -> Commands<'_, '_> {
2037 self.commands.reborrow()
2038 }
2039
2040 /// Returns a mutable reference to the underlying [`Commands`].
2041 pub fn commands_mut(&mut self) -> &mut Commands<'a, 'a> {
2042 &mut self.commands
2043 }
2044
2045 /// Creates an [`Observer`](crate::observer::Observer) watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]
2046 /// targets this entity.
2047 pub fn observe<M>(&mut self, observer: impl IntoEntityObserver<M>) -> &mut Self {
2048 self.queue(entity_command::observe(observer))
2049 }
2050
2051 /// Clones parts of an entity (components, observers, etc.) onto another entity,
2052 /// configured through [`EntityClonerBuilder`].
2053 ///
2054 /// The other entity will receive all the components of the original that implement
2055 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
2056 /// [denied](EntityClonerBuilder::deny) in the `config`.
2057 ///
2058 /// # Panics
2059 ///
2060 /// The command will panic when applied if the target entity does not exist.
2061 ///
2062 /// # Example
2063 ///
2064 /// Configure through [`EntityClonerBuilder<OptOut>`] as follows:
2065 /// ```
2066 /// # use bevy_ecs::prelude::*;
2067 /// #[derive(Component, Clone)]
2068 /// struct ComponentA(u32);
2069 /// #[derive(Component, Clone)]
2070 /// struct ComponentB(u32);
2071 ///
2072 /// fn example_system(mut commands: Commands) {
2073 /// // Create an empty entity.
2074 /// let target = commands.spawn_empty().id();
2075 ///
2076 /// // Create a new entity and keep its EntityCommands.
2077 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2078 ///
2079 /// // Clone ComponentA but not ComponentB onto the target.
2080 /// entity.clone_with_opt_out(target, |builder| {
2081 /// builder.deny::<ComponentB>();
2082 /// });
2083 /// }
2084 /// # bevy_ecs::system::assert_is_system(example_system);
2085 /// ```
2086 ///
2087 /// See [`EntityClonerBuilder`] for more options.
2088 pub fn clone_with_opt_out(
2089 &mut self,
2090 target: Entity,
2091 config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
2092 ) -> &mut Self {
2093 self.queue(entity_command::clone_with_opt_out(target, config))
2094 }
2095
2096 /// Clones parts of an entity (components, observers, etc.) onto another entity,
2097 /// configured through [`EntityClonerBuilder`].
2098 ///
2099 /// The other entity will receive only the components of the original that implement
2100 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
2101 /// [allowed](EntityClonerBuilder::allow) in the `config`.
2102 ///
2103 /// # Panics
2104 ///
2105 /// The command will panic when applied if the target entity does not exist.
2106 ///
2107 /// # Example
2108 ///
2109 /// Configure through [`EntityClonerBuilder<OptIn>`] as follows:
2110 /// ```
2111 /// # use bevy_ecs::prelude::*;
2112 /// #[derive(Component, Clone)]
2113 /// struct ComponentA(u32);
2114 /// #[derive(Component, Clone)]
2115 /// struct ComponentB(u32);
2116 ///
2117 /// fn example_system(mut commands: Commands) {
2118 /// // Create an empty entity.
2119 /// let target = commands.spawn_empty().id();
2120 ///
2121 /// // Create a new entity and keep its EntityCommands.
2122 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2123 ///
2124 /// // Clone ComponentA but not ComponentB onto the target.
2125 /// entity.clone_with_opt_in(target, |builder| {
2126 /// builder.allow::<ComponentA>();
2127 /// });
2128 /// }
2129 /// # bevy_ecs::system::assert_is_system(example_system);
2130 /// ```
2131 ///
2132 /// See [`EntityClonerBuilder`] for more options.
2133 pub fn clone_with_opt_in(
2134 &mut self,
2135 target: Entity,
2136 config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
2137 ) -> &mut Self {
2138 self.queue(entity_command::clone_with_opt_in(target, config))
2139 }
2140
2141 /// Spawns a clone of this entity and returns the [`EntityCommands`] of the clone.
2142 ///
2143 /// The clone will receive all the components of the original that implement
2144 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2145 ///
2146 /// To configure cloning behavior (such as only cloning certain components),
2147 /// use [`EntityCommands::clone_and_spawn_with_opt_out`]/
2148 /// [`opt_out`](EntityCommands::clone_and_spawn_with_opt_out).
2149 ///
2150 /// # Note
2151 ///
2152 /// If the original entity does not exist when this command is applied,
2153 /// the returned entity will have no components.
2154 ///
2155 /// # Example
2156 ///
2157 /// ```
2158 /// # use bevy_ecs::prelude::*;
2159 /// #[derive(Component, Clone)]
2160 /// struct ComponentA(u32);
2161 /// #[derive(Component, Clone)]
2162 /// struct ComponentB(u32);
2163 ///
2164 /// fn example_system(mut commands: Commands) {
2165 /// // Create a new entity and store its EntityCommands.
2166 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2167 ///
2168 /// // Create a clone of the entity.
2169 /// let mut entity_clone = entity.clone_and_spawn();
2170 /// }
2171 /// # bevy_ecs::system::assert_is_system(example_system);
2172 pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> {
2173 self.clone_and_spawn_with_opt_out(|_| {})
2174 }
2175
2176 /// Spawns a clone of this entity and allows configuring cloning behavior
2177 /// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.
2178 ///
2179 /// The clone will receive all the components of the original that implement
2180 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
2181 /// [denied](EntityClonerBuilder::deny) in the `config`.
2182 ///
2183 /// See the methods on [`EntityClonerBuilder<OptOut>`] for more options.
2184 ///
2185 /// # Note
2186 ///
2187 /// If the original entity does not exist when this command is applied,
2188 /// the returned entity will have no components.
2189 ///
2190 /// # Example
2191 ///
2192 /// ```
2193 /// # use bevy_ecs::prelude::*;
2194 /// #[derive(Component, Clone)]
2195 /// struct ComponentA(u32);
2196 /// #[derive(Component, Clone)]
2197 /// struct ComponentB(u32);
2198 ///
2199 /// fn example_system(mut commands: Commands) {
2200 /// // Create a new entity and store its EntityCommands.
2201 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2202 ///
2203 /// // Create a clone of the entity with ComponentA but without ComponentB.
2204 /// let mut entity_clone = entity.clone_and_spawn_with_opt_out(|builder| {
2205 /// builder.deny::<ComponentB>();
2206 /// });
2207 /// }
2208 /// # bevy_ecs::system::assert_is_system(example_system);
2209 pub fn clone_and_spawn_with_opt_out(
2210 &mut self,
2211 config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
2212 ) -> EntityCommands<'_> {
2213 let entity_clone = self.commands().spawn_empty().id();
2214 self.clone_with_opt_out(entity_clone, config);
2215 EntityCommands {
2216 commands: self.commands_mut().reborrow(),
2217 entity: entity_clone,
2218 }
2219 }
2220
2221 /// Spawns a clone of this entity and allows configuring cloning behavior
2222 /// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.
2223 ///
2224 /// The clone will receive only the components of the original that implement
2225 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
2226 /// [allowed](EntityClonerBuilder::allow) in the `config`.
2227 ///
2228 /// See the methods on [`EntityClonerBuilder<OptIn>`] for more options.
2229 ///
2230 /// # Note
2231 ///
2232 /// If the original entity does not exist when this command is applied,
2233 /// the returned entity will have no components.
2234 ///
2235 /// # Example
2236 ///
2237 /// ```
2238 /// # use bevy_ecs::prelude::*;
2239 /// #[derive(Component, Clone)]
2240 /// struct ComponentA(u32);
2241 /// #[derive(Component, Clone)]
2242 /// struct ComponentB(u32);
2243 ///
2244 /// fn example_system(mut commands: Commands) {
2245 /// // Create a new entity and store its EntityCommands.
2246 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2247 ///
2248 /// // Create a clone of the entity with ComponentA but without ComponentB.
2249 /// let mut entity_clone = entity.clone_and_spawn_with_opt_in(|builder| {
2250 /// builder.allow::<ComponentA>();
2251 /// });
2252 /// }
2253 /// # bevy_ecs::system::assert_is_system(example_system);
2254 pub fn clone_and_spawn_with_opt_in(
2255 &mut self,
2256 config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
2257 ) -> EntityCommands<'_> {
2258 let entity_clone = self.commands().spawn_empty().id();
2259 self.clone_with_opt_in(entity_clone, config);
2260 EntityCommands {
2261 commands: self.commands_mut().reborrow(),
2262 entity: entity_clone,
2263 }
2264 }
2265
2266 /// Clones the specified components of this entity and inserts them into another entity.
2267 ///
2268 /// Components can only be cloned if they implement
2269 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2270 ///
2271 /// # Panics
2272 ///
2273 /// The command will panic when applied if the target entity does not exist.
2274 pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
2275 self.queue(entity_command::clone_components::<B>(target))
2276 }
2277
2278 /// Moves the specified components of this entity into another entity.
2279 ///
2280 /// Components with [`Ignore`] clone behavior will not be moved, while components that
2281 /// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.
2282 /// All other components will be moved without any other special handling.
2283 ///
2284 /// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.
2285 ///
2286 /// # Panics
2287 ///
2288 /// The command will panic when applied if the target entity does not exist.
2289 ///
2290 /// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore
2291 /// [`Custom`]: crate::component::ComponentCloneBehavior::Custom
2292 pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
2293 self.queue(entity_command::move_components::<B>(target))
2294 }
2295
2296 /// Passes the current entity into the given function, and triggers the [`EntityEvent`] returned by that function.
2297 ///
2298 /// # Example
2299 ///
2300 /// A surprising number of functions meet the trait bounds for `event_fn`:
2301 ///
2302 /// ```rust
2303 /// # use bevy_ecs::prelude::*;
2304 ///
2305 /// #[derive(EntityEvent)]
2306 /// struct Explode(Entity);
2307 ///
2308 /// impl From<Entity> for Explode {
2309 /// fn from(entity: Entity) -> Self {
2310 /// Explode(entity)
2311 /// }
2312 /// }
2313 ///
2314 ///
2315 /// fn trigger_via_constructor(mut commands: Commands) {
2316 /// // The fact that `Explode` is a single-field tuple struct
2317 /// // ensures that `Explode(entity)` is a function that generates
2318 /// // an EntityEvent, meeting the trait bounds for `event_fn`.
2319 /// commands.spawn_empty().trigger(Explode);
2320 ///
2321 /// }
2322 ///
2323 ///
2324 /// fn trigger_via_from_trait(mut commands: Commands) {
2325 /// // This variant also works for events like `struct Explode { entity: Entity }`
2326 /// commands.spawn_empty().trigger(Explode::from);
2327 /// }
2328 ///
2329 /// fn trigger_via_closure(mut commands: Commands) {
2330 /// commands.spawn_empty().trigger(|entity| Explode(entity));
2331 /// }
2332 /// ```
2333 #[track_caller]
2334 pub fn trigger<'t, E: EntityEvent<Trigger<'t>: Default>>(
2335 &mut self,
2336 event_fn: impl FnOnce(Entity) -> E,
2337 ) -> &mut Self {
2338 let event = (event_fn)(self.entity);
2339 self.commands.trigger(event);
2340 self
2341 }
2342}
2343
2344/// A wrapper around [`EntityCommands`] with convenience methods for working with a specified component type.
2345pub struct EntityEntryCommands<'a, T> {
2346 entity_commands: EntityCommands<'a>,
2347 marker: PhantomData<T>,
2348}
2349
2350impl<'a, T: Component<Mutability = Mutable>> EntityEntryCommands<'a, T> {
2351 /// Modify the component `T` if it exists, using the function `modify`.
2352 pub fn and_modify(&mut self, modify: impl FnOnce(Mut<T>) + Send + Sync + 'static) -> &mut Self {
2353 self.entity_commands
2354 .queue(move |mut entity: EntityWorldMut| {
2355 if let Some(value) = entity.get_mut() {
2356 modify(value);
2357 }
2358 });
2359 self
2360 }
2361}
2362
2363impl<'a, T: Component> EntityEntryCommands<'a, T> {
2364 /// Returns a [`EntityEntryCommands`] with a smaller lifetime.
2365 ///
2366 /// This is useful if you have `&mut EntityEntryCommands` but need `EntityEntryCommands`.
2367 pub fn reborrow(&mut self) -> EntityEntryCommands<'_, T> {
2368 EntityEntryCommands {
2369 entity_commands: self.entity_commands.reborrow(),
2370 marker: PhantomData,
2371 }
2372 }
2373
2374 /// [Insert](EntityCommands::insert) `default` into this entity,
2375 /// if `T` is not already present.
2376 #[track_caller]
2377 pub fn or_insert(&mut self, default: T) -> &mut Self {
2378 self.entity_commands.insert_if_new(default);
2379 self
2380 }
2381
2382 /// [Insert](EntityCommands::insert) `default` into this entity,
2383 /// if `T` is not already present.
2384 ///
2385 /// # Note
2386 ///
2387 /// If the entity does not exist when this command is executed,
2388 /// the resulting error will be ignored.
2389 #[track_caller]
2390 pub fn or_try_insert(&mut self, default: T) -> &mut Self {
2391 self.entity_commands.try_insert_if_new(default);
2392 self
2393 }
2394
2395 /// [Insert](EntityCommands::insert) the value returned from `default` into this entity,
2396 /// if `T` is not already present.
2397 ///
2398 /// `default` will only be invoked if the component will actually be inserted.
2399 #[track_caller]
2400 pub fn or_insert_with<F>(&mut self, default: F) -> &mut Self
2401 where
2402 F: FnOnce() -> T + Send + 'static,
2403 {
2404 self.entity_commands
2405 .queue(entity_command::insert_with(default, InsertMode::Keep));
2406 self
2407 }
2408
2409 /// [Insert](EntityCommands::insert) the value returned from `default` into this entity,
2410 /// if `T` is not already present.
2411 ///
2412 /// `default` will only be invoked if the component will actually be inserted.
2413 ///
2414 /// # Note
2415 ///
2416 /// If the entity does not exist when this command is executed,
2417 /// the resulting error will be ignored.
2418 #[track_caller]
2419 pub fn or_try_insert_with<F>(&mut self, default: F) -> &mut Self
2420 where
2421 F: FnOnce() -> T + Send + 'static,
2422 {
2423 self.entity_commands
2424 .queue_silenced(entity_command::insert_with(default, InsertMode::Keep));
2425 self
2426 }
2427
2428 /// [Insert](EntityCommands::insert) `T::default` into this entity,
2429 /// if `T` is not already present.
2430 ///
2431 /// `T::default` will only be invoked if the component will actually be inserted.
2432 #[track_caller]
2433 pub fn or_default(&mut self) -> &mut Self
2434 where
2435 T: Default,
2436 {
2437 self.or_insert_with(T::default)
2438 }
2439
2440 /// [Insert](EntityCommands::insert) `T::from_world` into this entity,
2441 /// if `T` is not already present.
2442 ///
2443 /// `T::from_world` will only be invoked if the component will actually be inserted.
2444 #[track_caller]
2445 pub fn or_from_world(&mut self) -> &mut Self
2446 where
2447 T: FromWorld,
2448 {
2449 self.entity_commands
2450 .queue(entity_command::insert_from_world::<T>(InsertMode::Keep));
2451 self
2452 }
2453
2454 /// Get the [`EntityCommands`] from which the [`EntityEntryCommands`] was initiated.
2455 ///
2456 /// This allows you to continue chaining method calls after calling [`EntityCommands::entry`].
2457 ///
2458 /// # Example
2459 ///
2460 /// ```
2461 /// # use bevy_ecs::prelude::*;
2462 /// # #[derive(Resource)]
2463 /// # struct PlayerEntity { entity: Entity }
2464 /// #[derive(Component)]
2465 /// struct Level(u32);
2466 ///
2467 /// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {
2468 /// commands
2469 /// .entity(player.entity)
2470 /// .entry::<Level>()
2471 /// // Modify the component if it exists.
2472 /// .and_modify(|mut lvl| lvl.0 += 1)
2473 /// // Otherwise, insert a default value.
2474 /// .or_insert(Level(0))
2475 /// // Return the EntityCommands for the entity.
2476 /// .entity()
2477 /// // Continue chaining method calls.
2478 /// .insert(Name::new("Player"));
2479 /// }
2480 /// # bevy_ecs::system::assert_is_system(level_up_system);
2481 /// ```
2482 pub fn entity(&mut self) -> EntityCommands<'_> {
2483 self.entity_commands.reborrow()
2484 }
2485}
2486
2487#[cfg(test)]
2488mod tests {
2489 use crate::{
2490 component::Component,
2491 query::{Or, With, Without},
2492 resource::Resource,
2493 system::Commands,
2494 world::{CommandQueue, FromWorld, World},
2495 };
2496 use alloc::{string::String, sync::Arc, vec, vec::Vec};
2497 use core::{
2498 any::TypeId,
2499 sync::atomic::{AtomicUsize, Ordering},
2500 };
2501
2502 #[expect(
2503 dead_code,
2504 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."
2505 )]
2506 #[derive(Component)]
2507 #[component(storage = "SparseSet")]
2508 struct SparseDropCk(DropCk);
2509
2510 #[derive(Component)]
2511 struct DropCk(Arc<AtomicUsize>);
2512 impl DropCk {
2513 fn new_pair() -> (Self, Arc<AtomicUsize>) {
2514 let atomic = Arc::new(AtomicUsize::new(0));
2515 (DropCk(atomic.clone()), atomic)
2516 }
2517 }
2518
2519 impl Drop for DropCk {
2520 fn drop(&mut self) {
2521 self.0.as_ref().fetch_add(1, Ordering::Relaxed);
2522 }
2523 }
2524
2525 #[derive(Component)]
2526 struct W<T>(T);
2527
2528 #[derive(Resource)]
2529 struct V<T>(T);
2530
2531 fn simple_command(world: &mut World) {
2532 world.spawn((W(0u32), W(42u64)));
2533 }
2534
2535 impl FromWorld for W<String> {
2536 fn from_world(world: &mut World) -> Self {
2537 let v = world.resource::<V<usize>>();
2538 Self("*".repeat(v.0))
2539 }
2540 }
2541
2542 impl Default for W<u8> {
2543 fn default() -> Self {
2544 unreachable!()
2545 }
2546 }
2547
2548 #[test]
2549 fn entity_commands_entry() {
2550 let mut world = World::default();
2551 let mut queue = CommandQueue::default();
2552 let mut commands = Commands::new(&mut queue, &world);
2553 let entity = commands.spawn_empty().id();
2554 commands
2555 .entity(entity)
2556 .entry::<W<u32>>()
2557 .and_modify(|_| unreachable!());
2558 queue.apply(&mut world);
2559 assert!(!world.entity(entity).contains::<W<u32>>());
2560 let mut commands = Commands::new(&mut queue, &world);
2561 commands
2562 .entity(entity)
2563 .entry::<W<u32>>()
2564 .or_insert(W(0))
2565 .and_modify(|mut val| {
2566 val.0 = 21;
2567 });
2568 queue.apply(&mut world);
2569 assert_eq!(21, world.get::<W<u32>>(entity).unwrap().0);
2570 let mut commands = Commands::new(&mut queue, &world);
2571 commands
2572 .entity(entity)
2573 .entry::<W<u64>>()
2574 .and_modify(|_| unreachable!())
2575 .or_insert(W(42));
2576 queue.apply(&mut world);
2577 assert_eq!(42, world.get::<W<u64>>(entity).unwrap().0);
2578 world.insert_resource(V(5_usize));
2579 let mut commands = Commands::new(&mut queue, &world);
2580 commands.entity(entity).entry::<W<String>>().or_from_world();
2581 queue.apply(&mut world);
2582 assert_eq!("*****", &world.get::<W<String>>(entity).unwrap().0);
2583 let mut commands = Commands::new(&mut queue, &world);
2584 let id = commands.entity(entity).entry::<W<u64>>().entity().id();
2585 queue.apply(&mut world);
2586 assert_eq!(id, entity);
2587 let mut commands = Commands::new(&mut queue, &world);
2588 commands
2589 .entity(entity)
2590 .entry::<W<u8>>()
2591 .or_insert_with(|| W(5))
2592 .or_insert_with(|| unreachable!())
2593 .or_try_insert_with(|| unreachable!())
2594 .or_default()
2595 .or_from_world();
2596 queue.apply(&mut world);
2597 assert_eq!(5, world.get::<W<u8>>(entity).unwrap().0);
2598 }
2599
2600 #[test]
2601 fn commands() {
2602 let mut world = World::default();
2603 let mut command_queue = CommandQueue::default();
2604 let entity = Commands::new(&mut command_queue, &world)
2605 .spawn((W(1u32), W(2u64)))
2606 .id();
2607 command_queue.apply(&mut world);
2608 assert_eq!(world.query::<&W<u32>>().query(&world).count(), 1);
2609 let results = world
2610 .query::<(&W<u32>, &W<u64>)>()
2611 .iter(&world)
2612 .map(|(a, b)| (a.0, b.0))
2613 .collect::<Vec<_>>();
2614 assert_eq!(results, vec![(1u32, 2u64)]);
2615 // test entity despawn
2616 {
2617 let mut commands = Commands::new(&mut command_queue, &world);
2618 commands.entity(entity).despawn();
2619 commands.entity(entity).despawn(); // double despawn shouldn't panic
2620 }
2621 command_queue.apply(&mut world);
2622 let results2 = world
2623 .query::<(&W<u32>, &W<u64>)>()
2624 .iter(&world)
2625 .map(|(a, b)| (a.0, b.0))
2626 .collect::<Vec<_>>();
2627 assert_eq!(results2, vec![]);
2628
2629 // test adding simple (FnOnce) commands
2630 {
2631 let mut commands = Commands::new(&mut command_queue, &world);
2632
2633 // set up a simple command using a closure that adds one additional entity
2634 commands.queue(|world: &mut World| {
2635 world.spawn((W(42u32), W(0u64)));
2636 });
2637
2638 // set up a simple command using a function that adds one additional entity
2639 commands.queue(simple_command);
2640 }
2641 command_queue.apply(&mut world);
2642 let results3 = world
2643 .query::<(&W<u32>, &W<u64>)>()
2644 .iter(&world)
2645 .map(|(a, b)| (a.0, b.0))
2646 .collect::<Vec<_>>();
2647
2648 assert_eq!(results3, vec![(42u32, 0u64), (0u32, 42u64)]);
2649 }
2650
2651 #[test]
2652 fn insert_components() {
2653 let mut world = World::default();
2654 let mut command_queue1 = CommandQueue::default();
2655
2656 // insert components
2657 let entity = Commands::new(&mut command_queue1, &world)
2658 .spawn(())
2659 .insert_if(W(1u8), || true)
2660 .insert_if(W(2u8), || false)
2661 .insert_if_new(W(1u16))
2662 .insert_if_new(W(2u16))
2663 .insert_if_new_and(W(1u32), || false)
2664 .insert_if_new_and(W(2u32), || true)
2665 .insert_if_new_and(W(3u32), || true)
2666 .id();
2667 command_queue1.apply(&mut world);
2668
2669 let results = world
2670 .query::<(&W<u8>, &W<u16>, &W<u32>)>()
2671 .iter(&world)
2672 .map(|(a, b, c)| (a.0, b.0, c.0))
2673 .collect::<Vec<_>>();
2674 assert_eq!(results, vec![(1u8, 1u16, 2u32)]);
2675
2676 // try to insert components after despawning entity
2677 // in another command queue
2678 Commands::new(&mut command_queue1, &world)
2679 .entity(entity)
2680 .try_insert_if_new_and(W(1u64), || true);
2681
2682 let mut command_queue2 = CommandQueue::default();
2683 Commands::new(&mut command_queue2, &world)
2684 .entity(entity)
2685 .despawn();
2686 command_queue2.apply(&mut world);
2687 command_queue1.apply(&mut world);
2688 }
2689
2690 #[test]
2691 fn insert_component_if_not_equal() {
2692 use crate::query::Added;
2693
2694 #[derive(Component, PartialEq)]
2695 struct P(u8);
2696
2697 let mut world = World::default();
2698 let mut command_queue = CommandQueue::default();
2699
2700 let entity = Commands::new(&mut command_queue, &world)
2701 .spawn(P(41u8))
2702 .id();
2703
2704 Commands::new(&mut command_queue, &world)
2705 .entity(entity)
2706 .insert_if_neq(P(42u8));
2707
2708 command_queue.apply(&mut world);
2709
2710 let n_added = world.query_filtered::<(), Added<P>>().iter(&world).count();
2711
2712 assert_eq!(n_added, 1);
2713 assert_eq!(world.get::<P>(entity).unwrap().0, 42);
2714
2715 world.clear_trackers();
2716
2717 Commands::new(&mut command_queue, &world)
2718 .entity(entity)
2719 .insert_if_neq(P(42u8));
2720
2721 command_queue.apply(&mut world);
2722
2723 let n_added = world.query_filtered::<(), Added<P>>().iter(&world).count();
2724
2725 assert_eq!(n_added, 0);
2726 assert_eq!(world.get::<P>(entity).unwrap().0, 42);
2727
2728 world.clear_trackers();
2729
2730 Commands::new(&mut command_queue, &world)
2731 .entity(entity)
2732 .insert_if_neq(P(42u8));
2733
2734 let entity2 = Commands::new(&mut command_queue, &world).spawn_empty().id();
2735
2736 Commands::new(&mut command_queue, &world)
2737 .entity(entity2)
2738 .insert_if_neq(P(42u8));
2739 command_queue.apply(&mut world);
2740
2741 let n_added = world.query_filtered::<(), Added<P>>().iter(&world).count();
2742
2743 assert_eq!(n_added, 1);
2744 assert_eq!(world.get::<P>(entity2).unwrap().0, 42);
2745 }
2746
2747 #[cfg(feature = "track_location")]
2748 #[test]
2749 fn insert_component_if_not_equal_tracks_caller() {
2750 use core::panic::Location;
2751
2752 #[derive(Component, PartialEq)]
2753 struct P(u8);
2754
2755 let mut world = World::default();
2756 let mut command_queue = CommandQueue::default();
2757
2758 let entity = Commands::new(&mut command_queue, &world)
2759 .spawn(P(41u8))
2760 .id();
2761 command_queue.apply(&mut world);
2762 world.clear_trackers();
2763
2764 macro_rules! insert_if_neq_with_expected_caller {
2765 ($commands:expr, $entity:expr, $component:expr) => {{
2766 $commands.entity($entity).insert_if_neq($component);
2767 Location::caller()
2768 }};
2769 }
2770
2771 let expected = insert_if_neq_with_expected_caller!(
2772 Commands::new(&mut command_queue, &world),
2773 entity,
2774 P(42u8)
2775 );
2776 command_queue.apply(&mut world);
2777
2778 assert_eq!(
2779 world
2780 .entity(entity)
2781 .get_changed_by::<P>()
2782 .unwrap()
2783 .into_option(),
2784 Some(expected)
2785 );
2786 }
2787
2788 #[test]
2789 fn remove_components() {
2790 let mut world = World::default();
2791
2792 let mut command_queue = CommandQueue::default();
2793 let (dense_dropck, dense_is_dropped) = DropCk::new_pair();
2794 let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();
2795 let sparse_dropck = SparseDropCk(sparse_dropck);
2796
2797 let entity = Commands::new(&mut command_queue, &world)
2798 .spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
2799 .id();
2800 command_queue.apply(&mut world);
2801 let results_before = world
2802 .query::<(&W<u32>, &W<u64>)>()
2803 .iter(&world)
2804 .map(|(a, b)| (a.0, b.0))
2805 .collect::<Vec<_>>();
2806 assert_eq!(results_before, vec![(1u32, 2u64)]);
2807
2808 // test component removal
2809 Commands::new(&mut command_queue, &world)
2810 .entity(entity)
2811 .remove::<W<u32>>()
2812 .remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();
2813
2814 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
2815 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);
2816 command_queue.apply(&mut world);
2817 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);
2818 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);
2819
2820 let results_after = world
2821 .query::<(&W<u32>, &W<u64>)>()
2822 .iter(&world)
2823 .map(|(a, b)| (a.0, b.0))
2824 .collect::<Vec<_>>();
2825 assert_eq!(results_after, vec![]);
2826 let results_after_u64 = world
2827 .query::<&W<u64>>()
2828 .iter(&world)
2829 .map(|v| v.0)
2830 .collect::<Vec<_>>();
2831 assert_eq!(results_after_u64, vec![]);
2832 }
2833
2834 #[test]
2835 fn remove_components_by_id() {
2836 let mut world = World::default();
2837
2838 let mut command_queue = CommandQueue::default();
2839 let (dense_dropck, dense_is_dropped) = DropCk::new_pair();
2840 let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();
2841 let sparse_dropck = SparseDropCk(sparse_dropck);
2842
2843 let entity = Commands::new(&mut command_queue, &world)
2844 .spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
2845 .id();
2846 command_queue.apply(&mut world);
2847 let results_before = world
2848 .query::<(&W<u32>, &W<u64>)>()
2849 .iter(&world)
2850 .map(|(a, b)| (a.0, b.0))
2851 .collect::<Vec<_>>();
2852 assert_eq!(results_before, vec![(1u32, 2u64)]);
2853
2854 // test component removal
2855 Commands::new(&mut command_queue, &world)
2856 .entity(entity)
2857 .remove_by_id(world.components().get_id(TypeId::of::<W<u32>>()).unwrap())
2858 .remove_by_id(world.components().get_id(TypeId::of::<W<u64>>()).unwrap())
2859 .remove_by_id(world.components().get_id(TypeId::of::<DropCk>()).unwrap())
2860 .remove_by_id(
2861 world
2862 .components()
2863 .get_id(TypeId::of::<SparseDropCk>())
2864 .unwrap(),
2865 );
2866
2867 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
2868 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);
2869 command_queue.apply(&mut world);
2870 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);
2871 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);
2872
2873 let results_after = world
2874 .query::<(&W<u32>, &W<u64>)>()
2875 .iter(&world)
2876 .map(|(a, b)| (a.0, b.0))
2877 .collect::<Vec<_>>();
2878 assert_eq!(results_after, vec![]);
2879 let results_after_u64 = world
2880 .query::<&W<u64>>()
2881 .iter(&world)
2882 .map(|v| v.0)
2883 .collect::<Vec<_>>();
2884 assert_eq!(results_after_u64, vec![]);
2885 }
2886
2887 #[test]
2888 fn remove_resources() {
2889 let mut world = World::default();
2890 let mut queue = CommandQueue::default();
2891 {
2892 let mut commands = Commands::new(&mut queue, &world);
2893 commands.insert_resource(V(123i32));
2894 commands.insert_resource(V(456.0f64));
2895 }
2896
2897 queue.apply(&mut world);
2898 assert!(world.contains_resource::<V<i32>>());
2899 assert!(world.contains_resource::<V<f64>>());
2900
2901 {
2902 let mut commands = Commands::new(&mut queue, &world);
2903 // test resource removal
2904 commands.remove_resource::<V<i32>>();
2905 }
2906 queue.apply(&mut world);
2907 assert!(!world.contains_resource::<V<i32>>());
2908 assert!(world.contains_resource::<V<f64>>());
2909 }
2910
2911 #[test]
2912 fn insert_resource_if_not_equal() {
2913 #[derive(Resource, PartialEq)]
2914 struct P(u8);
2915
2916 let mut world = World::default();
2917 let mut queue = CommandQueue::default();
2918
2919 {
2920 let mut commands = Commands::new(&mut queue, &world);
2921 commands.insert_resource_if_neq(P(41));
2922 }
2923
2924 queue.apply(&mut world);
2925 assert!(world.is_resource_added::<P>());
2926 assert_eq!(world.get_resource::<P>().unwrap().0, 41);
2927
2928 world.clear_trackers();
2929
2930 {
2931 let mut commands = Commands::new(&mut queue, &world);
2932 commands.insert_resource_if_neq(P(42));
2933 }
2934
2935 queue.apply(&mut world);
2936 assert!(world.is_resource_changed::<P>());
2937 assert_eq!(world.get_resource::<P>().unwrap().0, 42);
2938
2939 world.clear_trackers();
2940
2941 {
2942 let mut commands = Commands::new(&mut queue, &world);
2943 commands.insert_resource_if_neq(P(42));
2944 }
2945
2946 queue.apply(&mut world);
2947 assert!(!world.is_resource_changed::<P>());
2948 assert_eq!(world.get_resource::<P>().unwrap().0, 42);
2949 }
2950
2951 #[cfg(feature = "track_location")]
2952 #[test]
2953 fn insert_resource_if_not_equal_tracks_caller() {
2954 use crate::change_detection::DetectChanges;
2955 use core::panic::Location;
2956
2957 #[derive(Resource, PartialEq)]
2958 struct P(u8);
2959
2960 let mut world = World::default();
2961 let mut queue = CommandQueue::default();
2962
2963 macro_rules! insert_resource_if_neq_with_expected_caller {
2964 ($commands:expr, $resource:expr) => {{
2965 $commands.insert_resource_if_neq($resource);
2966 Location::caller()
2967 }};
2968 }
2969 let expected1 =
2970 insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(41));
2971
2972 queue.apply(&mut world);
2973
2974 assert_eq!(
2975 world
2976 .get_resource_ref::<P>()
2977 .unwrap()
2978 .changed_by()
2979 .into_option(),
2980 Some(expected1)
2981 );
2982
2983 world.clear_trackers();
2984
2985 let expected2 =
2986 insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(42));
2987
2988 queue.apply(&mut world);
2989
2990 assert_eq!(
2991 world
2992 .get_resource_ref::<P>()
2993 .unwrap()
2994 .changed_by()
2995 .into_option(),
2996 Some(expected2)
2997 );
2998
2999 world.clear_trackers();
3000
3001 let expected3 =
3002 insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(42));
3003
3004 queue.apply(&mut world);
3005
3006 assert_ne!(
3007 world
3008 .get_resource_ref::<P>()
3009 .unwrap()
3010 .changed_by()
3011 .into_option(),
3012 Some(expected3)
3013 );
3014 }
3015
3016 #[test]
3017 fn remove_component_with_required_components() {
3018 #[derive(Component)]
3019 #[require(Y)]
3020 struct X;
3021
3022 #[derive(Component, Default)]
3023 struct Y;
3024
3025 #[derive(Component)]
3026 struct Z;
3027
3028 let mut world = World::default();
3029 let mut queue = CommandQueue::default();
3030 let e = {
3031 let mut commands = Commands::new(&mut queue, &world);
3032 commands.spawn((X, Z)).id()
3033 };
3034 queue.apply(&mut world);
3035
3036 assert!(world.get::<Y>(e).is_some());
3037 assert!(world.get::<X>(e).is_some());
3038 assert!(world.get::<Z>(e).is_some());
3039
3040 {
3041 let mut commands = Commands::new(&mut queue, &world);
3042 commands.entity(e).remove_with_requires::<X>();
3043 }
3044 queue.apply(&mut world);
3045
3046 assert!(world.get::<Y>(e).is_none());
3047 assert!(world.get::<X>(e).is_none());
3048
3049 assert!(world.get::<Z>(e).is_some());
3050 }
3051
3052 #[test]
3053 fn unregister_system_cached_commands() {
3054 let mut world = World::default();
3055 let mut queue = CommandQueue::default();
3056
3057 fn nothing() {}
3058
3059 let resources = world.iter_resources().count();
3060 let id = world.register_system_cached(nothing);
3061 assert_eq!(world.iter_resources().count(), resources + 1);
3062 assert!(world.get_entity(id.entity).is_ok());
3063
3064 let mut commands = Commands::new(&mut queue, &world);
3065 commands.unregister_system_cached(nothing);
3066 queue.apply(&mut world);
3067 assert_eq!(world.iter_resources().count(), resources);
3068 assert!(world.get_entity(id.entity).is_err());
3069 }
3070
3071 fn is_send<T: Send>() {}
3072 fn is_sync<T: Sync>() {}
3073
3074 #[test]
3075 fn test_commands_are_send_and_sync() {
3076 is_send::<Commands>();
3077 is_sync::<Commands>();
3078 }
3079
3080 #[test]
3081 fn append() {
3082 let mut world = World::default();
3083 let mut queue_1 = CommandQueue::default();
3084 {
3085 let mut commands = Commands::new(&mut queue_1, &world);
3086 commands.insert_resource(V(123i32));
3087 }
3088 let mut queue_2 = CommandQueue::default();
3089 {
3090 let mut commands = Commands::new(&mut queue_2, &world);
3091 commands.insert_resource(V(456.0f64));
3092 }
3093 queue_1.append(&mut queue_2);
3094 queue_1.apply(&mut world);
3095 assert!(world.contains_resource::<V<i32>>());
3096 assert!(world.contains_resource::<V<f64>>());
3097 }
3098
3099 #[test]
3100 fn track_spawn_ticks() {
3101 let mut world = World::default();
3102 world.increment_change_tick();
3103 let expected = world.change_tick();
3104 let id = world.commands().spawn_empty().id();
3105 world.flush();
3106 assert_eq!(
3107 Some(expected),
3108 world.entities().entity_get_spawn_or_despawn_tick(id)
3109 );
3110 }
3111
3112 #[test]
3113 fn despawn_all_command_despawns() {
3114 let mut world = World::default();
3115
3116 #[derive(Component)]
3117 struct ComponentA;
3118
3119 #[derive(Component)]
3120 struct ComponentB;
3121
3122 #[derive(Component)]
3123 struct ComponentC;
3124
3125 let a_1 = world.spawn(ComponentA).id();
3126 let a_2 = world.spawn(ComponentA).id();
3127 let a_b = world.spawn((ComponentA, ComponentB)).id();
3128 let c = world.spawn(ComponentC).id();
3129
3130 let mut commands = world.commands();
3131
3132 commands.despawn_all::<Or<(With<ComponentC>, (With<ComponentA>, Without<ComponentB>))>>();
3133
3134 world.flush_commands();
3135
3136 assert!(world.get_entity(a_1).is_err());
3137 assert!(world.get_entity(a_2).is_err());
3138 assert!(world.get_entity(c).is_err());
3139
3140 assert!(world.get_entity(a_b).is_ok());
3141 }
3142
3143 #[test]
3144 fn despawn_all_where_command_checks() {
3145 let mut world = World::default();
3146
3147 #[derive(Component)]
3148 struct ComponentA(usize);
3149
3150 let a_1 = world.spawn(ComponentA(1)).id();
3151 let a_2 = world.spawn(ComponentA(2)).id();
3152 let a_3 = world.spawn(ComponentA(3)).id();
3153
3154 let mut commands = world.commands();
3155
3156 commands.despawn_all_where::<&ComponentA, ()>(|data| data.0 < 3);
3157
3158 world.flush_commands();
3159
3160 assert!(world.get_entity(a_1).is_err());
3161 assert!(world.get_entity(a_2).is_err());
3162
3163 assert!(world.get_entity(a_3).is_ok());
3164 }
3165}