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