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