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