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