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