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: impl Into<SystemId> + Send) {
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>(
977 &mut self,
978 id: impl Into<SystemId<I>> + Send,
979 input: I::Inner<'static>,
980 ) where
981 I: SystemInput<Inner<'static>: Send> + 'static,
982 {
983 self.queue(command::run_system_with(id, input).handle_error_with(warn));
984 }
985
986 /// Registers a system and returns its [`SystemId`] so it can later be called by
987 /// [`Commands::run_system`] or [`World::run_system`].
988 ///
989 /// This is different from adding systems to a [`Schedule`](crate::schedule::Schedule),
990 /// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.
991 ///
992 /// Using a [`Schedule`](crate::schedule::Schedule) is still preferred for most cases
993 /// due to its better performance and ability to run non-conflicting systems simultaneously.
994 ///
995 /// # Note
996 ///
997 /// If the same system is registered more than once,
998 /// each registration will be considered a different system,
999 /// and they will each be given their own [`SystemId`].
1000 ///
1001 /// If you want to avoid registering the same system multiple times,
1002 /// consider using [`Commands::run_system_cached`] or storing the [`SystemId`]
1003 /// in a [`Local`](crate::system::Local).
1004 ///
1005 /// # Example
1006 ///
1007 /// ```
1008 /// # use bevy_ecs::{prelude::*, world::CommandQueue, system::SystemId};
1009 /// #[derive(Resource)]
1010 /// struct Counter(i32);
1011 ///
1012 /// fn register_system(
1013 /// mut commands: Commands,
1014 /// mut local_system: Local<Option<SystemId>>,
1015 /// ) {
1016 /// if let Some(system) = *local_system {
1017 /// commands.run_system(system);
1018 /// } else {
1019 /// *local_system = Some(commands.register_system(increment_counter));
1020 /// }
1021 /// }
1022 ///
1023 /// fn increment_counter(mut value: ResMut<Counter>) {
1024 /// value.0 += 1;
1025 /// }
1026 ///
1027 /// # let mut world = World::default();
1028 /// # world.insert_resource(Counter(0));
1029 /// # let mut queue_1 = CommandQueue::default();
1030 /// # let systemid = {
1031 /// # let mut commands = Commands::new(&mut queue_1, &world);
1032 /// # commands.register_system(increment_counter)
1033 /// # };
1034 /// # let mut queue_2 = CommandQueue::default();
1035 /// # {
1036 /// # let mut commands = Commands::new(&mut queue_2, &world);
1037 /// # commands.run_system(systemid);
1038 /// # }
1039 /// # queue_1.append(&mut queue_2);
1040 /// # queue_1.apply(&mut world);
1041 /// # assert_eq!(1, world.resource::<Counter>().0);
1042 /// # bevy_ecs::system::assert_is_system(register_system);
1043 /// ```
1044 pub fn register_system<I, O, M>(
1045 &mut self,
1046 system: impl IntoSystem<I, O, M> + 'static,
1047 ) -> SystemId<I, O>
1048 where
1049 I: SystemInput + Send + 'static,
1050 O: Send + 'static,
1051 {
1052 let entity = self.spawn_empty().id();
1053 let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));
1054 self.entity(entity).insert(system);
1055 SystemId::from_entity(entity)
1056 }
1057
1058 /// Removes a system previously registered with [`Commands::register_system`]
1059 /// or [`World::register_system`].
1060 ///
1061 /// After removing a system, the [`SystemId`] becomes invalid
1062 /// and attempting to use it afterwards will result in an error.
1063 /// Re-adding the removed system will register it with a new `SystemId`.
1064 ///
1065 /// # Fallible
1066 ///
1067 /// This command will fail if the given [`SystemId`]
1068 /// does not correspond to a [`System`](crate::system::System).
1069 ///
1070 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
1071 /// which will be handled by [logging the error at the `warn` level](warn).
1072 pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)
1073 where
1074 I: SystemInput + Send + 'static,
1075 O: Send + 'static,
1076 {
1077 self.queue(command::unregister_system(system_id).handle_error_with(warn));
1078 }
1079
1080 /// Removes a system previously registered with one of the following:
1081 /// - [`Commands::run_system_cached`]
1082 /// - [`World::run_system_cached`]
1083 /// - [`World::register_system_cached`]
1084 ///
1085 /// # Fallible
1086 ///
1087 /// This command will fail if the given system
1088 /// is not currently cached in a [`CachedSystemId`](crate::system::CachedSystemId) resource.
1089 ///
1090 /// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),
1091 /// which will be handled by [logging the error at the `warn` level](warn).
1092 pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)
1093 where
1094 I: SystemInput + Send + 'static,
1095 O: 'static,
1096 M: 'static,
1097 S: IntoSystem<I, O, M> + Send + 'static,
1098 {
1099 self.queue(command::unregister_system_cached(system).handle_error_with(warn));
1100 }
1101
1102 /// Runs a cached system, registering it if necessary.
1103 ///
1104 /// Unlike [`Commands::run_system`], this method does not require manual registration.
1105 ///
1106 /// The first time this method is called for a particular system,
1107 /// it will register the system and store its [`SystemId`] in a
1108 /// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.
1109 ///
1110 /// If you would rather manage the [`SystemId`] yourself,
1111 /// or register multiple copies of the same system,
1112 /// use [`Commands::register_system`] instead.
1113 ///
1114 /// # Limitations
1115 ///
1116 /// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of
1117 /// the same type must be equal. This means that closures that capture the environment, and
1118 /// function pointers, are not accepted.
1119 ///
1120 /// If you want to access values from the environment within a system,
1121 /// consider passing them in as inputs via [`Commands::run_system_cached_with`].
1122 ///
1123 /// If that's not an option, consider [`Commands::register_system`] instead.
1124 pub fn run_system_cached<M, S>(&mut self, system: S)
1125 where
1126 M: 'static,
1127 S: IntoSystem<(), (), M> + Send + 'static,
1128 {
1129 self.queue(command::run_system_cached(system).handle_error_with(warn));
1130 }
1131
1132 /// Runs a cached system with an input, registering it if necessary.
1133 ///
1134 /// Unlike [`Commands::run_system_with`], this method does not require manual registration.
1135 ///
1136 /// To use the supplied input, the system should have a [`SystemInput`] as the first parameter.
1137 ///
1138 /// The first time this method is called for a particular system,
1139 /// it will register the system and store its [`SystemId`] in a
1140 /// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.
1141 ///
1142 /// If you would rather manage the [`SystemId`] yourself,
1143 /// or register multiple copies of the same system,
1144 /// use [`Commands::register_system`] instead.
1145 ///
1146 /// # Limitations
1147 ///
1148 /// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of
1149 /// the same type must be equal. This means that closures that capture the environment, and
1150 /// function pointers, are not accepted.
1151 ///
1152 /// If you want to access values from the environment within a system,
1153 /// consider passing them in as inputs.
1154 ///
1155 /// If that's not an option, consider [`Commands::register_system`] instead.
1156 pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)
1157 where
1158 I: SystemInput<Inner<'static>: Send> + Send + 'static,
1159 M: 'static,
1160 S: IntoSystem<I, (), M> + Send + 'static,
1161 {
1162 self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));
1163 }
1164
1165 /// Triggers the given [`Event`], which will run any [`Observer`]s watching for it.
1166 ///
1167 /// [`Observer`]: crate::observer::Observer
1168 #[track_caller]
1169 pub fn trigger<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {
1170 self.queue(command::trigger(event));
1171 }
1172
1173 /// Triggers the given [`Event`] using the given [`Trigger`], which will run any [`Observer`]s watching for it.
1174 ///
1175 /// [`Trigger`]: crate::event::Trigger
1176 /// [`Observer`]: crate::observer::Observer
1177 #[track_caller]
1178 pub fn trigger_with<E: Event<Trigger<'static>: Send + Sync>>(
1179 &mut self,
1180 event: E,
1181 trigger: E::Trigger<'static>,
1182 ) {
1183 self.queue(command::trigger_with(event, trigger));
1184 }
1185
1186 /// Spawns an [`Observer`](crate::observer::Observer) and returns the [`EntityCommands`] associated
1187 /// with the entity that stores the observer.
1188 ///
1189 /// `observer` can be any system whose first parameter is [`On`].
1190 ///
1191 /// **Calling [`observe`](EntityCommands::observe) on the returned
1192 /// [`EntityCommands`] will observe the observer itself, which you very
1193 /// likely do not want.**
1194 ///
1195 /// # Panics
1196 ///
1197 /// Panics if the given system is an exclusive system.
1198 ///
1199 /// [`On`]: crate::observer::On
1200 pub fn add_observer<M>(&mut self, observer: impl IntoObserver<M>) -> EntityCommands<'_> {
1201 self.spawn(observer.into_observer())
1202 }
1203
1204 /// Writes an arbitrary [`Message`].
1205 ///
1206 /// This is a convenience method for writing messages
1207 /// without requiring a [`MessageWriter`](crate::message::MessageWriter).
1208 ///
1209 /// # Performance
1210 ///
1211 /// Since this is a command, exclusive world access is used, which means that it will not profit from
1212 /// system-level parallelism on supported platforms.
1213 ///
1214 /// If these messages are performance-critical or very frequently sent,
1215 /// consider using a [`MessageWriter`](crate::message::MessageWriter) instead.
1216 #[track_caller]
1217 pub fn write_message<M: Message>(&mut self, message: M) -> &mut Self {
1218 self.queue(command::write_message(message));
1219 self
1220 }
1221
1222 /// Runs the schedule corresponding to the given [`ScheduleLabel`].
1223 ///
1224 /// Calls [`World::try_run_schedule`](World::try_run_schedule).
1225 ///
1226 /// # Fallible
1227 ///
1228 /// This command will fail if the given [`ScheduleLabel`]
1229 /// does not correspond to a [`Schedule`](crate::schedule::Schedule).
1230 ///
1231 /// It will internally return a [`TryRunScheduleError`](crate::world::error::TryRunScheduleError),
1232 /// which will be handled by [logging the error at the `warn` level](warn).
1233 ///
1234 /// # Example
1235 ///
1236 /// ```
1237 /// # use bevy_ecs::prelude::*;
1238 /// # use bevy_ecs::schedule::ScheduleLabel;
1239 /// # #[derive(Default, Resource)]
1240 /// # struct Counter(u32);
1241 /// #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]
1242 /// struct FooSchedule;
1243 ///
1244 /// # fn foo_system(mut counter: ResMut<Counter>) {
1245 /// # counter.0 += 1;
1246 /// # }
1247 /// #
1248 /// # let mut schedule = Schedule::new(FooSchedule);
1249 /// # schedule.add_systems(foo_system);
1250 /// #
1251 /// # let mut world = World::default();
1252 /// #
1253 /// # world.init_resource::<Counter>();
1254 /// # world.add_schedule(schedule);
1255 /// #
1256 /// # assert_eq!(world.resource::<Counter>().0, 0);
1257 /// #
1258 /// # let mut commands = world.commands();
1259 /// commands.run_schedule(FooSchedule);
1260 /// #
1261 /// # world.flush();
1262 /// #
1263 /// # assert_eq!(world.resource::<Counter>().0, 1);
1264 /// ```
1265 pub fn run_schedule(&mut self, label: impl ScheduleLabel) {
1266 self.queue(command::run_schedule(label).handle_error_with(warn));
1267 }
1268}
1269
1270/// A list of commands that will be run to modify an [`Entity`].
1271///
1272/// # Note
1273///
1274/// Most [`Commands`] (and thereby [`EntityCommands`]) are deferred:
1275/// when you call the command, if it requires mutable access to the [`World`]
1276/// (that is, if it removes, adds, or changes something), it's not executed immediately.
1277///
1278/// Instead, the command is added to a "command queue."
1279/// The command queue is applied later
1280/// when the [`ApplyDeferred`](crate::schedule::ApplyDeferred) system runs.
1281/// Commands are executed one-by-one so that
1282/// each command can have exclusive access to the `World`.
1283///
1284/// # Fallible
1285///
1286/// Due to their deferred nature, an entity you're trying to change with an [`EntityCommand`]
1287/// can be despawned by the time the command is executed.
1288///
1289/// All deferred entity commands will check whether the entity exists at the time of execution
1290/// and will return an error if it doesn't.
1291///
1292/// # Error handling
1293///
1294/// An [`EntityCommand`] can return a [`Result`](crate::error::Result),
1295/// which will be passed to an [error handler](crate::error) if the `Result` is an error.
1296///
1297/// The fallback error handler panics. It can be configured via
1298/// the [`FallbackErrorHandler`](crate::error::FallbackErrorHandler) resource.
1299///
1300/// Alternatively, you can customize the error handler for a specific command
1301/// by calling [`EntityCommands::queue_handled`].
1302///
1303/// The [`error`](crate::error) module provides some simple error handlers for convenience.
1304pub struct EntityCommands<'a> {
1305 pub(crate) entity: Entity,
1306 pub(crate) commands: Commands<'a, 'a>,
1307}
1308
1309impl<'a> EntityCommands<'a> {
1310 /// Returns the [`Entity`] id of the entity.
1311 ///
1312 /// # Example
1313 ///
1314 /// ```
1315 /// # use bevy_ecs::prelude::*;
1316 /// #
1317 /// fn my_system(mut commands: Commands) {
1318 /// let entity_id = commands.spawn_empty().id();
1319 /// }
1320 /// # bevy_ecs::system::assert_is_system(my_system);
1321 /// ```
1322 #[inline]
1323 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
1324 pub fn id(&self) -> Entity {
1325 self.entity
1326 }
1327
1328 /// Returns an [`EntityCommands`] with a smaller lifetime.
1329 ///
1330 /// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`.
1331 pub fn reborrow(&mut self) -> EntityCommands<'_> {
1332 EntityCommands {
1333 entity: self.entity,
1334 commands: self.commands.reborrow(),
1335 }
1336 }
1337
1338 /// Get an [`EntityEntryCommands`] for the [`Component`] `T`,
1339 /// allowing you to modify it or insert it if it isn't already present.
1340 ///
1341 /// See also [`insert_if_new`](Self::insert_if_new),
1342 /// which lets you insert a [`Bundle`] without overwriting it.
1343 ///
1344 /// # Example
1345 ///
1346 /// ```
1347 /// # use bevy_ecs::prelude::*;
1348 /// # #[derive(Resource)]
1349 /// # struct PlayerEntity { entity: Entity }
1350 /// #[derive(Component)]
1351 /// struct Level(u32);
1352 ///
1353 ///
1354 /// #[derive(Component, Default)]
1355 /// struct Mana {
1356 /// max: u32,
1357 /// current: u32,
1358 /// }
1359 ///
1360 /// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {
1361 /// // If a component already exists then modify it, otherwise insert a default value
1362 /// commands
1363 /// .entity(player.entity)
1364 /// .entry::<Level>()
1365 /// .and_modify(|mut lvl| lvl.0 += 1)
1366 /// .or_insert(Level(0));
1367 ///
1368 /// // Add a default value if none exists, and then modify the existing or new value
1369 /// commands
1370 /// .entity(player.entity)
1371 /// .entry::<Mana>()
1372 /// .or_default()
1373 /// .and_modify(|mut mana| {
1374 /// mana.max += 10;
1375 /// mana.current = mana.max;
1376 /// });
1377 /// }
1378 ///
1379 /// # bevy_ecs::system::assert_is_system(level_up_system);
1380 /// ```
1381 pub fn entry<T: Component>(&mut self) -> EntityEntryCommands<'_, T> {
1382 EntityEntryCommands {
1383 entity_commands: self.reborrow(),
1384 marker: PhantomData,
1385 }
1386 }
1387
1388 /// Adds a [`Bundle`] of components to the entity.
1389 ///
1390 /// This will overwrite any previous value(s) of the same component type.
1391 /// See [`EntityCommands::insert_if_new`] to keep the old value instead.
1392 ///
1393 /// # Example
1394 ///
1395 /// ```
1396 /// # use bevy_ecs::prelude::*;
1397 /// # #[derive(Resource)]
1398 /// # struct PlayerEntity { entity: Entity }
1399 /// #[derive(Component)]
1400 /// struct Health(u32);
1401 /// #[derive(Component)]
1402 /// struct Strength(u32);
1403 /// #[derive(Component)]
1404 /// struct Defense(u32);
1405 ///
1406 /// #[derive(Bundle)]
1407 /// struct CombatBundle {
1408 /// health: Health,
1409 /// strength: Strength,
1410 /// }
1411 ///
1412 /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1413 /// commands
1414 /// .entity(player.entity)
1415 /// // You can insert individual components:
1416 /// .insert(Defense(10))
1417 /// // You can also insert pre-defined bundles of components:
1418 /// .insert(CombatBundle {
1419 /// health: Health(100),
1420 /// strength: Strength(40),
1421 /// })
1422 /// // You can also insert tuples of components and bundles.
1423 /// // This is equivalent to the calls above:
1424 /// .insert((
1425 /// Defense(10),
1426 /// CombatBundle {
1427 /// health: Health(100),
1428 /// strength: Strength(40),
1429 /// },
1430 /// ));
1431 /// }
1432 /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
1433 /// ```
1434 #[track_caller]
1435 pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
1436 self.queue(entity_command::insert(bundle, InsertMode::Replace))
1437 }
1438
1439 /// Adds a [`Bundle`] of components to the entity if the predicate returns true.
1440 ///
1441 /// This is useful for chaining method calls.
1442 ///
1443 /// # Example
1444 ///
1445 /// ```
1446 /// # use bevy_ecs::prelude::*;
1447 /// # #[derive(Resource)]
1448 /// # struct PlayerEntity { entity: Entity }
1449 /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }
1450 /// #[derive(Component)]
1451 /// struct StillLoadingStats;
1452 /// #[derive(Component)]
1453 /// struct Health(u32);
1454 ///
1455 /// fn add_health_system(mut commands: Commands, player: Res<PlayerEntity>) {
1456 /// commands
1457 /// .entity(player.entity)
1458 /// .insert_if(Health(10), || !player.is_spectator())
1459 /// .remove::<StillLoadingStats>();
1460 /// }
1461 /// # bevy_ecs::system::assert_is_system(add_health_system);
1462 /// ```
1463 #[track_caller]
1464 pub fn insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1465 where
1466 F: FnOnce() -> bool,
1467 {
1468 if condition() {
1469 self.insert(bundle)
1470 } else {
1471 self
1472 }
1473 }
1474
1475 /// Adds a [`Bundle`] of components to the entity without overwriting.
1476 ///
1477 /// This is the same as [`EntityCommands::insert`], but in case of duplicate
1478 /// components will leave the old values instead of replacing them with new ones.
1479 ///
1480 /// See also [`entry`](Self::entry), which lets you modify a [`Component`] if it's present,
1481 /// as well as initialize it with a default value.
1482 #[track_caller]
1483 pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {
1484 self.queue(entity_command::insert(bundle, InsertMode::Keep))
1485 }
1486
1487 /// Adds a [`Bundle`] of components to the entity without overwriting if the
1488 /// predicate returns true.
1489 ///
1490 /// This is the same as [`EntityCommands::insert_if`], but in case of duplicate
1491 /// components will leave the old values instead of replacing them with new ones.
1492 #[track_caller]
1493 pub fn insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1494 where
1495 F: FnOnce() -> bool,
1496 {
1497 if condition() {
1498 self.insert_if_new(bundle)
1499 } else {
1500 self
1501 }
1502 }
1503
1504 /// Adds a [`Component`] to the entity if the component is different or
1505 /// missing.
1506 #[track_caller]
1507 pub fn insert_if_neq<T: Component + PartialEq>(&mut self, component: T) -> &mut Self {
1508 let caller = MaybeLocation::caller();
1509
1510 self.queue(move |mut entity: EntityWorldMut| {
1511 if entity
1512 .get::<T>()
1513 .is_none_or(|old_component| *old_component != component)
1514 {
1515 move_as_ptr!(component);
1516 entity.insert_with_caller(
1517 component,
1518 InsertMode::Replace,
1519 caller,
1520 RelationshipHookMode::Run,
1521 );
1522 }
1523 })
1524 }
1525
1526 /// Adds a dynamic [`Component`] to the entity.
1527 ///
1528 /// This will overwrite any previous value(s) of the same component type.
1529 ///
1530 /// You should prefer to use the typed API [`EntityCommands::insert`] where possible.
1531 ///
1532 /// # Safety
1533 ///
1534 /// - [`ComponentId`] must be from the same world as `self`.
1535 /// - `T` must have the same layout as the one passed during `component_id` creation.
1536 #[track_caller]
1537 pub unsafe fn insert_by_id<T: Send + 'static>(
1538 &mut self,
1539 component_id: ComponentId,
1540 value: T,
1541 ) -> &mut Self {
1542 self.queue(
1543 // SAFETY:
1544 // - `ComponentId` safety is ensured by the caller.
1545 // - `T` safety is ensured by the caller.
1546 unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },
1547 )
1548 }
1549
1550 /// Adds a dynamic [`Component`] to the entity.
1551 ///
1552 /// This will overwrite any previous value(s) of the same component type.
1553 ///
1554 /// You should prefer to use the typed API [`EntityCommands::try_insert`] where possible.
1555 ///
1556 /// # Note
1557 ///
1558 /// If the entity does not exist when this command is executed,
1559 /// the resulting error will be ignored.
1560 ///
1561 /// # Safety
1562 ///
1563 /// - [`ComponentId`] must be from the same world as `self`.
1564 /// - `T` must have the same layout as the one passed during `component_id` creation.
1565 #[track_caller]
1566 pub unsafe fn try_insert_by_id<T: Send + 'static>(
1567 &mut self,
1568 component_id: ComponentId,
1569 value: T,
1570 ) -> &mut Self {
1571 self.queue_silenced(
1572 // SAFETY:
1573 // - `ComponentId` safety is ensured by the caller.
1574 // - `T` safety is ensured by the caller.
1575 unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },
1576 )
1577 }
1578
1579 /// Adds a [`Bundle`] of components to the entity.
1580 ///
1581 /// This will overwrite any previous value(s) of the same component type.
1582 ///
1583 /// # Note
1584 ///
1585 /// If the entity does not exist when this command is executed,
1586 /// the resulting error will be ignored.
1587 ///
1588 /// # Example
1589 ///
1590 /// ```
1591 /// # use bevy_ecs::prelude::*;
1592 /// # #[derive(Resource)]
1593 /// # struct PlayerEntity { entity: Entity }
1594 /// #[derive(Component)]
1595 /// struct Health(u32);
1596 /// #[derive(Component)]
1597 /// struct Strength(u32);
1598 /// #[derive(Component)]
1599 /// struct Defense(u32);
1600 ///
1601 /// #[derive(Bundle)]
1602 /// struct CombatBundle {
1603 /// health: Health,
1604 /// strength: Strength,
1605 /// }
1606 ///
1607 /// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1608 /// commands.entity(player.entity)
1609 /// // You can insert individual components:
1610 /// .try_insert(Defense(10))
1611 /// // You can also insert tuples of components:
1612 /// .try_insert(CombatBundle {
1613 /// health: Health(100),
1614 /// strength: Strength(40),
1615 /// });
1616 ///
1617 /// // Suppose this occurs in a parallel adjacent system or process.
1618 /// commands.entity(player.entity).despawn();
1619 ///
1620 /// // This will not panic nor will it add the component.
1621 /// commands.entity(player.entity).try_insert(Defense(5));
1622 /// }
1623 /// # bevy_ecs::system::assert_is_system(add_combat_stats_system);
1624 /// ```
1625 #[track_caller]
1626 pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self {
1627 self.queue_silenced(entity_command::insert(bundle, InsertMode::Replace))
1628 }
1629
1630 /// Adds a [`Bundle`] of components to the entity if the predicate returns true.
1631 ///
1632 /// This is useful for chaining method calls.
1633 ///
1634 /// # Note
1635 ///
1636 /// If the entity does not exist when this command is executed,
1637 /// the resulting error will be ignored.
1638 #[track_caller]
1639 pub fn try_insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1640 where
1641 F: FnOnce() -> bool,
1642 {
1643 if condition() {
1644 self.try_insert(bundle)
1645 } else {
1646 self
1647 }
1648 }
1649
1650 /// Adds a [`Bundle`] of components to the entity without overwriting if the
1651 /// predicate returns true.
1652 ///
1653 /// This is the same as [`EntityCommands::try_insert_if`], but in case of duplicate
1654 /// components will leave the old values instead of replacing them with new ones.
1655 ///
1656 /// # Note
1657 ///
1658 /// If the entity does not exist when this command is executed,
1659 /// the resulting error will be ignored.
1660 #[track_caller]
1661 pub fn try_insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self
1662 where
1663 F: FnOnce() -> bool,
1664 {
1665 if condition() {
1666 self.try_insert_if_new(bundle)
1667 } else {
1668 self
1669 }
1670 }
1671
1672 /// Adds a [`Bundle`] of components to the entity without overwriting.
1673 ///
1674 /// This is the same as [`EntityCommands::try_insert`], but in case of duplicate
1675 /// components will leave the old values instead of replacing them with new ones.
1676 ///
1677 /// # Note
1678 ///
1679 /// If the entity does not exist when this command is executed,
1680 /// the resulting error will be ignored.
1681 #[track_caller]
1682 pub fn try_insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {
1683 self.queue_silenced(entity_command::insert(bundle, InsertMode::Keep))
1684 }
1685
1686 /// Removes a [`Bundle`] of components from the entity.
1687 ///
1688 /// This will remove all components that intersect with the provided bundle;
1689 /// the entity does not need to have all the components in the bundle.
1690 ///
1691 /// This will emit a warning if the entity does not exist.
1692 ///
1693 /// # Example
1694 ///
1695 /// ```
1696 /// # use bevy_ecs::prelude::*;
1697 /// # #[derive(Resource)]
1698 /// # struct PlayerEntity { entity: Entity }
1699 /// #[derive(Component)]
1700 /// struct Health(u32);
1701 /// #[derive(Component)]
1702 /// struct Strength(u32);
1703 /// #[derive(Component)]
1704 /// struct Defense(u32);
1705 ///
1706 /// #[derive(Bundle)]
1707 /// struct CombatBundle {
1708 /// health: Health,
1709 /// strength: Strength,
1710 /// }
1711 ///
1712 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1713 /// commands
1714 /// .entity(player.entity)
1715 /// // You can remove individual components:
1716 /// .remove::<Defense>()
1717 /// // You can also remove pre-defined bundles of components:
1718 /// .remove::<CombatBundle>()
1719 /// // You can also remove tuples of components and bundles.
1720 /// // This is equivalent to the calls above:
1721 /// .remove::<(Defense, CombatBundle)>();
1722 /// }
1723 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1724 /// ```
1725 #[track_caller]
1726 pub fn remove<B: Bundle>(&mut self) -> &mut Self {
1727 self.queue_handled(entity_command::remove::<B>(), warn)
1728 }
1729
1730 /// Removes a [`Bundle`] of components from the entity if the predicate returns true.
1731 ///
1732 /// This is useful for chaining method calls.
1733 ///
1734 /// # Example
1735 ///
1736 /// ```
1737 /// # use bevy_ecs::prelude::*;
1738 /// # #[derive(Resource)]
1739 /// # struct PlayerEntity { entity: Entity }
1740 /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }
1741 /// #[derive(Component)]
1742 /// struct Health(u32);
1743 /// #[derive(Component)]
1744 /// struct Strength(u32);
1745 /// #[derive(Component)]
1746 /// struct Defense(u32);
1747 ///
1748 /// #[derive(Bundle)]
1749 /// struct CombatBundle {
1750 /// health: Health,
1751 /// strength: Strength,
1752 /// }
1753 ///
1754 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1755 /// commands
1756 /// .entity(player.entity)
1757 /// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator());
1758 /// }
1759 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1760 /// ```
1761 #[track_caller]
1762 pub fn remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {
1763 if condition() {
1764 self.remove::<B>()
1765 } else {
1766 self
1767 }
1768 }
1769
1770 /// Removes a [`Bundle`] of components from the entity if the predicate returns true.
1771 ///
1772 /// This is useful for chaining method calls.
1773 ///
1774 /// # Note
1775 ///
1776 /// If the entity does not exist when this command is executed,
1777 /// the resulting error will be ignored.
1778 #[track_caller]
1779 pub fn try_remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {
1780 if condition() {
1781 self.try_remove::<B>()
1782 } else {
1783 self
1784 }
1785 }
1786
1787 /// Removes a [`Bundle`] of components from the entity.
1788 ///
1789 /// This will remove all components that intersect with the provided bundle;
1790 /// the entity does not need to have all the components in the bundle.
1791 ///
1792 /// Unlike [`Self::remove`],
1793 /// this will not emit a warning if the entity does not exist.
1794 ///
1795 /// # Example
1796 ///
1797 /// ```
1798 /// # use bevy_ecs::prelude::*;
1799 /// # #[derive(Resource)]
1800 /// # struct PlayerEntity { entity: Entity }
1801 /// #[derive(Component)]
1802 /// struct Health(u32);
1803 /// #[derive(Component)]
1804 /// struct Strength(u32);
1805 /// #[derive(Component)]
1806 /// struct Defense(u32);
1807 ///
1808 /// #[derive(Bundle)]
1809 /// struct CombatBundle {
1810 /// health: Health,
1811 /// strength: Strength,
1812 /// }
1813 ///
1814 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
1815 /// commands
1816 /// .entity(player.entity)
1817 /// // You can remove individual components:
1818 /// .try_remove::<Defense>()
1819 /// // You can also remove pre-defined bundles of components:
1820 /// .try_remove::<CombatBundle>()
1821 /// // You can also remove tuples of components and bundles.
1822 /// // This is equivalent to the calls above:
1823 /// .try_remove::<(Defense, CombatBundle)>();
1824 /// }
1825 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
1826 /// ```
1827 pub fn try_remove<B: Bundle>(&mut self) -> &mut Self {
1828 self.queue_silenced(entity_command::remove::<B>())
1829 }
1830
1831 /// Removes a [`Bundle`] of components from the entity,
1832 /// and also removes any components required by the components in the bundle.
1833 ///
1834 /// This will remove all components that intersect with the provided bundle;
1835 /// the entity does not need to have all the components in the bundle.
1836 ///
1837 /// # Example
1838 ///
1839 /// ```
1840 /// # use bevy_ecs::prelude::*;
1841 /// # #[derive(Resource)]
1842 /// # struct PlayerEntity { entity: Entity }
1843 /// #
1844 /// #[derive(Component)]
1845 /// #[require(B)]
1846 /// struct A;
1847 /// #[derive(Component, Default)]
1848 /// struct B;
1849 ///
1850 /// fn remove_with_requires_system(mut commands: Commands, player: Res<PlayerEntity>) {
1851 /// commands
1852 /// .entity(player.entity)
1853 /// // Removes both A and B from the entity, because B is required by A.
1854 /// .remove_with_requires::<A>();
1855 /// }
1856 /// # bevy_ecs::system::assert_is_system(remove_with_requires_system);
1857 /// ```
1858 #[track_caller]
1859 pub fn remove_with_requires<B: Bundle>(&mut self) -> &mut Self {
1860 self.queue(entity_command::remove_with_requires::<B>())
1861 }
1862
1863 /// Removes a dynamic [`Component`] from the entity if it exists.
1864 ///
1865 /// # Panics
1866 ///
1867 /// Panics if the provided [`ComponentId`] does not exist in the [`World`].
1868 #[track_caller]
1869 pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {
1870 self.queue(entity_command::remove_by_id(component_id))
1871 }
1872
1873 /// Removes all components associated with the entity.
1874 #[track_caller]
1875 pub fn clear(&mut self) -> &mut Self {
1876 self.queue(entity_command::clear())
1877 }
1878
1879 /// Despawns the entity.
1880 ///
1881 /// This will emit a warning if the entity does not exist.
1882 ///
1883 /// # Note
1884 ///
1885 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)
1886 /// that is configured to despawn descendants.
1887 ///
1888 /// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1889 ///
1890 /// # Example
1891 ///
1892 /// ```
1893 /// # use bevy_ecs::prelude::*;
1894 /// # #[derive(Resource)]
1895 /// # struct CharacterToRemove { entity: Entity }
1896 /// #
1897 /// fn remove_character_system(
1898 /// mut commands: Commands,
1899 /// character_to_remove: Res<CharacterToRemove>
1900 /// ) {
1901 /// commands.entity(character_to_remove.entity).despawn();
1902 /// }
1903 /// # bevy_ecs::system::assert_is_system(remove_character_system);
1904 /// ```
1905 #[track_caller]
1906 pub fn despawn(&mut self) {
1907 self.queue_handled(entity_command::despawn(), warn);
1908 }
1909
1910 /// Despawns the entity.
1911 ///
1912 /// Unlike [`Self::despawn`],
1913 /// this will not emit a warning if the entity does not exist.
1914 ///
1915 /// # Note
1916 ///
1917 /// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)
1918 /// that is configured to despawn descendants.
1919 ///
1920 /// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).
1921 pub fn try_despawn(&mut self) {
1922 self.queue_silenced(entity_command::despawn());
1923 }
1924
1925 /// Pushes an [`EntityCommand`] to the queue,
1926 /// which will get executed for the current [`Entity`].
1927 ///
1928 /// The [fallback error handler](crate::error::FallbackErrorHandler)
1929 /// will be used to handle error cases.
1930 /// Every [`EntityCommand`] checks whether the entity exists at the time of execution
1931 /// and returns an error if it does not.
1932 ///
1933 /// To use a custom error handler, see [`EntityCommands::queue_handled`].
1934 ///
1935 /// The command can be:
1936 /// - A custom struct that implements [`EntityCommand`].
1937 /// - A closure or function that matches the following signature:
1938 /// - [`(EntityWorldMut)`](EntityWorldMut)
1939 /// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]
1940 /// - A built-in command from the [`entity_command`] module.
1941 ///
1942 /// # Example
1943 ///
1944 /// ```
1945 /// # use bevy_ecs::prelude::*;
1946 /// # fn my_system(mut commands: Commands) {
1947 /// commands
1948 /// .spawn_empty()
1949 /// // Closures with this signature implement `EntityCommand`.
1950 /// .queue(|entity: EntityWorldMut| {
1951 /// println!("Executed an EntityCommand for {}", entity.id());
1952 /// });
1953 /// # }
1954 /// # bevy_ecs::system::assert_is_system(my_system);
1955 /// ```
1956 pub fn queue(&mut self, command: impl EntityCommand) -> &mut Self {
1957 self.commands.queue(command.with_entity(self.entity));
1958 self
1959 }
1960
1961 /// Pushes an [`EntityCommand`] to the queue,
1962 /// which will get executed for the current [`Entity`].
1963 ///
1964 /// The given `error_handler` will be used to handle error cases.
1965 /// Every [`EntityCommand`] checks whether the entity exists at the time of execution
1966 /// and returns an error if it does not.
1967 ///
1968 /// To implicitly use the fallback error handler, see [`EntityCommands::queue`].
1969 ///
1970 /// The command can be:
1971 /// - A custom struct that implements [`EntityCommand`].
1972 /// - A closure or function that matches the following signature:
1973 /// - [`(EntityWorldMut)`](EntityWorldMut)
1974 /// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]
1975 /// - A built-in command from the [`entity_command`] module.
1976 ///
1977 /// # Example
1978 ///
1979 /// ```
1980 /// # use bevy_ecs::prelude::*;
1981 /// # fn my_system(mut commands: Commands) {
1982 /// use bevy_ecs::error::warn;
1983 ///
1984 /// commands
1985 /// .spawn_empty()
1986 /// // Closures with this signature implement `EntityCommand`.
1987 /// .queue_handled(
1988 /// |entity: EntityWorldMut| -> Result {
1989 /// let value: usize = "100".parse()?;
1990 /// println!("Successfully parsed the value {} for entity {}", value, entity.id());
1991 /// Ok(())
1992 /// },
1993 /// warn
1994 /// );
1995 /// # }
1996 /// # bevy_ecs::system::assert_is_system(my_system);
1997 /// ```
1998 pub fn queue_handled(
1999 &mut self,
2000 command: impl EntityCommand,
2001 error_handler: fn(BevyError, ErrorContext),
2002 ) -> &mut Self {
2003 self.commands
2004 .queue_handled(command.with_entity(self.entity), error_handler);
2005 self
2006 }
2007
2008 /// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].
2009 ///
2010 /// Unlike [`EntityCommands::queue_handled`], this will completely ignore any errors that occur.
2011 pub fn queue_silenced(&mut self, command: impl EntityCommand) -> &mut Self {
2012 self.commands
2013 .queue_silenced(command.with_entity(self.entity));
2014 self
2015 }
2016
2017 /// Removes all components except the given [`Bundle`] from the entity.
2018 ///
2019 /// # Example
2020 ///
2021 /// ```
2022 /// # use bevy_ecs::prelude::*;
2023 /// # #[derive(Resource)]
2024 /// # struct PlayerEntity { entity: Entity }
2025 /// #[derive(Component)]
2026 /// struct Health(u32);
2027 /// #[derive(Component)]
2028 /// struct Strength(u32);
2029 /// #[derive(Component)]
2030 /// struct Defense(u32);
2031 ///
2032 /// #[derive(Bundle)]
2033 /// struct CombatBundle {
2034 /// health: Health,
2035 /// strength: Strength,
2036 /// }
2037 ///
2038 /// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
2039 /// commands
2040 /// .entity(player.entity)
2041 /// // You can retain a pre-defined Bundle of components,
2042 /// // with this removing only the Defense component.
2043 /// .retain::<CombatBundle>()
2044 /// // You can also retain only a single component.
2045 /// .retain::<Health>();
2046 /// }
2047 /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
2048 /// ```
2049 #[track_caller]
2050 pub fn retain<B: Bundle>(&mut self) -> &mut Self {
2051 self.queue(entity_command::retain::<B>())
2052 }
2053
2054 /// Logs the components of the entity at the [`info`](log::info) level.
2055 pub fn log_components(&mut self) -> &mut Self {
2056 self.queue(entity_command::log_components())
2057 }
2058
2059 /// Returns the underlying [`Commands`].
2060 pub fn commands(&mut self) -> Commands<'_, '_> {
2061 self.commands.reborrow()
2062 }
2063
2064 /// Returns a mutable reference to the underlying [`Commands`].
2065 pub fn commands_mut(&mut self) -> &mut Commands<'a, 'a> {
2066 &mut self.commands
2067 }
2068
2069 /// Creates an [`Observer`](crate::observer::Observer) watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]
2070 /// targets this entity.
2071 pub fn observe<M>(&mut self, observer: impl IntoEntityObserver<M>) -> &mut Self {
2072 self.queue(entity_command::observe(observer))
2073 }
2074
2075 /// Clones parts of an entity (components, observers, etc.) onto another entity,
2076 /// configured through [`EntityClonerBuilder`].
2077 ///
2078 /// The other entity will receive all the components of the original that implement
2079 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
2080 /// [denied](EntityClonerBuilder::deny) in the `config`.
2081 ///
2082 /// # Panics
2083 ///
2084 /// The command will panic when applied if the target entity does not exist.
2085 ///
2086 /// # Example
2087 ///
2088 /// Configure through [`EntityClonerBuilder<OptOut>`] as follows:
2089 /// ```
2090 /// # use bevy_ecs::prelude::*;
2091 /// #[derive(Component, Clone)]
2092 /// struct ComponentA(u32);
2093 /// #[derive(Component, Clone)]
2094 /// struct ComponentB(u32);
2095 ///
2096 /// fn example_system(mut commands: Commands) {
2097 /// // Create an empty entity.
2098 /// let target = commands.spawn_empty().id();
2099 ///
2100 /// // Create a new entity and keep its EntityCommands.
2101 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2102 ///
2103 /// // Clone ComponentA but not ComponentB onto the target.
2104 /// entity.clone_with_opt_out(target, |builder| {
2105 /// builder.deny::<ComponentB>();
2106 /// });
2107 /// }
2108 /// # bevy_ecs::system::assert_is_system(example_system);
2109 /// ```
2110 ///
2111 /// See [`EntityClonerBuilder`] for more options.
2112 pub fn clone_with_opt_out(
2113 &mut self,
2114 target: Entity,
2115 config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
2116 ) -> &mut Self {
2117 self.queue(entity_command::clone_with_opt_out(target, config))
2118 }
2119
2120 /// Clones parts of an entity (components, observers, etc.) onto another entity,
2121 /// configured through [`EntityClonerBuilder`].
2122 ///
2123 /// The other entity will receive only the components of the original that implement
2124 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
2125 /// [allowed](EntityClonerBuilder::allow) in the `config`.
2126 ///
2127 /// # Panics
2128 ///
2129 /// The command will panic when applied if the target entity does not exist.
2130 ///
2131 /// # Example
2132 ///
2133 /// Configure through [`EntityClonerBuilder<OptIn>`] as follows:
2134 /// ```
2135 /// # use bevy_ecs::prelude::*;
2136 /// #[derive(Component, Clone)]
2137 /// struct ComponentA(u32);
2138 /// #[derive(Component, Clone)]
2139 /// struct ComponentB(u32);
2140 ///
2141 /// fn example_system(mut commands: Commands) {
2142 /// // Create an empty entity.
2143 /// let target = commands.spawn_empty().id();
2144 ///
2145 /// // Create a new entity and keep its EntityCommands.
2146 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2147 ///
2148 /// // Clone ComponentA but not ComponentB onto the target.
2149 /// entity.clone_with_opt_in(target, |builder| {
2150 /// builder.allow::<ComponentA>();
2151 /// });
2152 /// }
2153 /// # bevy_ecs::system::assert_is_system(example_system);
2154 /// ```
2155 ///
2156 /// See [`EntityClonerBuilder`] for more options.
2157 pub fn clone_with_opt_in(
2158 &mut self,
2159 target: Entity,
2160 config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
2161 ) -> &mut Self {
2162 self.queue(entity_command::clone_with_opt_in(target, config))
2163 }
2164
2165 /// Spawns a clone of this entity and returns the [`EntityCommands`] of the clone.
2166 ///
2167 /// The clone will receive all the components of the original that implement
2168 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2169 ///
2170 /// To configure cloning behavior (such as only cloning certain components),
2171 /// use [`EntityCommands::clone_and_spawn_with_opt_out`]/
2172 /// [`opt_out`](EntityCommands::clone_and_spawn_with_opt_out).
2173 ///
2174 /// # Note
2175 ///
2176 /// If the original entity does not exist when this command is applied,
2177 /// the returned entity will have no components.
2178 ///
2179 /// # Example
2180 ///
2181 /// ```
2182 /// # use bevy_ecs::prelude::*;
2183 /// #[derive(Component, Clone)]
2184 /// struct ComponentA(u32);
2185 /// #[derive(Component, Clone)]
2186 /// struct ComponentB(u32);
2187 ///
2188 /// fn example_system(mut commands: Commands) {
2189 /// // Create a new entity and store its EntityCommands.
2190 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2191 ///
2192 /// // Create a clone of the entity.
2193 /// let mut entity_clone = entity.clone_and_spawn();
2194 /// }
2195 /// # bevy_ecs::system::assert_is_system(example_system);
2196 pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> {
2197 self.clone_and_spawn_with_opt_out(|_| {})
2198 }
2199
2200 /// Spawns a clone of this entity and allows configuring cloning behavior
2201 /// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.
2202 ///
2203 /// The clone will receive all the components of the original that implement
2204 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
2205 /// [denied](EntityClonerBuilder::deny) in the `config`.
2206 ///
2207 /// See the methods on [`EntityClonerBuilder<OptOut>`] for more options.
2208 ///
2209 /// # Note
2210 ///
2211 /// If the original entity does not exist when this command is applied,
2212 /// the returned entity will have no components.
2213 ///
2214 /// # Example
2215 ///
2216 /// ```
2217 /// # use bevy_ecs::prelude::*;
2218 /// #[derive(Component, Clone)]
2219 /// struct ComponentA(u32);
2220 /// #[derive(Component, Clone)]
2221 /// struct ComponentB(u32);
2222 ///
2223 /// fn example_system(mut commands: Commands) {
2224 /// // Create a new entity and store its EntityCommands.
2225 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2226 ///
2227 /// // Create a clone of the entity with ComponentA but without ComponentB.
2228 /// let mut entity_clone = entity.clone_and_spawn_with_opt_out(|builder| {
2229 /// builder.deny::<ComponentB>();
2230 /// });
2231 /// }
2232 /// # bevy_ecs::system::assert_is_system(example_system);
2233 pub fn clone_and_spawn_with_opt_out(
2234 &mut self,
2235 config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
2236 ) -> EntityCommands<'_> {
2237 let entity_clone = self.commands().spawn_empty().id();
2238 self.clone_with_opt_out(entity_clone, config);
2239 EntityCommands {
2240 commands: self.commands_mut().reborrow(),
2241 entity: entity_clone,
2242 }
2243 }
2244
2245 /// Spawns a clone of this entity and allows configuring cloning behavior
2246 /// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.
2247 ///
2248 /// The clone will receive only the components of the original that implement
2249 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
2250 /// [allowed](EntityClonerBuilder::allow) in the `config`.
2251 ///
2252 /// See the methods on [`EntityClonerBuilder<OptIn>`] for more options.
2253 ///
2254 /// # Note
2255 ///
2256 /// If the original entity does not exist when this command is applied,
2257 /// the returned entity will have no components.
2258 ///
2259 /// # Example
2260 ///
2261 /// ```
2262 /// # use bevy_ecs::prelude::*;
2263 /// #[derive(Component, Clone)]
2264 /// struct ComponentA(u32);
2265 /// #[derive(Component, Clone)]
2266 /// struct ComponentB(u32);
2267 ///
2268 /// fn example_system(mut commands: Commands) {
2269 /// // Create a new entity and store its EntityCommands.
2270 /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));
2271 ///
2272 /// // Create a clone of the entity with ComponentA but without ComponentB.
2273 /// let mut entity_clone = entity.clone_and_spawn_with_opt_in(|builder| {
2274 /// builder.allow::<ComponentA>();
2275 /// });
2276 /// }
2277 /// # bevy_ecs::system::assert_is_system(example_system);
2278 pub fn clone_and_spawn_with_opt_in(
2279 &mut self,
2280 config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
2281 ) -> EntityCommands<'_> {
2282 let entity_clone = self.commands().spawn_empty().id();
2283 self.clone_with_opt_in(entity_clone, config);
2284 EntityCommands {
2285 commands: self.commands_mut().reborrow(),
2286 entity: entity_clone,
2287 }
2288 }
2289
2290 /// Clones the specified components of this entity and inserts them into another entity.
2291 ///
2292 /// Components can only be cloned if they implement
2293 /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2294 ///
2295 /// # Panics
2296 ///
2297 /// The command will panic when applied if the target entity does not exist.
2298 pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
2299 self.queue(entity_command::clone_components::<B>(target))
2300 }
2301
2302 /// Moves the specified components of this entity into another entity.
2303 ///
2304 /// Components with [`Ignore`] clone behavior will not be moved, while components that
2305 /// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.
2306 /// All other components will be moved without any other special handling.
2307 ///
2308 /// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.
2309 ///
2310 /// # Panics
2311 ///
2312 /// The command will panic when applied if the target entity does not exist.
2313 ///
2314 /// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore
2315 /// [`Custom`]: crate::component::ComponentCloneBehavior::Custom
2316 pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
2317 self.queue(entity_command::move_components::<B>(target))
2318 }
2319
2320 /// Passes the current entity into the given function, and triggers the [`EntityEvent`] returned by that function.
2321 ///
2322 /// # Example
2323 ///
2324 /// A surprising number of functions meet the trait bounds for `event_fn`:
2325 ///
2326 /// ```rust
2327 /// # use bevy_ecs::prelude::*;
2328 ///
2329 /// #[derive(EntityEvent)]
2330 /// struct Explode(Entity);
2331 ///
2332 /// impl From<Entity> for Explode {
2333 /// fn from(entity: Entity) -> Self {
2334 /// Explode(entity)
2335 /// }
2336 /// }
2337 ///
2338 ///
2339 /// fn trigger_via_constructor(mut commands: Commands) {
2340 /// // The fact that `Explode` is a single-field tuple struct
2341 /// // ensures that `Explode(entity)` is a function that generates
2342 /// // an EntityEvent, meeting the trait bounds for `event_fn`.
2343 /// commands.spawn_empty().trigger(Explode);
2344 ///
2345 /// }
2346 ///
2347 ///
2348 /// fn trigger_via_from_trait(mut commands: Commands) {
2349 /// // This variant also works for events like `struct Explode { entity: Entity }`
2350 /// commands.spawn_empty().trigger(Explode::from);
2351 /// }
2352 ///
2353 /// fn trigger_via_closure(mut commands: Commands) {
2354 /// commands.spawn_empty().trigger(|entity| Explode(entity));
2355 /// }
2356 /// ```
2357 #[track_caller]
2358 pub fn trigger<'t, E: EntityEvent<Trigger<'t>: Default>>(
2359 &mut self,
2360 event_fn: impl FnOnce(Entity) -> E,
2361 ) -> &mut Self {
2362 let event = (event_fn)(self.entity);
2363 self.commands.trigger(event);
2364 self
2365 }
2366}
2367
2368/// A wrapper around [`EntityCommands`] with convenience methods for working with a specified component type.
2369pub struct EntityEntryCommands<'a, T> {
2370 entity_commands: EntityCommands<'a>,
2371 marker: PhantomData<T>,
2372}
2373
2374impl<'a, T: Component<Mutability = Mutable>> EntityEntryCommands<'a, T> {
2375 /// Modify the component `T` if it exists, using the function `modify`.
2376 pub fn and_modify(&mut self, modify: impl FnOnce(Mut<T>) + Send + Sync + 'static) -> &mut Self {
2377 self.entity_commands
2378 .queue(move |mut entity: EntityWorldMut| {
2379 if let Some(value) = entity.get_mut() {
2380 modify(value);
2381 }
2382 });
2383 self
2384 }
2385}
2386
2387impl<'a, T: Component> EntityEntryCommands<'a, T> {
2388 /// Returns a [`EntityEntryCommands`] with a smaller lifetime.
2389 ///
2390 /// This is useful if you have `&mut EntityEntryCommands` but need `EntityEntryCommands`.
2391 pub fn reborrow(&mut self) -> EntityEntryCommands<'_, T> {
2392 EntityEntryCommands {
2393 entity_commands: self.entity_commands.reborrow(),
2394 marker: PhantomData,
2395 }
2396 }
2397
2398 /// [Insert](EntityCommands::insert) `default` into this entity,
2399 /// if `T` is not already present.
2400 #[track_caller]
2401 pub fn or_insert(&mut self, default: T) -> &mut Self {
2402 self.entity_commands.insert_if_new(default);
2403 self
2404 }
2405
2406 /// [Insert](EntityCommands::insert) `default` into this entity,
2407 /// if `T` is not already present.
2408 ///
2409 /// # Note
2410 ///
2411 /// If the entity does not exist when this command is executed,
2412 /// the resulting error will be ignored.
2413 #[track_caller]
2414 pub fn or_try_insert(&mut self, default: T) -> &mut Self {
2415 self.entity_commands.try_insert_if_new(default);
2416 self
2417 }
2418
2419 /// [Insert](EntityCommands::insert) the value returned from `default` into this entity,
2420 /// if `T` is not already present.
2421 ///
2422 /// `default` will only be invoked if the component will actually be inserted.
2423 #[track_caller]
2424 pub fn or_insert_with<F>(&mut self, default: F) -> &mut Self
2425 where
2426 F: FnOnce() -> T + Send + 'static,
2427 {
2428 self.entity_commands
2429 .queue(entity_command::insert_with(default, InsertMode::Keep));
2430 self
2431 }
2432
2433 /// [Insert](EntityCommands::insert) the value returned from `default` into this entity,
2434 /// if `T` is not already present.
2435 ///
2436 /// `default` will only be invoked if the component will actually be inserted.
2437 ///
2438 /// # Note
2439 ///
2440 /// If the entity does not exist when this command is executed,
2441 /// the resulting error will be ignored.
2442 #[track_caller]
2443 pub fn or_try_insert_with<F>(&mut self, default: F) -> &mut Self
2444 where
2445 F: FnOnce() -> T + Send + 'static,
2446 {
2447 self.entity_commands
2448 .queue_silenced(entity_command::insert_with(default, InsertMode::Keep));
2449 self
2450 }
2451
2452 /// [Insert](EntityCommands::insert) `T::default` into this entity,
2453 /// if `T` is not already present.
2454 ///
2455 /// `T::default` will only be invoked if the component will actually be inserted.
2456 #[track_caller]
2457 pub fn or_default(&mut self) -> &mut Self
2458 where
2459 T: Default,
2460 {
2461 self.or_insert_with(T::default)
2462 }
2463
2464 /// [Insert](EntityCommands::insert) `T::from_world` into this entity,
2465 /// if `T` is not already present.
2466 ///
2467 /// `T::from_world` will only be invoked if the component will actually be inserted.
2468 #[track_caller]
2469 pub fn or_from_world(&mut self) -> &mut Self
2470 where
2471 T: FromWorld,
2472 {
2473 self.entity_commands
2474 .queue(entity_command::insert_from_world::<T>(InsertMode::Keep));
2475 self
2476 }
2477
2478 /// Get the [`EntityCommands`] from which the [`EntityEntryCommands`] was initiated.
2479 ///
2480 /// This allows you to continue chaining method calls after calling [`EntityCommands::entry`].
2481 ///
2482 /// # Example
2483 ///
2484 /// ```
2485 /// # use bevy_ecs::prelude::*;
2486 /// # #[derive(Resource)]
2487 /// # struct PlayerEntity { entity: Entity }
2488 /// #[derive(Component)]
2489 /// struct Level(u32);
2490 ///
2491 /// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {
2492 /// commands
2493 /// .entity(player.entity)
2494 /// .entry::<Level>()
2495 /// // Modify the component if it exists.
2496 /// .and_modify(|mut lvl| lvl.0 += 1)
2497 /// // Otherwise, insert a default value.
2498 /// .or_insert(Level(0))
2499 /// // Return the EntityCommands for the entity.
2500 /// .entity()
2501 /// // Continue chaining method calls.
2502 /// .insert(Name::new("Player"));
2503 /// }
2504 /// # bevy_ecs::system::assert_is_system(level_up_system);
2505 /// ```
2506 pub fn entity(&mut self) -> EntityCommands<'_> {
2507 self.entity_commands.reborrow()
2508 }
2509}
2510
2511#[cfg(test)]
2512mod tests {
2513 use crate::{
2514 component::Component,
2515 resource::Resource,
2516 system::Commands,
2517 world::{CommandQueue, FromWorld, World},
2518 };
2519 use alloc::{string::String, sync::Arc, vec, vec::Vec};
2520 use core::{
2521 any::TypeId,
2522 sync::atomic::{AtomicUsize, Ordering},
2523 };
2524
2525 #[expect(
2526 dead_code,
2527 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."
2528 )]
2529 #[derive(Component)]
2530 #[component(storage = "SparseSet")]
2531 struct SparseDropCk(DropCk);
2532
2533 #[derive(Component)]
2534 struct DropCk(Arc<AtomicUsize>);
2535 impl DropCk {
2536 fn new_pair() -> (Self, Arc<AtomicUsize>) {
2537 let atomic = Arc::new(AtomicUsize::new(0));
2538 (DropCk(atomic.clone()), atomic)
2539 }
2540 }
2541
2542 impl Drop for DropCk {
2543 fn drop(&mut self) {
2544 self.0.as_ref().fetch_add(1, Ordering::Relaxed);
2545 }
2546 }
2547
2548 #[derive(Component)]
2549 struct W<T>(T);
2550
2551 #[derive(Resource)]
2552 struct V<T>(T);
2553
2554 fn simple_command(world: &mut World) {
2555 world.spawn((W(0u32), W(42u64)));
2556 }
2557
2558 impl FromWorld for W<String> {
2559 fn from_world(world: &mut World) -> Self {
2560 let v = world.resource::<V<usize>>();
2561 Self("*".repeat(v.0))
2562 }
2563 }
2564
2565 impl Default for W<u8> {
2566 fn default() -> Self {
2567 unreachable!()
2568 }
2569 }
2570
2571 #[test]
2572 fn entity_commands_entry() {
2573 let mut world = World::default();
2574 let mut queue = CommandQueue::default();
2575 let mut commands = Commands::new(&mut queue, &world);
2576 let entity = commands.spawn_empty().id();
2577 commands
2578 .entity(entity)
2579 .entry::<W<u32>>()
2580 .and_modify(|_| unreachable!());
2581 queue.apply(&mut world);
2582 assert!(!world.entity(entity).contains::<W<u32>>());
2583 let mut commands = Commands::new(&mut queue, &world);
2584 commands
2585 .entity(entity)
2586 .entry::<W<u32>>()
2587 .or_insert(W(0))
2588 .and_modify(|mut val| {
2589 val.0 = 21;
2590 });
2591 queue.apply(&mut world);
2592 assert_eq!(21, world.get::<W<u32>>(entity).unwrap().0);
2593 let mut commands = Commands::new(&mut queue, &world);
2594 commands
2595 .entity(entity)
2596 .entry::<W<u64>>()
2597 .and_modify(|_| unreachable!())
2598 .or_insert(W(42));
2599 queue.apply(&mut world);
2600 assert_eq!(42, world.get::<W<u64>>(entity).unwrap().0);
2601 world.insert_resource(V(5_usize));
2602 let mut commands = Commands::new(&mut queue, &world);
2603 commands.entity(entity).entry::<W<String>>().or_from_world();
2604 queue.apply(&mut world);
2605 assert_eq!("*****", &world.get::<W<String>>(entity).unwrap().0);
2606 let mut commands = Commands::new(&mut queue, &world);
2607 let id = commands.entity(entity).entry::<W<u64>>().entity().id();
2608 queue.apply(&mut world);
2609 assert_eq!(id, entity);
2610 let mut commands = Commands::new(&mut queue, &world);
2611 commands
2612 .entity(entity)
2613 .entry::<W<u8>>()
2614 .or_insert_with(|| W(5))
2615 .or_insert_with(|| unreachable!())
2616 .or_try_insert_with(|| unreachable!())
2617 .or_default()
2618 .or_from_world();
2619 queue.apply(&mut world);
2620 assert_eq!(5, world.get::<W<u8>>(entity).unwrap().0);
2621 }
2622
2623 #[test]
2624 fn commands() {
2625 let mut world = World::default();
2626 let mut command_queue = CommandQueue::default();
2627 let entity = Commands::new(&mut command_queue, &world)
2628 .spawn((W(1u32), W(2u64)))
2629 .id();
2630 command_queue.apply(&mut world);
2631 assert_eq!(world.query::<&W<u32>>().query(&world).count(), 1);
2632 let results = world
2633 .query::<(&W<u32>, &W<u64>)>()
2634 .iter(&world)
2635 .map(|(a, b)| (a.0, b.0))
2636 .collect::<Vec<_>>();
2637 assert_eq!(results, vec![(1u32, 2u64)]);
2638 // test entity despawn
2639 {
2640 let mut commands = Commands::new(&mut command_queue, &world);
2641 commands.entity(entity).despawn();
2642 commands.entity(entity).despawn(); // double despawn shouldn't panic
2643 }
2644 command_queue.apply(&mut world);
2645 let results2 = world
2646 .query::<(&W<u32>, &W<u64>)>()
2647 .iter(&world)
2648 .map(|(a, b)| (a.0, b.0))
2649 .collect::<Vec<_>>();
2650 assert_eq!(results2, vec![]);
2651
2652 // test adding simple (FnOnce) commands
2653 {
2654 let mut commands = Commands::new(&mut command_queue, &world);
2655
2656 // set up a simple command using a closure that adds one additional entity
2657 commands.queue(|world: &mut World| {
2658 world.spawn((W(42u32), W(0u64)));
2659 });
2660
2661 // set up a simple command using a function that adds one additional entity
2662 commands.queue(simple_command);
2663 }
2664 command_queue.apply(&mut world);
2665 let results3 = world
2666 .query::<(&W<u32>, &W<u64>)>()
2667 .iter(&world)
2668 .map(|(a, b)| (a.0, b.0))
2669 .collect::<Vec<_>>();
2670
2671 assert_eq!(results3, vec![(42u32, 0u64), (0u32, 42u64)]);
2672 }
2673
2674 #[test]
2675 fn insert_components() {
2676 let mut world = World::default();
2677 let mut command_queue1 = CommandQueue::default();
2678
2679 // insert components
2680 let entity = Commands::new(&mut command_queue1, &world)
2681 .spawn(())
2682 .insert_if(W(1u8), || true)
2683 .insert_if(W(2u8), || false)
2684 .insert_if_new(W(1u16))
2685 .insert_if_new(W(2u16))
2686 .insert_if_new_and(W(1u32), || false)
2687 .insert_if_new_and(W(2u32), || true)
2688 .insert_if_new_and(W(3u32), || true)
2689 .id();
2690 command_queue1.apply(&mut world);
2691
2692 let results = world
2693 .query::<(&W<u8>, &W<u16>, &W<u32>)>()
2694 .iter(&world)
2695 .map(|(a, b, c)| (a.0, b.0, c.0))
2696 .collect::<Vec<_>>();
2697 assert_eq!(results, vec![(1u8, 1u16, 2u32)]);
2698
2699 // try to insert components after despawning entity
2700 // in another command queue
2701 Commands::new(&mut command_queue1, &world)
2702 .entity(entity)
2703 .try_insert_if_new_and(W(1u64), || true);
2704
2705 let mut command_queue2 = CommandQueue::default();
2706 Commands::new(&mut command_queue2, &world)
2707 .entity(entity)
2708 .despawn();
2709 command_queue2.apply(&mut world);
2710 command_queue1.apply(&mut world);
2711 }
2712
2713 #[test]
2714 fn insert_component_if_not_equal() {
2715 use crate::query::Added;
2716
2717 #[derive(Component, PartialEq)]
2718 struct P(u8);
2719
2720 let mut world = World::default();
2721 let mut command_queue = CommandQueue::default();
2722
2723 let entity = Commands::new(&mut command_queue, &world)
2724 .spawn(P(41u8))
2725 .id();
2726
2727 Commands::new(&mut command_queue, &world)
2728 .entity(entity)
2729 .insert_if_neq(P(42u8));
2730
2731 command_queue.apply(&mut world);
2732
2733 let n_added = world.query_filtered::<(), Added<P>>().iter(&world).count();
2734
2735 assert_eq!(n_added, 1);
2736 assert_eq!(world.get::<P>(entity).unwrap().0, 42);
2737
2738 world.clear_trackers();
2739
2740 Commands::new(&mut command_queue, &world)
2741 .entity(entity)
2742 .insert_if_neq(P(42u8));
2743
2744 command_queue.apply(&mut world);
2745
2746 let n_added = world.query_filtered::<(), Added<P>>().iter(&world).count();
2747
2748 assert_eq!(n_added, 0);
2749 assert_eq!(world.get::<P>(entity).unwrap().0, 42);
2750
2751 world.clear_trackers();
2752
2753 Commands::new(&mut command_queue, &world)
2754 .entity(entity)
2755 .insert_if_neq(P(42u8));
2756
2757 let entity2 = Commands::new(&mut command_queue, &world).spawn_empty().id();
2758
2759 Commands::new(&mut command_queue, &world)
2760 .entity(entity2)
2761 .insert_if_neq(P(42u8));
2762 command_queue.apply(&mut world);
2763
2764 let n_added = world.query_filtered::<(), Added<P>>().iter(&world).count();
2765
2766 assert_eq!(n_added, 1);
2767 assert_eq!(world.get::<P>(entity2).unwrap().0, 42);
2768 }
2769
2770 #[cfg(feature = "track_location")]
2771 #[test]
2772 fn insert_component_if_not_equal_tracks_caller() {
2773 use core::panic::Location;
2774
2775 #[derive(Component, PartialEq)]
2776 struct P(u8);
2777
2778 let mut world = World::default();
2779 let mut command_queue = CommandQueue::default();
2780
2781 let entity = Commands::new(&mut command_queue, &world)
2782 .spawn(P(41u8))
2783 .id();
2784 command_queue.apply(&mut world);
2785 world.clear_trackers();
2786
2787 macro_rules! insert_if_neq_with_expected_caller {
2788 ($commands:expr, $entity:expr, $component:expr) => {{
2789 $commands.entity($entity).insert_if_neq($component);
2790 Location::caller()
2791 }};
2792 }
2793
2794 let expected = insert_if_neq_with_expected_caller!(
2795 Commands::new(&mut command_queue, &world),
2796 entity,
2797 P(42u8)
2798 );
2799 command_queue.apply(&mut world);
2800
2801 assert_eq!(
2802 world
2803 .entity(entity)
2804 .get_changed_by::<P>()
2805 .unwrap()
2806 .into_option(),
2807 Some(expected)
2808 );
2809 }
2810
2811 #[test]
2812 fn remove_components() {
2813 let mut world = World::default();
2814
2815 let mut command_queue = CommandQueue::default();
2816 let (dense_dropck, dense_is_dropped) = DropCk::new_pair();
2817 let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();
2818 let sparse_dropck = SparseDropCk(sparse_dropck);
2819
2820 let entity = Commands::new(&mut command_queue, &world)
2821 .spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
2822 .id();
2823 command_queue.apply(&mut world);
2824 let results_before = world
2825 .query::<(&W<u32>, &W<u64>)>()
2826 .iter(&world)
2827 .map(|(a, b)| (a.0, b.0))
2828 .collect::<Vec<_>>();
2829 assert_eq!(results_before, vec![(1u32, 2u64)]);
2830
2831 // test component removal
2832 Commands::new(&mut command_queue, &world)
2833 .entity(entity)
2834 .remove::<W<u32>>()
2835 .remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();
2836
2837 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
2838 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);
2839 command_queue.apply(&mut world);
2840 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);
2841 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);
2842
2843 let results_after = world
2844 .query::<(&W<u32>, &W<u64>)>()
2845 .iter(&world)
2846 .map(|(a, b)| (a.0, b.0))
2847 .collect::<Vec<_>>();
2848 assert_eq!(results_after, vec![]);
2849 let results_after_u64 = world
2850 .query::<&W<u64>>()
2851 .iter(&world)
2852 .map(|v| v.0)
2853 .collect::<Vec<_>>();
2854 assert_eq!(results_after_u64, vec![]);
2855 }
2856
2857 #[test]
2858 fn remove_components_by_id() {
2859 let mut world = World::default();
2860
2861 let mut command_queue = CommandQueue::default();
2862 let (dense_dropck, dense_is_dropped) = DropCk::new_pair();
2863 let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();
2864 let sparse_dropck = SparseDropCk(sparse_dropck);
2865
2866 let entity = Commands::new(&mut command_queue, &world)
2867 .spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))
2868 .id();
2869 command_queue.apply(&mut world);
2870 let results_before = world
2871 .query::<(&W<u32>, &W<u64>)>()
2872 .iter(&world)
2873 .map(|(a, b)| (a.0, b.0))
2874 .collect::<Vec<_>>();
2875 assert_eq!(results_before, vec![(1u32, 2u64)]);
2876
2877 // test component removal
2878 Commands::new(&mut command_queue, &world)
2879 .entity(entity)
2880 .remove_by_id(world.components().get_id(TypeId::of::<W<u32>>()).unwrap())
2881 .remove_by_id(world.components().get_id(TypeId::of::<W<u64>>()).unwrap())
2882 .remove_by_id(world.components().get_id(TypeId::of::<DropCk>()).unwrap())
2883 .remove_by_id(
2884 world
2885 .components()
2886 .get_id(TypeId::of::<SparseDropCk>())
2887 .unwrap(),
2888 );
2889
2890 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);
2891 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);
2892 command_queue.apply(&mut world);
2893 assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);
2894 assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);
2895
2896 let results_after = world
2897 .query::<(&W<u32>, &W<u64>)>()
2898 .iter(&world)
2899 .map(|(a, b)| (a.0, b.0))
2900 .collect::<Vec<_>>();
2901 assert_eq!(results_after, vec![]);
2902 let results_after_u64 = world
2903 .query::<&W<u64>>()
2904 .iter(&world)
2905 .map(|v| v.0)
2906 .collect::<Vec<_>>();
2907 assert_eq!(results_after_u64, vec![]);
2908 }
2909
2910 #[test]
2911 fn remove_resources() {
2912 let mut world = World::default();
2913 let mut queue = CommandQueue::default();
2914 {
2915 let mut commands = Commands::new(&mut queue, &world);
2916 commands.insert_resource(V(123i32));
2917 commands.insert_resource(V(456.0f64));
2918 }
2919
2920 queue.apply(&mut world);
2921 assert!(world.contains_resource::<V<i32>>());
2922 assert!(world.contains_resource::<V<f64>>());
2923
2924 {
2925 let mut commands = Commands::new(&mut queue, &world);
2926 // test resource removal
2927 commands.remove_resource::<V<i32>>();
2928 }
2929 queue.apply(&mut world);
2930 assert!(!world.contains_resource::<V<i32>>());
2931 assert!(world.contains_resource::<V<f64>>());
2932 }
2933
2934 #[test]
2935 fn insert_resource_if_not_equal() {
2936 #[derive(Resource, PartialEq)]
2937 struct P(u8);
2938
2939 let mut world = World::default();
2940 let mut queue = CommandQueue::default();
2941
2942 {
2943 let mut commands = Commands::new(&mut queue, &world);
2944 commands.insert_resource_if_neq(P(41));
2945 }
2946
2947 queue.apply(&mut world);
2948 assert!(world.is_resource_added::<P>());
2949 assert_eq!(world.get_resource::<P>().unwrap().0, 41);
2950
2951 world.clear_trackers();
2952
2953 {
2954 let mut commands = Commands::new(&mut queue, &world);
2955 commands.insert_resource_if_neq(P(42));
2956 }
2957
2958 queue.apply(&mut world);
2959 assert!(world.is_resource_changed::<P>());
2960 assert_eq!(world.get_resource::<P>().unwrap().0, 42);
2961
2962 world.clear_trackers();
2963
2964 {
2965 let mut commands = Commands::new(&mut queue, &world);
2966 commands.insert_resource_if_neq(P(42));
2967 }
2968
2969 queue.apply(&mut world);
2970 assert!(!world.is_resource_changed::<P>());
2971 assert_eq!(world.get_resource::<P>().unwrap().0, 42);
2972 }
2973
2974 #[cfg(feature = "track_location")]
2975 #[test]
2976 fn insert_resource_if_not_equal_tracks_caller() {
2977 use crate::change_detection::DetectChanges;
2978 use core::panic::Location;
2979
2980 #[derive(Resource, PartialEq)]
2981 struct P(u8);
2982
2983 let mut world = World::default();
2984 let mut queue = CommandQueue::default();
2985
2986 macro_rules! insert_resource_if_neq_with_expected_caller {
2987 ($commands:expr, $resource:expr) => {{
2988 $commands.insert_resource_if_neq($resource);
2989 Location::caller()
2990 }};
2991 }
2992 let expected1 =
2993 insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(41));
2994
2995 queue.apply(&mut world);
2996
2997 assert_eq!(
2998 world
2999 .get_resource_ref::<P>()
3000 .unwrap()
3001 .changed_by()
3002 .into_option(),
3003 Some(expected1)
3004 );
3005
3006 world.clear_trackers();
3007
3008 let expected2 =
3009 insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(42));
3010
3011 queue.apply(&mut world);
3012
3013 assert_eq!(
3014 world
3015 .get_resource_ref::<P>()
3016 .unwrap()
3017 .changed_by()
3018 .into_option(),
3019 Some(expected2)
3020 );
3021
3022 world.clear_trackers();
3023
3024 let expected3 =
3025 insert_resource_if_neq_with_expected_caller!(Commands::new(&mut queue, &world), P(42));
3026
3027 queue.apply(&mut world);
3028
3029 assert_ne!(
3030 world
3031 .get_resource_ref::<P>()
3032 .unwrap()
3033 .changed_by()
3034 .into_option(),
3035 Some(expected3)
3036 );
3037 }
3038
3039 #[test]
3040 fn remove_component_with_required_components() {
3041 #[derive(Component)]
3042 #[require(Y)]
3043 struct X;
3044
3045 #[derive(Component, Default)]
3046 struct Y;
3047
3048 #[derive(Component)]
3049 struct Z;
3050
3051 let mut world = World::default();
3052 let mut queue = CommandQueue::default();
3053 let e = {
3054 let mut commands = Commands::new(&mut queue, &world);
3055 commands.spawn((X, Z)).id()
3056 };
3057 queue.apply(&mut world);
3058
3059 assert!(world.get::<Y>(e).is_some());
3060 assert!(world.get::<X>(e).is_some());
3061 assert!(world.get::<Z>(e).is_some());
3062
3063 {
3064 let mut commands = Commands::new(&mut queue, &world);
3065 commands.entity(e).remove_with_requires::<X>();
3066 }
3067 queue.apply(&mut world);
3068
3069 assert!(world.get::<Y>(e).is_none());
3070 assert!(world.get::<X>(e).is_none());
3071
3072 assert!(world.get::<Z>(e).is_some());
3073 }
3074
3075 #[test]
3076 fn unregister_system_cached_commands() {
3077 let mut world = World::default();
3078 let mut queue = CommandQueue::default();
3079
3080 fn nothing() {}
3081
3082 let resources = world.iter_resources().count();
3083 let id = world.register_system_cached(nothing);
3084 assert_eq!(world.iter_resources().count(), resources + 1);
3085 assert!(world.get_entity(id.entity).is_ok());
3086
3087 let mut commands = Commands::new(&mut queue, &world);
3088 commands.unregister_system_cached(nothing);
3089 queue.apply(&mut world);
3090 assert_eq!(world.iter_resources().count(), resources);
3091 assert!(world.get_entity(id.entity).is_err());
3092 }
3093
3094 fn is_send<T: Send>() {}
3095 fn is_sync<T: Sync>() {}
3096
3097 #[test]
3098 fn test_commands_are_send_and_sync() {
3099 is_send::<Commands>();
3100 is_sync::<Commands>();
3101 }
3102
3103 #[test]
3104 fn append() {
3105 let mut world = World::default();
3106 let mut queue_1 = CommandQueue::default();
3107 {
3108 let mut commands = Commands::new(&mut queue_1, &world);
3109 commands.insert_resource(V(123i32));
3110 }
3111 let mut queue_2 = CommandQueue::default();
3112 {
3113 let mut commands = Commands::new(&mut queue_2, &world);
3114 commands.insert_resource(V(456.0f64));
3115 }
3116 queue_1.append(&mut queue_2);
3117 queue_1.apply(&mut world);
3118 assert!(world.contains_resource::<V<i32>>());
3119 assert!(world.contains_resource::<V<f64>>());
3120 }
3121
3122 #[test]
3123 fn track_spawn_ticks() {
3124 let mut world = World::default();
3125 world.increment_change_tick();
3126 let expected = world.change_tick();
3127 let id = world.commands().spawn_empty().id();
3128 world.flush();
3129 assert_eq!(
3130 Some(expected),
3131 world.entities().entity_get_spawn_or_despawn_tick(id)
3132 );
3133 }
3134}