Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/world/entity_ref.rs
6849 views
1
use crate::{
2
archetype::Archetype,
3
bundle::{
4
Bundle, BundleFromComponents, BundleInserter, BundleRemover, DynamicBundle, InsertMode,
5
},
6
change_detection::{MaybeLocation, MutUntyped},
7
component::{Component, ComponentId, ComponentTicks, Components, Mutable, StorageType, Tick},
8
entity::{
9
ContainsEntity, Entity, EntityCloner, EntityClonerBuilder, EntityEquivalent,
10
EntityIdLocation, EntityLocation, OptIn, OptOut,
11
},
12
event::{EntityComponentsTrigger, EntityEvent},
13
lifecycle::{Despawn, Remove, Replace, DESPAWN, REMOVE, REPLACE},
14
observer::Observer,
15
query::{Access, DebugCheckedUnwrap, ReadOnlyQueryData, ReleaseStateQueryData},
16
relationship::RelationshipHookMode,
17
resource::Resource,
18
storage::{SparseSets, Table},
19
system::IntoObserverSystem,
20
world::{error::EntityComponentError, unsafe_world_cell::UnsafeEntityCell, Mut, Ref, World},
21
};
22
use alloc::vec::Vec;
23
use bevy_platform::collections::{HashMap, HashSet};
24
use bevy_ptr::{move_as_ptr, MovingPtr, OwningPtr, Ptr};
25
use core::{
26
any::TypeId,
27
cmp::Ordering,
28
hash::{Hash, Hasher},
29
marker::PhantomData,
30
mem::MaybeUninit,
31
};
32
use thiserror::Error;
33
34
/// A read-only reference to a particular [`Entity`] and all of its components.
35
///
36
/// # Examples
37
///
38
/// Read-only access disjoint with mutable access.
39
///
40
/// ```
41
/// # use bevy_ecs::prelude::*;
42
/// # #[derive(Component)] pub struct A;
43
/// # #[derive(Component)] pub struct B;
44
/// fn disjoint_system(
45
/// query1: Query<&mut A>,
46
/// query2: Query<EntityRef, Without<A>>,
47
/// ) {
48
/// // ...
49
/// }
50
/// # bevy_ecs::system::assert_is_system(disjoint_system);
51
/// ```
52
#[derive(Copy, Clone)]
53
pub struct EntityRef<'w> {
54
cell: UnsafeEntityCell<'w>,
55
}
56
57
impl<'w> EntityRef<'w> {
58
/// # Safety
59
/// - `cell` must have permission to read every component of the entity.
60
/// - No mutable accesses to any of the entity's components may exist
61
/// at the same time as the returned [`EntityRef`].
62
#[inline]
63
pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {
64
Self { cell }
65
}
66
67
/// Returns the [ID](Entity) of the current entity.
68
#[inline]
69
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
70
pub fn id(&self) -> Entity {
71
self.cell.id()
72
}
73
74
/// Gets metadata indicating the location where the current entity is stored.
75
#[inline]
76
pub fn location(&self) -> EntityLocation {
77
self.cell.location()
78
}
79
80
/// Returns the archetype that the current entity belongs to.
81
#[inline]
82
pub fn archetype(&self) -> &Archetype {
83
self.cell.archetype()
84
}
85
86
/// Returns `true` if the current entity has a component of type `T`.
87
/// Otherwise, this returns `false`.
88
///
89
/// ## Notes
90
///
91
/// If you do not know the concrete type of a component, consider using
92
/// [`Self::contains_id`] or [`Self::contains_type_id`].
93
#[inline]
94
pub fn contains<T: Component>(&self) -> bool {
95
self.contains_type_id(TypeId::of::<T>())
96
}
97
98
/// Returns `true` if the current entity has a component identified by `component_id`.
99
/// Otherwise, this returns false.
100
///
101
/// ## Notes
102
///
103
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
104
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
105
/// [`Self::contains_type_id`].
106
#[inline]
107
pub fn contains_id(&self, component_id: ComponentId) -> bool {
108
self.cell.contains_id(component_id)
109
}
110
111
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
112
/// Otherwise, this returns false.
113
///
114
/// ## Notes
115
///
116
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
117
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
118
#[inline]
119
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
120
self.cell.contains_type_id(type_id)
121
}
122
123
/// Gets access to the component of type `T` for the current entity.
124
/// Returns `None` if the entity does not have a component of type `T`.
125
#[inline]
126
pub fn get<T: Component>(&self) -> Option<&'w T> {
127
// SAFETY: We have read-only access to all components of this entity.
128
unsafe { self.cell.get::<T>() }
129
}
130
131
/// Gets access to the component of type `T` for the current entity,
132
/// including change detection information as a [`Ref`].
133
///
134
/// Returns `None` if the entity does not have a component of type `T`.
135
#[inline]
136
pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {
137
// SAFETY: We have read-only access to all components of this entity.
138
unsafe { self.cell.get_ref::<T>() }
139
}
140
141
/// Retrieves the change ticks for the given component. This can be useful for implementing change
142
/// detection in custom runtimes.
143
#[inline]
144
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
145
// SAFETY: We have read-only access to all components of this entity.
146
unsafe { self.cell.get_change_ticks::<T>() }
147
}
148
149
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
150
/// detection in custom runtimes.
151
///
152
/// **You should prefer to use the typed API [`EntityRef::get_change_ticks`] where possible and only
153
/// use this in cases where the actual component types are not known at
154
/// compile time.**
155
#[inline]
156
pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
157
// SAFETY: We have read-only access to all components of this entity.
158
unsafe { self.cell.get_change_ticks_by_id(component_id) }
159
}
160
161
/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the
162
/// current entity, based on the given [`ComponentId`]s.
163
///
164
/// **You should prefer to use the typed API [`EntityRef::get`] where
165
/// possible and only use this in cases where the actual component types
166
/// are not known at compile time.**
167
///
168
/// Unlike [`EntityRef::get`], this returns untyped reference(s) to
169
/// component(s), and it's the job of the caller to ensure the correct
170
/// type(s) are dereferenced (if necessary).
171
///
172
/// # Errors
173
///
174
/// Returns [`EntityComponentError::MissingComponent`] if the entity does
175
/// not have a component.
176
///
177
/// # Examples
178
///
179
/// ## Single [`ComponentId`]
180
///
181
/// ```
182
/// # use bevy_ecs::prelude::*;
183
/// #
184
/// # #[derive(Component, PartialEq, Debug)]
185
/// # pub struct Foo(i32);
186
/// # let mut world = World::new();
187
/// let entity = world.spawn(Foo(42)).id();
188
///
189
/// // Grab the component ID for `Foo` in whatever way you like.
190
/// let component_id = world.register_component::<Foo>();
191
///
192
/// // Then, get the component by ID.
193
/// let ptr = world.entity(entity).get_by_id(component_id);
194
/// # assert_eq!(unsafe { ptr.unwrap().deref::<Foo>() }, &Foo(42));
195
/// ```
196
///
197
/// ## Array of [`ComponentId`]s
198
///
199
/// ```
200
/// # use bevy_ecs::prelude::*;
201
/// #
202
/// # #[derive(Component, PartialEq, Debug)]
203
/// # pub struct X(i32);
204
/// # #[derive(Component, PartialEq, Debug)]
205
/// # pub struct Y(i32);
206
/// # let mut world = World::new();
207
/// let entity = world.spawn((X(42), Y(10))).id();
208
///
209
/// // Grab the component IDs for `X` and `Y` in whatever way you like.
210
/// let x_id = world.register_component::<X>();
211
/// let y_id = world.register_component::<Y>();
212
///
213
/// // Then, get the components by ID. You'll receive a same-sized array.
214
/// let Ok([x_ptr, y_ptr]) = world.entity(entity).get_by_id([x_id, y_id]) else {
215
/// // Up to you to handle if a component is missing from the entity.
216
/// # unreachable!();
217
/// };
218
/// # assert_eq!((unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() }), (&X(42), &Y(10)));
219
/// ```
220
///
221
/// ## Slice of [`ComponentId`]s
222
///
223
/// ```
224
/// # use bevy_ecs::{prelude::*, component::ComponentId};
225
/// #
226
/// # #[derive(Component, PartialEq, Debug)]
227
/// # pub struct X(i32);
228
/// # #[derive(Component, PartialEq, Debug)]
229
/// # pub struct Y(i32);
230
/// # let mut world = World::new();
231
/// let entity = world.spawn((X(42), Y(10))).id();
232
///
233
/// // Grab the component IDs for `X` and `Y` in whatever way you like.
234
/// let x_id = world.register_component::<X>();
235
/// let y_id = world.register_component::<Y>();
236
///
237
/// // Then, get the components by ID. You'll receive a vec of ptrs.
238
/// let ptrs = world.entity(entity).get_by_id(&[x_id, y_id] as &[ComponentId]);
239
/// # let ptrs = ptrs.unwrap();
240
/// # assert_eq!((unsafe { ptrs[0].deref::<X>() }, unsafe { ptrs[1].deref::<Y>() }), (&X(42), &Y(10)));
241
/// ```
242
///
243
/// ## [`HashSet`] of [`ComponentId`]s
244
///
245
/// ```
246
/// # use bevy_platform::collections::HashSet;
247
/// # use bevy_ecs::{prelude::*, component::ComponentId};
248
/// #
249
/// # #[derive(Component, PartialEq, Debug)]
250
/// # pub struct X(i32);
251
/// # #[derive(Component, PartialEq, Debug)]
252
/// # pub struct Y(i32);
253
/// # let mut world = World::new();
254
/// let entity = world.spawn((X(42), Y(10))).id();
255
///
256
/// // Grab the component IDs for `X` and `Y` in whatever way you like.
257
/// let x_id = world.register_component::<X>();
258
/// let y_id = world.register_component::<Y>();
259
///
260
/// // Then, get the components by ID. You'll receive a vec of ptrs.
261
/// let ptrs = world.entity(entity).get_by_id(&HashSet::from_iter([x_id, y_id]));
262
/// # let ptrs = ptrs.unwrap();
263
/// # assert_eq!((unsafe { ptrs[&x_id].deref::<X>() }, unsafe { ptrs[&y_id].deref::<Y>() }), (&X(42), &Y(10)));
264
/// ```
265
#[inline]
266
pub fn get_by_id<F: DynamicComponentFetch>(
267
&self,
268
component_ids: F,
269
) -> Result<F::Ref<'w>, EntityComponentError> {
270
// SAFETY: We have read-only access to all components of this entity.
271
unsafe { component_ids.fetch_ref(self.cell) }
272
}
273
274
/// Returns read-only components for the current entity that match the query `Q`.
275
///
276
/// # Panics
277
///
278
/// If the entity does not have the components required by the query `Q`.
279
pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'w, 'static> {
280
self.get_components::<Q>()
281
.expect("Query does not match the current entity")
282
}
283
284
/// Returns read-only components for the current entity that match the query `Q`,
285
/// or `None` if the entity does not have the components required by the query `Q`.
286
pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
287
&self,
288
) -> Option<Q::Item<'w, 'static>> {
289
// SAFETY:
290
// - We have read-only access to all components of this entity.
291
// - The query is read-only, and read-only references cannot have conflicts.
292
unsafe { self.cell.get_components::<Q>() }
293
}
294
295
/// Returns the source code location from which this entity has been spawned.
296
pub fn spawned_by(&self) -> MaybeLocation {
297
self.cell.spawned_by()
298
}
299
300
/// Returns the [`Tick`] at which this entity has been spawned.
301
pub fn spawn_tick(&self) -> Tick {
302
self.cell.spawn_tick()
303
}
304
}
305
306
impl<'w> From<EntityWorldMut<'w>> for EntityRef<'w> {
307
fn from(entity: EntityWorldMut<'w>) -> EntityRef<'w> {
308
// SAFETY:
309
// - `EntityWorldMut` guarantees exclusive access to the entire world.
310
unsafe { EntityRef::new(entity.into_unsafe_entity_cell()) }
311
}
312
}
313
314
impl<'a> From<&'a EntityWorldMut<'_>> for EntityRef<'a> {
315
fn from(entity: &'a EntityWorldMut<'_>) -> Self {
316
// SAFETY:
317
// - `EntityWorldMut` guarantees exclusive access to the entire world.
318
// - `&entity` ensures no mutable accesses are active.
319
unsafe { EntityRef::new(entity.as_unsafe_entity_cell_readonly()) }
320
}
321
}
322
323
impl<'w> From<EntityMut<'w>> for EntityRef<'w> {
324
fn from(entity: EntityMut<'w>) -> Self {
325
// SAFETY:
326
// - `EntityMut` guarantees exclusive access to all of the entity's components.
327
unsafe { EntityRef::new(entity.cell) }
328
}
329
}
330
331
impl<'a> From<&'a EntityMut<'_>> for EntityRef<'a> {
332
fn from(entity: &'a EntityMut<'_>) -> Self {
333
// SAFETY:
334
// - `EntityMut` guarantees exclusive access to all of the entity's components.
335
// - `&entity` ensures there are no mutable accesses.
336
unsafe { EntityRef::new(entity.cell) }
337
}
338
}
339
340
impl<'a> TryFrom<FilteredEntityRef<'a, '_>> for EntityRef<'a> {
341
type Error = TryFromFilteredError;
342
343
fn try_from(entity: FilteredEntityRef<'a, '_>) -> Result<Self, Self::Error> {
344
if !entity.access.has_read_all() {
345
Err(TryFromFilteredError::MissingReadAllAccess)
346
} else {
347
// SAFETY: check above guarantees read-only access to all components of the entity.
348
Ok(unsafe { EntityRef::new(entity.entity) })
349
}
350
}
351
}
352
353
impl<'a> TryFrom<&'a FilteredEntityRef<'_, '_>> for EntityRef<'a> {
354
type Error = TryFromFilteredError;
355
356
fn try_from(entity: &'a FilteredEntityRef<'_, '_>) -> Result<Self, Self::Error> {
357
if !entity.access.has_read_all() {
358
Err(TryFromFilteredError::MissingReadAllAccess)
359
} else {
360
// SAFETY: check above guarantees read-only access to all components of the entity.
361
Ok(unsafe { EntityRef::new(entity.entity) })
362
}
363
}
364
}
365
366
impl<'a> TryFrom<FilteredEntityMut<'a, '_>> for EntityRef<'a> {
367
type Error = TryFromFilteredError;
368
369
fn try_from(entity: FilteredEntityMut<'a, '_>) -> Result<Self, Self::Error> {
370
if !entity.access.has_read_all() {
371
Err(TryFromFilteredError::MissingReadAllAccess)
372
} else {
373
// SAFETY: check above guarantees read-only access to all components of the entity.
374
Ok(unsafe { EntityRef::new(entity.entity) })
375
}
376
}
377
}
378
379
impl<'a> TryFrom<&'a FilteredEntityMut<'_, '_>> for EntityRef<'a> {
380
type Error = TryFromFilteredError;
381
382
fn try_from(entity: &'a FilteredEntityMut<'_, '_>) -> Result<Self, Self::Error> {
383
if !entity.access.has_read_all() {
384
Err(TryFromFilteredError::MissingReadAllAccess)
385
} else {
386
// SAFETY: check above guarantees read-only access to all components of the entity.
387
Ok(unsafe { EntityRef::new(entity.entity) })
388
}
389
}
390
}
391
392
impl PartialEq for EntityRef<'_> {
393
fn eq(&self, other: &Self) -> bool {
394
self.entity() == other.entity()
395
}
396
}
397
398
impl Eq for EntityRef<'_> {}
399
400
impl PartialOrd for EntityRef<'_> {
401
/// [`EntityRef`]'s comparison trait implementations match the underlying [`Entity`],
402
/// and cannot discern between different worlds.
403
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
404
Some(self.cmp(other))
405
}
406
}
407
408
impl Ord for EntityRef<'_> {
409
fn cmp(&self, other: &Self) -> Ordering {
410
self.entity().cmp(&other.entity())
411
}
412
}
413
414
impl Hash for EntityRef<'_> {
415
fn hash<H: Hasher>(&self, state: &mut H) {
416
self.entity().hash(state);
417
}
418
}
419
420
impl ContainsEntity for EntityRef<'_> {
421
fn entity(&self) -> Entity {
422
self.id()
423
}
424
}
425
426
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
427
unsafe impl EntityEquivalent for EntityRef<'_> {}
428
429
/// Provides mutable access to a single entity and all of its components.
430
///
431
/// Contrast with [`EntityWorldMut`], which allows adding and removing components,
432
/// despawning the entity, and provides mutable access to the entire world.
433
/// Because of this, `EntityWorldMut` cannot coexist with any other world accesses.
434
///
435
/// # Examples
436
///
437
/// Disjoint mutable access.
438
///
439
/// ```
440
/// # use bevy_ecs::prelude::*;
441
/// # #[derive(Component)] pub struct A;
442
/// fn disjoint_system(
443
/// query1: Query<EntityMut, With<A>>,
444
/// query2: Query<EntityMut, Without<A>>,
445
/// ) {
446
/// // ...
447
/// }
448
/// # bevy_ecs::system::assert_is_system(disjoint_system);
449
/// ```
450
pub struct EntityMut<'w> {
451
cell: UnsafeEntityCell<'w>,
452
}
453
454
impl<'w> EntityMut<'w> {
455
/// # Safety
456
/// - `cell` must have permission to mutate every component of the entity.
457
/// - No accesses to any of the entity's components may exist
458
/// at the same time as the returned [`EntityMut`].
459
#[inline]
460
pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {
461
Self { cell }
462
}
463
464
/// Returns a new instance with a shorter lifetime.
465
/// This is useful if you have `&mut EntityMut`, but you need `EntityMut`.
466
pub fn reborrow(&mut self) -> EntityMut<'_> {
467
// SAFETY: We have exclusive access to the entire entity and its components.
468
unsafe { Self::new(self.cell) }
469
}
470
471
/// Consumes `self` and returns read-only access to all of the entity's
472
/// components, with the world `'w` lifetime.
473
pub fn into_readonly(self) -> EntityRef<'w> {
474
EntityRef::from(self)
475
}
476
477
/// Gets read-only access to all of the entity's components.
478
pub fn as_readonly(&self) -> EntityRef<'_> {
479
EntityRef::from(self)
480
}
481
482
/// Returns the [ID](Entity) of the current entity.
483
#[inline]
484
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
485
pub fn id(&self) -> Entity {
486
self.cell.id()
487
}
488
489
/// Gets metadata indicating the location where the current entity is stored.
490
#[inline]
491
pub fn location(&self) -> EntityLocation {
492
self.cell.location()
493
}
494
495
/// Returns the archetype that the current entity belongs to.
496
#[inline]
497
pub fn archetype(&self) -> &Archetype {
498
self.cell.archetype()
499
}
500
501
/// Returns `true` if the current entity has a component of type `T`.
502
/// Otherwise, this returns `false`.
503
///
504
/// ## Notes
505
///
506
/// If you do not know the concrete type of a component, consider using
507
/// [`Self::contains_id`] or [`Self::contains_type_id`].
508
#[inline]
509
pub fn contains<T: Component>(&self) -> bool {
510
self.contains_type_id(TypeId::of::<T>())
511
}
512
513
/// Returns `true` if the current entity has a component identified by `component_id`.
514
/// Otherwise, this returns false.
515
///
516
/// ## Notes
517
///
518
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
519
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
520
/// [`Self::contains_type_id`].
521
#[inline]
522
pub fn contains_id(&self, component_id: ComponentId) -> bool {
523
self.cell.contains_id(component_id)
524
}
525
526
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
527
/// Otherwise, this returns false.
528
///
529
/// ## Notes
530
///
531
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
532
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
533
#[inline]
534
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
535
self.cell.contains_type_id(type_id)
536
}
537
538
/// Gets access to the component of type `T` for the current entity.
539
/// Returns `None` if the entity does not have a component of type `T`.
540
#[inline]
541
pub fn get<T: Component>(&self) -> Option<&'_ T> {
542
self.as_readonly().get()
543
}
544
545
/// Returns read-only components for the current entity that match the query `Q`.
546
///
547
/// # Panics
548
///
549
/// If the entity does not have the components required by the query `Q`.
550
pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {
551
self.as_readonly().components::<Q>()
552
}
553
554
/// Returns read-only components for the current entity that match the query `Q`,
555
/// or `None` if the entity does not have the components required by the query `Q`.
556
pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
557
&self,
558
) -> Option<Q::Item<'_, 'static>> {
559
self.as_readonly().get_components::<Q>()
560
}
561
562
/// Returns components for the current entity that match the query `Q`,
563
/// or `None` if the entity does not have the components required by the query `Q`.
564
///
565
/// # Example
566
///
567
/// ```
568
/// # use bevy_ecs::prelude::*;
569
/// #
570
/// #[derive(Component)]
571
/// struct X(usize);
572
/// #[derive(Component)]
573
/// struct Y(usize);
574
///
575
/// # let mut world = World::default();
576
/// let mut entity = world.spawn((X(0), Y(0))).into_mutable();
577
/// // Get mutable access to two components at once
578
/// // SAFETY: X and Y are different components
579
/// let (mut x, mut y) =
580
/// unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();
581
/// *x = X(1);
582
/// *y = Y(1);
583
/// // This would trigger undefined behavior, as the `&mut X`s would alias:
584
/// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();
585
/// ```
586
///
587
/// # Safety
588
/// It is the caller's responsibility to ensure that
589
/// the `QueryData` does not provide aliasing mutable references to the same component.
590
pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(
591
&mut self,
592
) -> Option<Q::Item<'_, 'static>> {
593
// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component
594
unsafe { self.reborrow().into_components_mut_unchecked::<Q>() }
595
}
596
597
/// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,
598
/// or `None` if the entity does not have the components required by the query `Q`.
599
///
600
/// # Example
601
///
602
/// ```
603
/// # use bevy_ecs::prelude::*;
604
/// #
605
/// #[derive(Component)]
606
/// struct X(usize);
607
/// #[derive(Component)]
608
/// struct Y(usize);
609
///
610
/// # let mut world = World::default();
611
/// let mut entity = world.spawn((X(0), Y(0))).into_mutable();
612
/// // Get mutable access to two components at once
613
/// // SAFETY: X and Y are different components
614
/// let (mut x, mut y) =
615
/// unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();
616
/// *x = X(1);
617
/// *y = Y(1);
618
/// // This would trigger undefined behavior, as the `&mut X`s would alias:
619
/// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();
620
/// ```
621
///
622
/// # Safety
623
/// It is the caller's responsibility to ensure that
624
/// the `QueryData` does not provide aliasing mutable references to the same component.
625
pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(
626
self,
627
) -> Option<Q::Item<'w, 'static>> {
628
// SAFETY:
629
// - We have mutable access to all components of this entity.
630
// - Caller asserts the `QueryData` does not provide aliasing mutable references to the same component
631
unsafe { self.cell.get_components::<Q>() }
632
}
633
634
/// Consumes `self` and gets access to the component of type `T` with the
635
/// world `'w` lifetime for the current entity.
636
///
637
/// Returns `None` if the entity does not have a component of type `T`.
638
#[inline]
639
pub fn into_borrow<T: Component>(self) -> Option<&'w T> {
640
self.into_readonly().get()
641
}
642
643
/// Gets access to the component of type `T` for the current entity,
644
/// including change detection information as a [`Ref`].
645
///
646
/// Returns `None` if the entity does not have a component of type `T`.
647
#[inline]
648
pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
649
self.as_readonly().get_ref()
650
}
651
652
/// Consumes `self` and gets access to the component of type `T` with world
653
/// `'w` lifetime for the current entity, including change detection information
654
/// as a [`Ref<'w>`].
655
///
656
/// Returns `None` if the entity does not have a component of type `T`.
657
#[inline]
658
pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {
659
self.into_readonly().get_ref()
660
}
661
662
/// Gets mutable access to the component of type `T` for the current entity.
663
/// Returns `None` if the entity does not have a component of type `T`.
664
#[inline]
665
pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {
666
// SAFETY: &mut self implies exclusive access for duration of returned value
667
unsafe { self.cell.get_mut() }
668
}
669
670
/// Gets mutable access to the component of type `T` for the current entity.
671
/// Returns `None` if the entity does not have a component of type `T`.
672
///
673
/// # Safety
674
///
675
/// - `T` must be a mutable component
676
#[inline]
677
pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {
678
// SAFETY:
679
// - &mut self implies exclusive access for duration of returned value
680
// - Caller ensures `T` is a mutable component
681
unsafe { self.cell.get_mut_assume_mutable() }
682
}
683
684
/// Consumes self and gets mutable access to the component of type `T`
685
/// with the world `'w` lifetime for the current entity.
686
/// Returns `None` if the entity does not have a component of type `T`.
687
#[inline]
688
pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {
689
// SAFETY: consuming `self` implies exclusive access
690
unsafe { self.cell.get_mut() }
691
}
692
693
/// Gets mutable access to the component of type `T` for the current entity.
694
/// Returns `None` if the entity does not have a component of type `T`.
695
///
696
/// # Safety
697
///
698
/// - `T` must be a mutable component
699
#[inline]
700
pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {
701
// SAFETY:
702
// - Consuming `self` implies exclusive access
703
// - Caller ensures `T` is a mutable component
704
unsafe { self.cell.get_mut_assume_mutable() }
705
}
706
707
/// Retrieves the change ticks for the given component. This can be useful for implementing change
708
/// detection in custom runtimes.
709
#[inline]
710
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
711
self.as_readonly().get_change_ticks::<T>()
712
}
713
714
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
715
/// detection in custom runtimes.
716
///
717
/// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only
718
/// use this in cases where the actual component types are not known at
719
/// compile time.**
720
#[inline]
721
pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
722
self.as_readonly().get_change_ticks_by_id(component_id)
723
}
724
725
/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the
726
/// current entity, based on the given [`ComponentId`]s.
727
///
728
/// **You should prefer to use the typed API [`EntityMut::get`] where
729
/// possible and only use this in cases where the actual component types
730
/// are not known at compile time.**
731
///
732
/// Unlike [`EntityMut::get`], this returns untyped reference(s) to
733
/// component(s), and it's the job of the caller to ensure the correct
734
/// type(s) are dereferenced (if necessary).
735
///
736
/// # Errors
737
///
738
/// Returns [`EntityComponentError::MissingComponent`] if the entity does
739
/// not have a component.
740
///
741
/// # Examples
742
///
743
/// For examples on how to use this method, see [`EntityRef::get_by_id`].
744
#[inline]
745
pub fn get_by_id<F: DynamicComponentFetch>(
746
&self,
747
component_ids: F,
748
) -> Result<F::Ref<'_>, EntityComponentError> {
749
self.as_readonly().get_by_id(component_ids)
750
}
751
752
/// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to
753
/// component(s) with lifetime `'w` for the current entity, based on the
754
/// given [`ComponentId`]s.
755
///
756
/// **You should prefer to use the typed API [`EntityMut::into_borrow`]
757
/// where possible and only use this in cases where the actual component
758
/// types are not known at compile time.**
759
///
760
/// Unlike [`EntityMut::into_borrow`], this returns untyped reference(s) to
761
/// component(s), and it's the job of the caller to ensure the correct
762
/// type(s) are dereferenced (if necessary).
763
///
764
/// # Errors
765
///
766
/// Returns [`EntityComponentError::MissingComponent`] if the entity does
767
/// not have a component.
768
///
769
/// # Examples
770
///
771
/// For examples on how to use this method, see [`EntityRef::get_by_id`].
772
#[inline]
773
pub fn into_borrow_by_id<F: DynamicComponentFetch>(
774
self,
775
component_ids: F,
776
) -> Result<F::Ref<'w>, EntityComponentError> {
777
self.into_readonly().get_by_id(component_ids)
778
}
779
780
/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
781
/// the current entity, based on the given [`ComponentId`]s.
782
///
783
/// **You should prefer to use the typed API [`EntityMut::get_mut`] where
784
/// possible and only use this in cases where the actual component types
785
/// are not known at compile time.**
786
///
787
/// Unlike [`EntityMut::get_mut`], this returns untyped reference(s) to
788
/// component(s), and it's the job of the caller to ensure the correct
789
/// type(s) are dereferenced (if necessary).
790
///
791
/// # Errors
792
///
793
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
794
/// not have a component.
795
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
796
/// is requested multiple times.
797
///
798
/// # Examples
799
///
800
/// ## Single [`ComponentId`]
801
///
802
/// ```
803
/// # use bevy_ecs::prelude::*;
804
/// #
805
/// # #[derive(Component, PartialEq, Debug)]
806
/// # pub struct Foo(i32);
807
/// # let mut world = World::new();
808
/// let entity = world.spawn(Foo(42)).id();
809
///
810
/// // Grab the component ID for `Foo` in whatever way you like.
811
/// let component_id = world.register_component::<Foo>();
812
///
813
/// // Then, get the component by ID.
814
/// let mut entity_mut = world.entity_mut(entity);
815
/// let mut ptr = entity_mut.get_mut_by_id(component_id)
816
/// # .unwrap();
817
/// # assert_eq!(unsafe { ptr.as_mut().deref_mut::<Foo>() }, &mut Foo(42));
818
/// ```
819
///
820
/// ## Array of [`ComponentId`]s
821
///
822
/// ```
823
/// # use bevy_ecs::prelude::*;
824
/// #
825
/// # #[derive(Component, PartialEq, Debug)]
826
/// # pub struct X(i32);
827
/// # #[derive(Component, PartialEq, Debug)]
828
/// # pub struct Y(i32);
829
/// # let mut world = World::new();
830
/// let entity = world.spawn((X(42), Y(10))).id();
831
///
832
/// // Grab the component IDs for `X` and `Y` in whatever way you like.
833
/// let x_id = world.register_component::<X>();
834
/// let y_id = world.register_component::<Y>();
835
///
836
/// // Then, get the components by ID. You'll receive a same-sized array.
837
/// let mut entity_mut = world.entity_mut(entity);
838
/// let Ok([mut x_ptr, mut y_ptr]) = entity_mut.get_mut_by_id([x_id, y_id]) else {
839
/// // Up to you to handle if a component is missing from the entity.
840
/// # unreachable!();
841
/// };
842
/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));
843
/// ```
844
///
845
/// ## Slice of [`ComponentId`]s
846
///
847
/// ```
848
/// # use bevy_ecs::{prelude::*, component::ComponentId, change_detection::MutUntyped};
849
/// #
850
/// # #[derive(Component, PartialEq, Debug)]
851
/// # pub struct X(i32);
852
/// # #[derive(Component, PartialEq, Debug)]
853
/// # pub struct Y(i32);
854
/// # let mut world = World::new();
855
/// let entity = world.spawn((X(42), Y(10))).id();
856
///
857
/// // Grab the component IDs for `X` and `Y` in whatever way you like.
858
/// let x_id = world.register_component::<X>();
859
/// let y_id = world.register_component::<Y>();
860
///
861
/// // Then, get the components by ID. You'll receive a vec of ptrs.
862
/// let mut entity_mut = world.entity_mut(entity);
863
/// let ptrs = entity_mut.get_mut_by_id(&[x_id, y_id] as &[ComponentId])
864
/// # .unwrap();
865
/// # let [mut x_ptr, mut y_ptr]: [MutUntyped; 2] = ptrs.try_into().unwrap();
866
/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));
867
/// ```
868
///
869
/// ## [`HashSet`] of [`ComponentId`]s
870
///
871
/// ```
872
/// # use bevy_platform::collections::HashSet;
873
/// # use bevy_ecs::{prelude::*, component::ComponentId};
874
/// #
875
/// # #[derive(Component, PartialEq, Debug)]
876
/// # pub struct X(i32);
877
/// # #[derive(Component, PartialEq, Debug)]
878
/// # pub struct Y(i32);
879
/// # let mut world = World::new();
880
/// let entity = world.spawn((X(42), Y(10))).id();
881
///
882
/// // Grab the component IDs for `X` and `Y` in whatever way you like.
883
/// let x_id = world.register_component::<X>();
884
/// let y_id = world.register_component::<Y>();
885
///
886
/// // Then, get the components by ID. You'll receive a `HashMap` of ptrs.
887
/// let mut entity_mut = world.entity_mut(entity);
888
/// let mut ptrs = entity_mut.get_mut_by_id(&HashSet::from_iter([x_id, y_id]))
889
/// # .unwrap();
890
/// # let [Some(mut x_ptr), Some(mut y_ptr)] = ptrs.get_many_mut([&x_id, &y_id]) else { unreachable!() };
891
/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));
892
/// ```
893
#[inline]
894
pub fn get_mut_by_id<F: DynamicComponentFetch>(
895
&mut self,
896
component_ids: F,
897
) -> Result<F::Mut<'_>, EntityComponentError> {
898
// SAFETY:
899
// - `&mut self` ensures that no references exist to this entity's components.
900
// - We have exclusive access to all components of this entity.
901
unsafe { component_ids.fetch_mut(self.cell) }
902
}
903
904
/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
905
/// the current entity, based on the given [`ComponentId`]s.
906
/// Assumes the given [`ComponentId`]s refer to mutable components.
907
///
908
/// **You should prefer to use the typed API [`EntityMut::get_mut_assume_mutable`] where
909
/// possible and only use this in cases where the actual component types
910
/// are not known at compile time.**
911
///
912
/// Unlike [`EntityMut::get_mut_assume_mutable`], this returns untyped reference(s) to
913
/// component(s), and it's the job of the caller to ensure the correct
914
/// type(s) are dereferenced (if necessary).
915
///
916
/// # Errors
917
///
918
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
919
/// not have a component.
920
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
921
/// is requested multiple times.
922
///
923
/// # Safety
924
/// It is the callers responsibility to ensure that
925
/// - the provided [`ComponentId`]s must refer to mutable components.
926
#[inline]
927
pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(
928
&mut self,
929
component_ids: F,
930
) -> Result<F::Mut<'_>, EntityComponentError> {
931
// SAFETY:
932
// - `&mut self` ensures that no references exist to this entity's components.
933
// - We have exclusive access to all components of this entity.
934
unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }
935
}
936
937
/// Returns [untyped mutable reference](MutUntyped) to component for
938
/// the current entity, based on the given [`ComponentId`].
939
///
940
/// Unlike [`EntityMut::get_mut_by_id`], this method borrows &self instead of
941
/// &mut self, allowing the caller to access multiple components simultaneously.
942
///
943
/// # Errors
944
///
945
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
946
/// not have a component.
947
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
948
/// is requested multiple times.
949
///
950
/// # Safety
951
/// It is the callers responsibility to ensure that
952
/// - the [`UnsafeEntityCell`] has permission to access the component mutably
953
/// - no other references to the component exist at the same time
954
#[inline]
955
pub unsafe fn get_mut_by_id_unchecked<F: DynamicComponentFetch>(
956
&self,
957
component_ids: F,
958
) -> Result<F::Mut<'_>, EntityComponentError> {
959
// SAFETY:
960
// - The caller must ensure simultaneous access is limited
961
// - to components that are mutually independent.
962
unsafe { component_ids.fetch_mut(self.cell) }
963
}
964
965
/// Returns [untyped mutable reference](MutUntyped) to component for
966
/// the current entity, based on the given [`ComponentId`].
967
/// Assumes the given [`ComponentId`]s refer to mutable components.
968
///
969
/// Unlike [`EntityMut::get_mut_assume_mutable_by_id`], this method borrows &self instead of
970
/// &mut self, allowing the caller to access multiple components simultaneously.
971
///
972
/// # Errors
973
///
974
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
975
/// not have a component.
976
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
977
/// is requested multiple times.
978
///
979
/// # Safety
980
/// It is the callers responsibility to ensure that
981
/// - the [`UnsafeEntityCell`] has permission to access the component mutably
982
/// - no other references to the component exist at the same time
983
/// - the provided [`ComponentId`]s must refer to mutable components.
984
#[inline]
985
pub unsafe fn get_mut_assume_mutable_by_id_unchecked<F: DynamicComponentFetch>(
986
&self,
987
component_ids: F,
988
) -> Result<F::Mut<'_>, EntityComponentError> {
989
// SAFETY:
990
// - The caller must ensure simultaneous access is limited
991
// - to components that are mutually independent.
992
unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }
993
}
994
995
/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
996
/// to component(s) with lifetime `'w` for the current entity, based on the
997
/// given [`ComponentId`]s.
998
///
999
/// **You should prefer to use the typed API [`EntityMut::into_mut`] where
1000
/// possible and only use this in cases where the actual component types
1001
/// are not known at compile time.**
1002
///
1003
/// Unlike [`EntityMut::into_mut`], this returns untyped reference(s) to
1004
/// component(s), and it's the job of the caller to ensure the correct
1005
/// type(s) are dereferenced (if necessary).
1006
///
1007
/// # Errors
1008
///
1009
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1010
/// not have a component.
1011
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
1012
/// is requested multiple times.
1013
///
1014
/// # Examples
1015
///
1016
/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
1017
#[inline]
1018
pub fn into_mut_by_id<F: DynamicComponentFetch>(
1019
self,
1020
component_ids: F,
1021
) -> Result<F::Mut<'w>, EntityComponentError> {
1022
// SAFETY:
1023
// - consuming `self` ensures that no references exist to this entity's components.
1024
// - We have exclusive access to all components of this entity.
1025
unsafe { component_ids.fetch_mut(self.cell) }
1026
}
1027
1028
/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
1029
/// to component(s) with lifetime `'w` for the current entity, based on the
1030
/// given [`ComponentId`]s.
1031
/// Assumes the given [`ComponentId`]s refer to mutable components.
1032
///
1033
/// **You should prefer to use the typed API [`EntityMut::into_mut_assume_mutable`] where
1034
/// possible and only use this in cases where the actual component types
1035
/// are not known at compile time.**
1036
///
1037
/// Unlike [`EntityMut::into_mut_assume_mutable`], this returns untyped reference(s) to
1038
/// component(s), and it's the job of the caller to ensure the correct
1039
/// type(s) are dereferenced (if necessary).
1040
///
1041
/// # Errors
1042
///
1043
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1044
/// not have a component.
1045
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
1046
/// is requested multiple times.
1047
///
1048
/// # Safety
1049
/// It is the callers responsibility to ensure that
1050
/// - the provided [`ComponentId`]s must refer to mutable components.
1051
#[inline]
1052
pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(
1053
self,
1054
component_ids: F,
1055
) -> Result<F::Mut<'w>, EntityComponentError> {
1056
// SAFETY:
1057
// - consuming `self` ensures that no references exist to this entity's components.
1058
// - We have exclusive access to all components of this entity.
1059
unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }
1060
}
1061
1062
/// Returns the source code location from which this entity has been spawned.
1063
pub fn spawned_by(&self) -> MaybeLocation {
1064
self.cell.spawned_by()
1065
}
1066
1067
/// Returns the [`Tick`] at which this entity has been spawned.
1068
pub fn spawn_tick(&self) -> Tick {
1069
self.cell.spawn_tick()
1070
}
1071
}
1072
1073
impl<'w> From<&'w mut EntityMut<'_>> for EntityMut<'w> {
1074
fn from(entity: &'w mut EntityMut<'_>) -> Self {
1075
entity.reborrow()
1076
}
1077
}
1078
1079
impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {
1080
fn from(entity: EntityWorldMut<'w>) -> Self {
1081
// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
1082
unsafe { EntityMut::new(entity.into_unsafe_entity_cell()) }
1083
}
1084
}
1085
1086
impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {
1087
#[inline]
1088
fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {
1089
// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
1090
unsafe { EntityMut::new(entity.as_unsafe_entity_cell()) }
1091
}
1092
}
1093
1094
impl<'a> TryFrom<FilteredEntityMut<'a, '_>> for EntityMut<'a> {
1095
type Error = TryFromFilteredError;
1096
1097
fn try_from(entity: FilteredEntityMut<'a, '_>) -> Result<Self, Self::Error> {
1098
if !entity.access.has_read_all() {
1099
Err(TryFromFilteredError::MissingReadAllAccess)
1100
} else if !entity.access.has_write_all() {
1101
Err(TryFromFilteredError::MissingWriteAllAccess)
1102
} else {
1103
// SAFETY: check above guarantees exclusive access to all components of the entity.
1104
Ok(unsafe { EntityMut::new(entity.entity) })
1105
}
1106
}
1107
}
1108
1109
impl<'a> TryFrom<&'a mut FilteredEntityMut<'_, '_>> for EntityMut<'a> {
1110
type Error = TryFromFilteredError;
1111
1112
fn try_from(entity: &'a mut FilteredEntityMut<'_, '_>) -> Result<Self, Self::Error> {
1113
if !entity.access.has_read_all() {
1114
Err(TryFromFilteredError::MissingReadAllAccess)
1115
} else if !entity.access.has_write_all() {
1116
Err(TryFromFilteredError::MissingWriteAllAccess)
1117
} else {
1118
// SAFETY: check above guarantees exclusive access to all components of the entity.
1119
Ok(unsafe { EntityMut::new(entity.entity) })
1120
}
1121
}
1122
}
1123
1124
impl PartialEq for EntityMut<'_> {
1125
fn eq(&self, other: &Self) -> bool {
1126
self.entity() == other.entity()
1127
}
1128
}
1129
1130
impl Eq for EntityMut<'_> {}
1131
1132
impl PartialOrd for EntityMut<'_> {
1133
/// [`EntityMut`]'s comparison trait implementations match the underlying [`Entity`],
1134
/// and cannot discern between different worlds.
1135
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1136
Some(self.cmp(other))
1137
}
1138
}
1139
1140
impl Ord for EntityMut<'_> {
1141
fn cmp(&self, other: &Self) -> Ordering {
1142
self.entity().cmp(&other.entity())
1143
}
1144
}
1145
1146
impl Hash for EntityMut<'_> {
1147
fn hash<H: Hasher>(&self, state: &mut H) {
1148
self.entity().hash(state);
1149
}
1150
}
1151
1152
impl ContainsEntity for EntityMut<'_> {
1153
fn entity(&self) -> Entity {
1154
self.id()
1155
}
1156
}
1157
1158
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
1159
unsafe impl EntityEquivalent for EntityMut<'_> {}
1160
1161
/// A mutable reference to a particular [`Entity`], and the entire world.
1162
///
1163
/// This is essentially a performance-optimized `(Entity, &mut World)` tuple,
1164
/// which caches the [`EntityLocation`] to reduce duplicate lookups.
1165
///
1166
/// Since this type provides mutable access to the entire world, only one
1167
/// [`EntityWorldMut`] can exist at a time for a given world.
1168
///
1169
/// See also [`EntityMut`], which allows disjoint mutable access to multiple
1170
/// entities at once. Unlike `EntityMut`, this type allows adding and
1171
/// removing components, and despawning the entity.
1172
pub struct EntityWorldMut<'w> {
1173
world: &'w mut World,
1174
entity: Entity,
1175
location: EntityIdLocation,
1176
}
1177
1178
impl<'w> EntityWorldMut<'w> {
1179
#[track_caller]
1180
#[inline(never)]
1181
#[cold]
1182
fn panic_despawned(&self) -> ! {
1183
panic!(
1184
"Entity {} {}",
1185
self.entity,
1186
self.world
1187
.entities()
1188
.entity_does_not_exist_error_details(self.entity)
1189
);
1190
}
1191
1192
#[inline(always)]
1193
#[track_caller]
1194
pub(crate) fn assert_not_despawned(&self) {
1195
if self.location.is_none() {
1196
self.panic_despawned()
1197
}
1198
}
1199
1200
#[inline(always)]
1201
fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {
1202
let location = self.location();
1203
let last_change_tick = self.world.last_change_tick;
1204
let change_tick = self.world.read_change_tick();
1205
UnsafeEntityCell::new(
1206
self.world.as_unsafe_world_cell_readonly(),
1207
self.entity,
1208
location,
1209
last_change_tick,
1210
change_tick,
1211
)
1212
}
1213
1214
#[inline(always)]
1215
fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {
1216
let location = self.location();
1217
let last_change_tick = self.world.last_change_tick;
1218
let change_tick = self.world.change_tick();
1219
UnsafeEntityCell::new(
1220
self.world.as_unsafe_world_cell(),
1221
self.entity,
1222
location,
1223
last_change_tick,
1224
change_tick,
1225
)
1226
}
1227
1228
#[inline(always)]
1229
fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {
1230
let location = self.location();
1231
let last_change_tick = self.world.last_change_tick;
1232
let change_tick = self.world.change_tick();
1233
UnsafeEntityCell::new(
1234
self.world.as_unsafe_world_cell(),
1235
self.entity,
1236
location,
1237
last_change_tick,
1238
change_tick,
1239
)
1240
}
1241
1242
/// # Safety
1243
///
1244
/// - `entity` must be valid for `world`: the generation should match that of the entity at the same index.
1245
/// - `location` must be sourced from `world`'s `Entities` and must exactly match the location for `entity`
1246
///
1247
/// The above is trivially satisfied if `location` was sourced from `world.entities().get(entity)`.
1248
#[inline]
1249
pub(crate) unsafe fn new(
1250
world: &'w mut World,
1251
entity: Entity,
1252
location: Option<EntityLocation>,
1253
) -> Self {
1254
debug_assert!(world.entities().contains(entity));
1255
debug_assert_eq!(world.entities().get(entity), location);
1256
1257
EntityWorldMut {
1258
world,
1259
entity,
1260
location,
1261
}
1262
}
1263
1264
/// Consumes `self` and returns read-only access to all of the entity's
1265
/// components, with the world `'w` lifetime.
1266
pub fn into_readonly(self) -> EntityRef<'w> {
1267
EntityRef::from(self)
1268
}
1269
1270
/// Gets read-only access to all of the entity's components.
1271
#[inline]
1272
pub fn as_readonly(&self) -> EntityRef<'_> {
1273
EntityRef::from(self)
1274
}
1275
1276
/// Consumes `self` and returns non-structural mutable access to all of the
1277
/// entity's components, with the world `'w` lifetime.
1278
pub fn into_mutable(self) -> EntityMut<'w> {
1279
EntityMut::from(self)
1280
}
1281
1282
/// Gets non-structural mutable access to all of the entity's components.
1283
#[inline]
1284
pub fn as_mutable(&mut self) -> EntityMut<'_> {
1285
EntityMut::from(self)
1286
}
1287
1288
/// Returns the [ID](Entity) of the current entity.
1289
#[inline]
1290
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
1291
pub fn id(&self) -> Entity {
1292
self.entity
1293
}
1294
1295
/// Gets metadata indicating the location where the current entity is stored.
1296
///
1297
/// # Panics
1298
///
1299
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1300
#[inline]
1301
pub fn location(&self) -> EntityLocation {
1302
match self.location {
1303
Some(loc) => loc,
1304
None => self.panic_despawned(),
1305
}
1306
}
1307
1308
/// Returns the archetype that the current entity belongs to.
1309
///
1310
/// # Panics
1311
///
1312
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1313
#[inline]
1314
pub fn archetype(&self) -> &Archetype {
1315
let location = self.location();
1316
&self.world.archetypes[location.archetype_id]
1317
}
1318
1319
/// Returns `true` if the current entity has a component of type `T`.
1320
/// Otherwise, this returns `false`.
1321
///
1322
/// ## Notes
1323
///
1324
/// If you do not know the concrete type of a component, consider using
1325
/// [`Self::contains_id`] or [`Self::contains_type_id`].
1326
///
1327
/// # Panics
1328
///
1329
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1330
#[inline]
1331
pub fn contains<T: Component>(&self) -> bool {
1332
self.contains_type_id(TypeId::of::<T>())
1333
}
1334
1335
/// Returns `true` if the current entity has a component identified by `component_id`.
1336
/// Otherwise, this returns false.
1337
///
1338
/// ## Notes
1339
///
1340
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
1341
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
1342
/// [`Self::contains_type_id`].
1343
///
1344
/// # Panics
1345
///
1346
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1347
#[inline]
1348
pub fn contains_id(&self, component_id: ComponentId) -> bool {
1349
self.as_unsafe_entity_cell_readonly()
1350
.contains_id(component_id)
1351
}
1352
1353
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
1354
/// Otherwise, this returns false.
1355
///
1356
/// ## Notes
1357
///
1358
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
1359
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
1360
///
1361
/// # Panics
1362
///
1363
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1364
#[inline]
1365
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
1366
self.as_unsafe_entity_cell_readonly()
1367
.contains_type_id(type_id)
1368
}
1369
1370
/// Gets access to the component of type `T` for the current entity.
1371
/// Returns `None` if the entity does not have a component of type `T`.
1372
///
1373
/// # Panics
1374
///
1375
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1376
#[inline]
1377
pub fn get<T: Component>(&self) -> Option<&'_ T> {
1378
self.as_readonly().get()
1379
}
1380
1381
/// Returns read-only components for the current entity that match the query `Q`.
1382
///
1383
/// # Panics
1384
///
1385
/// If the entity does not have the components required by the query `Q` or if the entity
1386
/// has been despawned while this `EntityWorldMut` is still alive.
1387
#[inline]
1388
pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {
1389
self.as_readonly().components::<Q>()
1390
}
1391
1392
/// Returns read-only components for the current entity that match the query `Q`,
1393
/// or `None` if the entity does not have the components required by the query `Q`.
1394
///
1395
/// # Panics
1396
///
1397
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1398
#[inline]
1399
pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
1400
&self,
1401
) -> Option<Q::Item<'_, 'static>> {
1402
self.as_readonly().get_components::<Q>()
1403
}
1404
1405
/// Returns components for the current entity that match the query `Q`,
1406
/// or `None` if the entity does not have the components required by the query `Q`.
1407
///
1408
/// # Example
1409
///
1410
/// ```
1411
/// # use bevy_ecs::prelude::*;
1412
/// #
1413
/// #[derive(Component)]
1414
/// struct X(usize);
1415
/// #[derive(Component)]
1416
/// struct Y(usize);
1417
///
1418
/// # let mut world = World::default();
1419
/// let mut entity = world.spawn((X(0), Y(0)));
1420
/// // Get mutable access to two components at once
1421
/// // SAFETY: X and Y are different components
1422
/// let (mut x, mut y) =
1423
/// unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();
1424
/// *x = X(1);
1425
/// *y = Y(1);
1426
/// // This would trigger undefined behavior, as the `&mut X`s would alias:
1427
/// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();
1428
/// ```
1429
///
1430
/// # Safety
1431
/// It is the caller's responsibility to ensure that
1432
/// the `QueryData` does not provide aliasing mutable references to the same component.
1433
pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(
1434
&mut self,
1435
) -> Option<Q::Item<'_, 'static>> {
1436
// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component
1437
unsafe { self.as_mutable().into_components_mut_unchecked::<Q>() }
1438
}
1439
1440
/// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,
1441
/// or `None` if the entity does not have the components required by the query `Q`.
1442
///
1443
/// # Example
1444
///
1445
/// ```
1446
/// # use bevy_ecs::prelude::*;
1447
/// #
1448
/// #[derive(Component)]
1449
/// struct X(usize);
1450
/// #[derive(Component)]
1451
/// struct Y(usize);
1452
///
1453
/// # let mut world = World::default();
1454
/// let mut entity = world.spawn((X(0), Y(0)));
1455
/// // Get mutable access to two components at once
1456
/// // SAFETY: X and Y are different components
1457
/// let (mut x, mut y) =
1458
/// unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();
1459
/// *x = X(1);
1460
/// *y = Y(1);
1461
/// // This would trigger undefined behavior, as the `&mut X`s would alias:
1462
/// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();
1463
/// ```
1464
///
1465
/// # Safety
1466
/// It is the caller's responsibility to ensure that
1467
/// the `QueryData` does not provide aliasing mutable references to the same component.
1468
pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(
1469
self,
1470
) -> Option<Q::Item<'w, 'static>> {
1471
// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component
1472
unsafe { self.into_mutable().into_components_mut_unchecked::<Q>() }
1473
}
1474
1475
/// Consumes `self` and gets access to the component of type `T` with
1476
/// the world `'w` lifetime for the current entity.
1477
/// Returns `None` if the entity does not have a component of type `T`.
1478
///
1479
/// # Panics
1480
///
1481
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1482
#[inline]
1483
pub fn into_borrow<T: Component>(self) -> Option<&'w T> {
1484
self.into_readonly().get()
1485
}
1486
1487
/// Gets access to the component of type `T` for the current entity,
1488
/// including change detection information as a [`Ref`].
1489
///
1490
/// Returns `None` if the entity does not have a component of type `T`.
1491
///
1492
/// # Panics
1493
///
1494
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1495
#[inline]
1496
pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
1497
self.as_readonly().get_ref()
1498
}
1499
1500
/// Consumes `self` and gets access to the component of type `T`
1501
/// with the world `'w` lifetime for the current entity,
1502
/// including change detection information as a [`Ref`].
1503
///
1504
/// Returns `None` if the entity does not have a component of type `T`.
1505
///
1506
/// # Panics
1507
///
1508
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1509
#[inline]
1510
pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {
1511
self.into_readonly().get_ref()
1512
}
1513
1514
/// Gets mutable access to the component of type `T` for the current entity.
1515
/// Returns `None` if the entity does not have a component of type `T`.
1516
///
1517
/// # Panics
1518
///
1519
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1520
#[inline]
1521
pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {
1522
self.as_mutable().into_mut()
1523
}
1524
1525
/// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the
1526
/// provided closure on it, returning the result if `T` was available.
1527
/// This will trigger the `Remove` and `Replace` component hooks without
1528
/// causing an archetype move.
1529
///
1530
/// This is most useful with immutable components, where removal and reinsertion
1531
/// is the only way to modify a value.
1532
///
1533
/// If you do not need to ensure the above hooks are triggered, and your component
1534
/// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).
1535
///
1536
/// # Examples
1537
///
1538
/// ```rust
1539
/// # use bevy_ecs::prelude::*;
1540
/// #
1541
/// #[derive(Component, PartialEq, Eq, Debug)]
1542
/// #[component(immutable)]
1543
/// struct Foo(bool);
1544
///
1545
/// # let mut world = World::default();
1546
/// # world.register_component::<Foo>();
1547
/// #
1548
/// # let entity = world.spawn(Foo(false)).id();
1549
/// #
1550
/// # let mut entity = world.entity_mut(entity);
1551
/// #
1552
/// # assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));
1553
/// #
1554
/// entity.modify_component(|foo: &mut Foo| {
1555
/// foo.0 = true;
1556
/// });
1557
/// #
1558
/// # assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));
1559
/// ```
1560
///
1561
/// # Panics
1562
///
1563
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1564
#[inline]
1565
pub fn modify_component<T: Component, R>(&mut self, f: impl FnOnce(&mut T) -> R) -> Option<R> {
1566
self.assert_not_despawned();
1567
1568
let result = self
1569
.world
1570
.modify_component(self.entity, f)
1571
.expect("entity access must be valid")?;
1572
1573
self.update_location();
1574
1575
Some(result)
1576
}
1577
1578
/// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the
1579
/// provided closure on it, returning the result if `T` was available.
1580
/// This will trigger the `Remove` and `Replace` component hooks without
1581
/// causing an archetype move.
1582
///
1583
/// This is most useful with immutable components, where removal and reinsertion
1584
/// is the only way to modify a value.
1585
///
1586
/// If you do not need to ensure the above hooks are triggered, and your component
1587
/// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).
1588
///
1589
/// # Panics
1590
///
1591
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1592
#[inline]
1593
pub fn modify_component_by_id<R>(
1594
&mut self,
1595
component_id: ComponentId,
1596
f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,
1597
) -> Option<R> {
1598
self.assert_not_despawned();
1599
1600
let result = self
1601
.world
1602
.modify_component_by_id(self.entity, component_id, f)
1603
.expect("entity access must be valid")?;
1604
1605
self.update_location();
1606
1607
Some(result)
1608
}
1609
1610
/// Gets mutable access to the component of type `T` for the current entity.
1611
/// Returns `None` if the entity does not have a component of type `T`.
1612
///
1613
/// # Safety
1614
///
1615
/// - `T` must be a mutable component
1616
#[inline]
1617
pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {
1618
self.as_mutable().into_mut_assume_mutable()
1619
}
1620
1621
/// Consumes `self` and gets mutable access to the component of type `T`
1622
/// with the world `'w` lifetime for the current entity.
1623
/// Returns `None` if the entity does not have a component of type `T`.
1624
///
1625
/// # Panics
1626
///
1627
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1628
#[inline]
1629
pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {
1630
// SAFETY: consuming `self` implies exclusive access
1631
unsafe { self.into_unsafe_entity_cell().get_mut() }
1632
}
1633
1634
/// Consumes `self` and gets mutable access to the component of type `T`
1635
/// with the world `'w` lifetime for the current entity.
1636
/// Returns `None` if the entity does not have a component of type `T`.
1637
///
1638
/// # Panics
1639
///
1640
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1641
///
1642
/// # Safety
1643
///
1644
/// - `T` must be a mutable component
1645
#[inline]
1646
pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {
1647
// SAFETY: consuming `self` implies exclusive access
1648
unsafe { self.into_unsafe_entity_cell().get_mut_assume_mutable() }
1649
}
1650
1651
/// Gets a reference to the resource of the given type
1652
///
1653
/// # Panics
1654
///
1655
/// Panics if the resource does not exist.
1656
/// Use [`get_resource`](EntityWorldMut::get_resource) instead if you want to handle this case.
1657
#[inline]
1658
#[track_caller]
1659
pub fn resource<R: Resource>(&self) -> &R {
1660
self.world.resource::<R>()
1661
}
1662
1663
/// Gets a mutable reference to the resource of the given type
1664
///
1665
/// # Panics
1666
///
1667
/// Panics if the resource does not exist.
1668
/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.
1669
///
1670
/// If you want to instead insert a value if the resource does not exist,
1671
/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
1672
#[inline]
1673
#[track_caller]
1674
pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {
1675
self.world.resource_mut::<R>()
1676
}
1677
1678
/// Gets a reference to the resource of the given type if it exists
1679
#[inline]
1680
pub fn get_resource<R: Resource>(&self) -> Option<&R> {
1681
self.world.get_resource()
1682
}
1683
1684
/// Gets a mutable reference to the resource of the given type if it exists
1685
#[inline]
1686
pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {
1687
self.world.get_resource_mut()
1688
}
1689
1690
/// Temporarily removes the requested resource from the [`World`], runs custom user code,
1691
/// then re-adds the resource before returning.
1692
///
1693
/// # Panics
1694
///
1695
/// Panics if the resource does not exist.
1696
/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.
1697
///
1698
/// See [`World::resource_scope`] for further details.
1699
#[track_caller]
1700
pub fn resource_scope<R: Resource, U>(
1701
&mut self,
1702
f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,
1703
) -> U {
1704
let id = self.id();
1705
self.world_scope(|world| {
1706
world.resource_scope(|world, res| {
1707
// Acquiring a new EntityWorldMut here and using that instead of `self` is fine because
1708
// the outer `world_scope` will handle updating our location if it gets changed by the user code
1709
let mut this = world.entity_mut(id);
1710
f(&mut this, res)
1711
})
1712
})
1713
}
1714
1715
/// Temporarily removes the requested resource from the [`World`] if it exists, runs custom user code,
1716
/// then re-adds the resource before returning. Returns `None` if the resource does not exist in the [`World`].
1717
///
1718
/// See [`World::try_resource_scope`] for further details.
1719
pub fn try_resource_scope<R: Resource, U>(
1720
&mut self,
1721
f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,
1722
) -> Option<U> {
1723
let id = self.id();
1724
self.world_scope(|world| {
1725
world.try_resource_scope(|world, res| {
1726
// Acquiring a new EntityWorldMut here and using that instead of `self` is fine because
1727
// the outer `world_scope` will handle updating our location if it gets changed by the user code
1728
let mut this = world.entity_mut(id);
1729
f(&mut this, res)
1730
})
1731
})
1732
}
1733
1734
/// Retrieves the change ticks for the given component. This can be useful for implementing change
1735
/// detection in custom runtimes.
1736
///
1737
/// # Panics
1738
///
1739
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1740
#[inline]
1741
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
1742
self.as_readonly().get_change_ticks::<T>()
1743
}
1744
1745
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
1746
/// detection in custom runtimes.
1747
///
1748
/// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only
1749
/// use this in cases where the actual component types are not known at
1750
/// compile time.**
1751
///
1752
/// # Panics
1753
///
1754
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1755
#[inline]
1756
pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
1757
self.as_readonly().get_change_ticks_by_id(component_id)
1758
}
1759
1760
/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the
1761
/// current entity, based on the given [`ComponentId`]s.
1762
///
1763
/// **You should prefer to use the typed API [`EntityWorldMut::get`] where
1764
/// possible and only use this in cases where the actual component types
1765
/// are not known at compile time.**
1766
///
1767
/// Unlike [`EntityWorldMut::get`], this returns untyped reference(s) to
1768
/// component(s), and it's the job of the caller to ensure the correct
1769
/// type(s) are dereferenced (if necessary).
1770
///
1771
/// # Errors
1772
///
1773
/// Returns [`EntityComponentError::MissingComponent`] if the entity does
1774
/// not have a component.
1775
///
1776
/// # Examples
1777
///
1778
/// For examples on how to use this method, see [`EntityRef::get_by_id`].
1779
///
1780
/// # Panics
1781
///
1782
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1783
#[inline]
1784
pub fn get_by_id<F: DynamicComponentFetch>(
1785
&self,
1786
component_ids: F,
1787
) -> Result<F::Ref<'_>, EntityComponentError> {
1788
self.as_readonly().get_by_id(component_ids)
1789
}
1790
1791
/// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to
1792
/// component(s) with lifetime `'w` for the current entity, based on the
1793
/// given [`ComponentId`]s.
1794
///
1795
/// **You should prefer to use the typed API [`EntityWorldMut::into_borrow`]
1796
/// where possible and only use this in cases where the actual component
1797
/// types are not known at compile time.**
1798
///
1799
/// Unlike [`EntityWorldMut::into_borrow`], this returns untyped reference(s) to
1800
/// component(s), and it's the job of the caller to ensure the correct
1801
/// type(s) are dereferenced (if necessary).
1802
///
1803
/// # Errors
1804
///
1805
/// Returns [`EntityComponentError::MissingComponent`] if the entity does
1806
/// not have a component.
1807
///
1808
/// # Examples
1809
///
1810
/// For examples on how to use this method, see [`EntityRef::get_by_id`].
1811
///
1812
/// # Panics
1813
///
1814
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1815
#[inline]
1816
pub fn into_borrow_by_id<F: DynamicComponentFetch>(
1817
self,
1818
component_ids: F,
1819
) -> Result<F::Ref<'w>, EntityComponentError> {
1820
self.into_readonly().get_by_id(component_ids)
1821
}
1822
1823
/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
1824
/// the current entity, based on the given [`ComponentId`]s.
1825
///
1826
/// **You should prefer to use the typed API [`EntityWorldMut::get_mut`] where
1827
/// possible and only use this in cases where the actual component types
1828
/// are not known at compile time.**
1829
///
1830
/// Unlike [`EntityWorldMut::get_mut`], this returns untyped reference(s) to
1831
/// component(s), and it's the job of the caller to ensure the correct
1832
/// type(s) are dereferenced (if necessary).
1833
///
1834
/// # Errors
1835
///
1836
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1837
/// not have a component.
1838
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
1839
/// is requested multiple times.
1840
///
1841
/// # Examples
1842
///
1843
/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
1844
///
1845
/// # Panics
1846
///
1847
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1848
#[inline]
1849
pub fn get_mut_by_id<F: DynamicComponentFetch>(
1850
&mut self,
1851
component_ids: F,
1852
) -> Result<F::Mut<'_>, EntityComponentError> {
1853
self.as_mutable().into_mut_by_id(component_ids)
1854
}
1855
1856
/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
1857
/// the current entity, based on the given [`ComponentId`]s.
1858
/// Assumes the given [`ComponentId`]s refer to mutable components.
1859
///
1860
/// **You should prefer to use the typed API [`EntityWorldMut::get_mut_assume_mutable`] where
1861
/// possible and only use this in cases where the actual component types
1862
/// are not known at compile time.**
1863
///
1864
/// Unlike [`EntityWorldMut::get_mut_assume_mutable`], this returns untyped reference(s) to
1865
/// component(s), and it's the job of the caller to ensure the correct
1866
/// type(s) are dereferenced (if necessary).
1867
///
1868
/// # Errors
1869
///
1870
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1871
/// not have a component.
1872
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
1873
/// is requested multiple times.
1874
///
1875
/// # Panics
1876
///
1877
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1878
///
1879
/// # Safety
1880
/// It is the callers responsibility to ensure that
1881
/// - the provided [`ComponentId`]s must refer to mutable components.
1882
#[inline]
1883
pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(
1884
&mut self,
1885
component_ids: F,
1886
) -> Result<F::Mut<'_>, EntityComponentError> {
1887
self.as_mutable()
1888
.into_mut_assume_mutable_by_id(component_ids)
1889
}
1890
1891
/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
1892
/// to component(s) with lifetime `'w` for the current entity, based on the
1893
/// given [`ComponentId`]s.
1894
///
1895
/// **You should prefer to use the typed API [`EntityWorldMut::into_mut`] where
1896
/// possible and only use this in cases where the actual component types
1897
/// are not known at compile time.**
1898
///
1899
/// Unlike [`EntityWorldMut::into_mut`], this returns untyped reference(s) to
1900
/// component(s), and it's the job of the caller to ensure the correct
1901
/// type(s) are dereferenced (if necessary).
1902
///
1903
/// # Errors
1904
///
1905
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1906
/// not have a component.
1907
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
1908
/// is requested multiple times.
1909
///
1910
/// # Examples
1911
///
1912
/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
1913
///
1914
/// # Panics
1915
///
1916
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1917
#[inline]
1918
pub fn into_mut_by_id<F: DynamicComponentFetch>(
1919
self,
1920
component_ids: F,
1921
) -> Result<F::Mut<'w>, EntityComponentError> {
1922
self.into_mutable().into_mut_by_id(component_ids)
1923
}
1924
1925
/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
1926
/// to component(s) with lifetime `'w` for the current entity, based on the
1927
/// given [`ComponentId`]s.
1928
/// Assumes the given [`ComponentId`]s refer to mutable components.
1929
///
1930
/// **You should prefer to use the typed API [`EntityWorldMut::into_mut_assume_mutable`] where
1931
/// possible and only use this in cases where the actual component types
1932
/// are not known at compile time.**
1933
///
1934
/// Unlike [`EntityWorldMut::into_mut_assume_mutable`], this returns untyped reference(s) to
1935
/// component(s), and it's the job of the caller to ensure the correct
1936
/// type(s) are dereferenced (if necessary).
1937
///
1938
/// # Errors
1939
///
1940
/// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1941
/// not have a component.
1942
/// - Returns [`EntityComponentError::AliasedMutability`] if a component
1943
/// is requested multiple times.
1944
///
1945
/// # Panics
1946
///
1947
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1948
///
1949
/// # Safety
1950
/// It is the callers responsibility to ensure that
1951
/// - the provided [`ComponentId`]s must refer to mutable components.
1952
#[inline]
1953
pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(
1954
self,
1955
component_ids: F,
1956
) -> Result<F::Mut<'w>, EntityComponentError> {
1957
self.into_mutable()
1958
.into_mut_assume_mutable_by_id(component_ids)
1959
}
1960
1961
/// Adds a [`Bundle`] of components to the entity.
1962
///
1963
/// This will overwrite any previous value(s) of the same component type.
1964
///
1965
/// # Panics
1966
///
1967
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1968
#[track_caller]
1969
pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {
1970
move_as_ptr!(bundle);
1971
self.insert_with_caller(
1972
bundle,
1973
InsertMode::Replace,
1974
MaybeLocation::caller(),
1975
RelationshipHookMode::Run,
1976
)
1977
}
1978
1979
/// Adds a [`Bundle`] of components to the entity.
1980
/// [`Relationship`](crate::relationship::Relationship) components in the bundle will follow the configuration
1981
/// in `relationship_hook_mode`.
1982
///
1983
/// This will overwrite any previous value(s) of the same component type.
1984
///
1985
/// # Warning
1986
///
1987
/// This can easily break the integrity of relationships. This is intended to be used for cloning and spawning code internals,
1988
/// not most user-facing scenarios.
1989
///
1990
/// # Panics
1991
///
1992
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
1993
#[track_caller]
1994
pub fn insert_with_relationship_hook_mode<T: Bundle>(
1995
&mut self,
1996
bundle: T,
1997
relationship_hook_mode: RelationshipHookMode,
1998
) -> &mut Self {
1999
move_as_ptr!(bundle);
2000
self.insert_with_caller(
2001
bundle,
2002
InsertMode::Replace,
2003
MaybeLocation::caller(),
2004
relationship_hook_mode,
2005
)
2006
}
2007
2008
/// Adds a [`Bundle`] of components to the entity without overwriting.
2009
///
2010
/// This will leave any previous value(s) of the same component type
2011
/// unchanged.
2012
///
2013
/// # Panics
2014
///
2015
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2016
#[track_caller]
2017
pub fn insert_if_new<T: Bundle>(&mut self, bundle: T) -> &mut Self {
2018
move_as_ptr!(bundle);
2019
self.insert_with_caller(
2020
bundle,
2021
InsertMode::Keep,
2022
MaybeLocation::caller(),
2023
RelationshipHookMode::Run,
2024
)
2025
}
2026
2027
/// Adds a [`Bundle`] of components to the entity.
2028
#[inline]
2029
pub(crate) fn insert_with_caller<T: Bundle>(
2030
&mut self,
2031
bundle: MovingPtr<'_, T>,
2032
mode: InsertMode,
2033
caller: MaybeLocation,
2034
relationship_hook_mode: RelationshipHookMode,
2035
) -> &mut Self {
2036
let location = self.location();
2037
let change_tick = self.world.change_tick();
2038
let mut bundle_inserter =
2039
BundleInserter::new::<T>(self.world, location.archetype_id, change_tick);
2040
// SAFETY:
2041
// - `location` matches current entity and thus must currently exist in the source
2042
// archetype for this inserter and its location within the archetype.
2043
// - `T` matches the type used to create the `BundleInserter`.
2044
// - `apply_effect` is called exactly once after this function.
2045
// - The value pointed at by `bundle` is not accessed for anything other than `apply_effect`
2046
// and the caller ensures that the value is not accessed or dropped after this function
2047
// returns.
2048
let (bundle, location) = bundle.partial_move(|bundle| unsafe {
2049
bundle_inserter.insert(
2050
self.entity,
2051
location,
2052
bundle,
2053
mode,
2054
caller,
2055
relationship_hook_mode,
2056
)
2057
});
2058
self.location = Some(location);
2059
self.world.flush();
2060
self.update_location();
2061
// SAFETY:
2062
// - This is called exactly once after the `BundleInsert::insert` call before returning to safe code.
2063
// - `bundle` points to the same `B` that `BundleInsert::insert` was called on.
2064
unsafe { T::apply_effect(bundle, self) };
2065
self
2066
}
2067
2068
/// Inserts a dynamic [`Component`] into the entity.
2069
///
2070
/// This will overwrite any previous value(s) of the same component type.
2071
///
2072
/// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.
2073
///
2074
/// # Safety
2075
///
2076
/// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]
2077
/// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
2078
///
2079
/// # Panics
2080
///
2081
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2082
#[track_caller]
2083
pub unsafe fn insert_by_id(
2084
&mut self,
2085
component_id: ComponentId,
2086
component: OwningPtr<'_>,
2087
) -> &mut Self {
2088
self.insert_by_id_with_caller(
2089
component_id,
2090
component,
2091
InsertMode::Replace,
2092
MaybeLocation::caller(),
2093
RelationshipHookMode::Run,
2094
)
2095
}
2096
2097
/// # Safety
2098
///
2099
/// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]
2100
/// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
2101
#[inline]
2102
pub(crate) unsafe fn insert_by_id_with_caller(
2103
&mut self,
2104
component_id: ComponentId,
2105
component: OwningPtr<'_>,
2106
mode: InsertMode,
2107
caller: MaybeLocation,
2108
relationship_hook_insert_mode: RelationshipHookMode,
2109
) -> &mut Self {
2110
let location = self.location();
2111
let change_tick = self.world.change_tick();
2112
let bundle_id = self.world.bundles.init_component_info(
2113
&mut self.world.storages,
2114
&self.world.components,
2115
component_id,
2116
);
2117
let storage_type = self.world.bundles.get_storage_unchecked(bundle_id);
2118
2119
let bundle_inserter =
2120
BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);
2121
2122
self.location = Some(insert_dynamic_bundle(
2123
bundle_inserter,
2124
self.entity,
2125
location,
2126
Some(component).into_iter(),
2127
Some(storage_type).iter().cloned(),
2128
mode,
2129
caller,
2130
relationship_hook_insert_mode,
2131
));
2132
self.world.flush();
2133
self.update_location();
2134
self
2135
}
2136
2137
/// Inserts a dynamic [`Bundle`] into the entity.
2138
///
2139
/// This will overwrite any previous value(s) of the same component type.
2140
///
2141
/// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.
2142
/// If your [`Bundle`] only has one component, use the cached API [`EntityWorldMut::insert_by_id`].
2143
///
2144
/// If possible, pass a sorted slice of `ComponentId` to maximize caching potential.
2145
///
2146
/// # Safety
2147
/// - Each [`ComponentId`] must be from the same world as [`EntityWorldMut`]
2148
/// - Each [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
2149
///
2150
/// # Panics
2151
///
2152
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2153
#[track_caller]
2154
pub unsafe fn insert_by_ids<'a, I: Iterator<Item = OwningPtr<'a>>>(
2155
&mut self,
2156
component_ids: &[ComponentId],
2157
iter_components: I,
2158
) -> &mut Self {
2159
self.insert_by_ids_internal(component_ids, iter_components, RelationshipHookMode::Run)
2160
}
2161
2162
#[track_caller]
2163
pub(crate) unsafe fn insert_by_ids_internal<'a, I: Iterator<Item = OwningPtr<'a>>>(
2164
&mut self,
2165
component_ids: &[ComponentId],
2166
iter_components: I,
2167
relationship_hook_insert_mode: RelationshipHookMode,
2168
) -> &mut Self {
2169
let location = self.location();
2170
let change_tick = self.world.change_tick();
2171
let bundle_id = self.world.bundles.init_dynamic_info(
2172
&mut self.world.storages,
2173
&self.world.components,
2174
component_ids,
2175
);
2176
let mut storage_types =
2177
core::mem::take(self.world.bundles.get_storages_unchecked(bundle_id));
2178
let bundle_inserter =
2179
BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);
2180
2181
self.location = Some(insert_dynamic_bundle(
2182
bundle_inserter,
2183
self.entity,
2184
location,
2185
iter_components,
2186
(*storage_types).iter().cloned(),
2187
InsertMode::Replace,
2188
MaybeLocation::caller(),
2189
relationship_hook_insert_mode,
2190
));
2191
*self.world.bundles.get_storages_unchecked(bundle_id) = core::mem::take(&mut storage_types);
2192
self.world.flush();
2193
self.update_location();
2194
self
2195
}
2196
2197
/// Removes all components in the [`Bundle`] from the entity and returns their previous values.
2198
///
2199
/// **Note:** If the entity does not have every component in the bundle, this method will not
2200
/// remove any of them.
2201
///
2202
/// # Panics
2203
///
2204
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2205
#[must_use]
2206
#[track_caller]
2207
pub fn take<T: Bundle + BundleFromComponents>(&mut self) -> Option<T> {
2208
let location = self.location();
2209
let entity = self.entity;
2210
2211
let mut remover =
2212
// SAFETY: The archetype id must be valid since this entity is in it.
2213
unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, true) }?;
2214
// SAFETY: The passed location has the sane archetype as the remover, since they came from the same location.
2215
let (new_location, result) = unsafe {
2216
remover.remove(
2217
entity,
2218
location,
2219
MaybeLocation::caller(),
2220
|sets, table, components, bundle_components| {
2221
let mut bundle_components = bundle_components.iter().copied();
2222
(
2223
false,
2224
T::from_components(&mut (sets, table), &mut |(sets, table)| {
2225
let component_id = bundle_components.next().unwrap();
2226
// SAFETY: the component existed to be removed, so its id must be valid.
2227
let component_info = components.get_info_unchecked(component_id);
2228
match component_info.storage_type() {
2229
StorageType::Table => {
2230
table
2231
.as_mut()
2232
// SAFETY: The table must be valid if the component is in it.
2233
.debug_checked_unwrap()
2234
// SAFETY: The remover is cleaning this up.
2235
.take_component(component_id, location.table_row)
2236
}
2237
StorageType::SparseSet => sets
2238
.get_mut(component_id)
2239
.unwrap()
2240
.remove_and_forget(entity)
2241
.unwrap(),
2242
}
2243
}),
2244
)
2245
},
2246
)
2247
};
2248
self.location = Some(new_location);
2249
2250
self.world.flush();
2251
self.update_location();
2252
Some(result)
2253
}
2254
2255
/// Removes any components in the [`Bundle`] from the entity.
2256
///
2257
/// See [`EntityCommands::remove`](crate::system::EntityCommands::remove) for more details.
2258
///
2259
/// # Panics
2260
///
2261
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2262
#[track_caller]
2263
pub fn remove<T: Bundle>(&mut self) -> &mut Self {
2264
self.remove_with_caller::<T>(MaybeLocation::caller())
2265
}
2266
2267
#[inline]
2268
pub(crate) fn remove_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {
2269
let location = self.location();
2270
2271
let Some(mut remover) =
2272
// SAFETY: The archetype id must be valid since this entity is in it.
2273
(unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, false) })
2274
else {
2275
return self;
2276
};
2277
// SAFETY: The remover archetype came from the passed location and the removal can not fail.
2278
let new_location = unsafe {
2279
remover.remove(
2280
self.entity,
2281
location,
2282
caller,
2283
BundleRemover::empty_pre_remove,
2284
)
2285
}
2286
.0;
2287
2288
self.location = Some(new_location);
2289
self.world.flush();
2290
self.update_location();
2291
self
2292
}
2293
2294
/// Removes all components in the [`Bundle`] and remove all required components for each component in the bundle
2295
///
2296
/// # Panics
2297
///
2298
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2299
#[track_caller]
2300
pub fn remove_with_requires<T: Bundle>(&mut self) -> &mut Self {
2301
self.remove_with_requires_with_caller::<T>(MaybeLocation::caller())
2302
}
2303
2304
pub(crate) fn remove_with_requires_with_caller<T: Bundle>(
2305
&mut self,
2306
caller: MaybeLocation,
2307
) -> &mut Self {
2308
let location = self.location();
2309
let bundle_id = self.world.register_contributed_bundle_info::<T>();
2310
2311
// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
2312
let Some(mut remover) = (unsafe {
2313
BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
2314
}) else {
2315
return self;
2316
};
2317
// SAFETY: The remover archetype came from the passed location and the removal can not fail.
2318
let new_location = unsafe {
2319
remover.remove(
2320
self.entity,
2321
location,
2322
caller,
2323
BundleRemover::empty_pre_remove,
2324
)
2325
}
2326
.0;
2327
2328
self.location = Some(new_location);
2329
self.world.flush();
2330
self.update_location();
2331
self
2332
}
2333
2334
/// Removes any components except those in the [`Bundle`] (and its Required Components) from the entity.
2335
///
2336
/// See [`EntityCommands::retain`](crate::system::EntityCommands::retain) for more details.
2337
///
2338
/// # Panics
2339
///
2340
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2341
#[track_caller]
2342
pub fn retain<T: Bundle>(&mut self) -> &mut Self {
2343
self.retain_with_caller::<T>(MaybeLocation::caller())
2344
}
2345
2346
#[inline]
2347
pub(crate) fn retain_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {
2348
let old_location = self.location();
2349
let retained_bundle = self.world.register_bundle_info::<T>();
2350
let archetypes = &mut self.world.archetypes;
2351
2352
// SAFETY: `retained_bundle` exists as we just registered it.
2353
let retained_bundle_info = unsafe { self.world.bundles.get_unchecked(retained_bundle) };
2354
let old_archetype = &mut archetypes[old_location.archetype_id];
2355
2356
// PERF: this could be stored in an Archetype Edge
2357
let to_remove = &old_archetype
2358
.iter_components()
2359
.filter(|c| !retained_bundle_info.contributed_components().contains(c))
2360
.collect::<Vec<_>>();
2361
let remove_bundle = self.world.bundles.init_dynamic_info(
2362
&mut self.world.storages,
2363
&self.world.components,
2364
to_remove,
2365
);
2366
2367
// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
2368
let Some(mut remover) = (unsafe {
2369
BundleRemover::new_with_id(self.world, old_location.archetype_id, remove_bundle, false)
2370
}) else {
2371
return self;
2372
};
2373
// SAFETY: The remover archetype came from the passed location and the removal can not fail.
2374
let new_location = unsafe {
2375
remover.remove(
2376
self.entity,
2377
old_location,
2378
caller,
2379
BundleRemover::empty_pre_remove,
2380
)
2381
}
2382
.0;
2383
2384
self.location = Some(new_location);
2385
self.world.flush();
2386
self.update_location();
2387
self
2388
}
2389
2390
/// Removes a dynamic [`Component`] from the entity if it exists.
2391
///
2392
/// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.
2393
///
2394
/// # Panics
2395
///
2396
/// Panics if the provided [`ComponentId`] does not exist in the [`World`] or if the
2397
/// entity has been despawned while this `EntityWorldMut` is still alive.
2398
#[track_caller]
2399
pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {
2400
self.remove_by_id_with_caller(component_id, MaybeLocation::caller())
2401
}
2402
2403
#[inline]
2404
pub(crate) fn remove_by_id_with_caller(
2405
&mut self,
2406
component_id: ComponentId,
2407
caller: MaybeLocation,
2408
) -> &mut Self {
2409
let location = self.location();
2410
let components = &mut self.world.components;
2411
2412
let bundle_id = self.world.bundles.init_component_info(
2413
&mut self.world.storages,
2414
components,
2415
component_id,
2416
);
2417
2418
// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
2419
let Some(mut remover) = (unsafe {
2420
BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
2421
}) else {
2422
return self;
2423
};
2424
// SAFETY: The remover archetype came from the passed location and the removal can not fail.
2425
let new_location = unsafe {
2426
remover.remove(
2427
self.entity,
2428
location,
2429
caller,
2430
BundleRemover::empty_pre_remove,
2431
)
2432
}
2433
.0;
2434
2435
self.location = Some(new_location);
2436
self.world.flush();
2437
self.update_location();
2438
self
2439
}
2440
2441
/// Removes a dynamic bundle from the entity if it exists.
2442
///
2443
/// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.
2444
///
2445
/// # Panics
2446
///
2447
/// Panics if any of the provided [`ComponentId`]s do not exist in the [`World`] or if the
2448
/// entity has been despawned while this `EntityWorldMut` is still alive.
2449
#[track_caller]
2450
pub fn remove_by_ids(&mut self, component_ids: &[ComponentId]) -> &mut Self {
2451
self.remove_by_ids_with_caller(
2452
component_ids,
2453
MaybeLocation::caller(),
2454
RelationshipHookMode::Run,
2455
BundleRemover::empty_pre_remove,
2456
)
2457
}
2458
2459
#[inline]
2460
pub(crate) fn remove_by_ids_with_caller<T: 'static>(
2461
&mut self,
2462
component_ids: &[ComponentId],
2463
caller: MaybeLocation,
2464
relationship_hook_mode: RelationshipHookMode,
2465
pre_remove: impl FnOnce(
2466
&mut SparseSets,
2467
Option<&mut Table>,
2468
&Components,
2469
&[ComponentId],
2470
) -> (bool, T),
2471
) -> &mut Self {
2472
let location = self.location();
2473
let components = &mut self.world.components;
2474
2475
let bundle_id = self.world.bundles.init_dynamic_info(
2476
&mut self.world.storages,
2477
components,
2478
component_ids,
2479
);
2480
2481
// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
2482
let Some(mut remover) = (unsafe {
2483
BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
2484
}) else {
2485
return self;
2486
};
2487
remover.relationship_hook_mode = relationship_hook_mode;
2488
// SAFETY: The remover archetype came from the passed location and the removal can not fail.
2489
let new_location = unsafe { remover.remove(self.entity, location, caller, pre_remove) }.0;
2490
2491
self.location = Some(new_location);
2492
self.world.flush();
2493
self.update_location();
2494
self
2495
}
2496
2497
/// Removes all components associated with the entity.
2498
///
2499
/// # Panics
2500
///
2501
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2502
#[track_caller]
2503
pub fn clear(&mut self) -> &mut Self {
2504
self.clear_with_caller(MaybeLocation::caller())
2505
}
2506
2507
#[inline]
2508
pub(crate) fn clear_with_caller(&mut self, caller: MaybeLocation) -> &mut Self {
2509
let location = self.location();
2510
// PERF: this should not be necessary
2511
let component_ids: Vec<ComponentId> = self.archetype().components().to_vec();
2512
let components = &mut self.world.components;
2513
2514
let bundle_id = self.world.bundles.init_dynamic_info(
2515
&mut self.world.storages,
2516
components,
2517
component_ids.as_slice(),
2518
);
2519
2520
// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
2521
let Some(mut remover) = (unsafe {
2522
BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
2523
}) else {
2524
return self;
2525
};
2526
// SAFETY: The remover archetype came from the passed location and the removal can not fail.
2527
let new_location = unsafe {
2528
remover.remove(
2529
self.entity,
2530
location,
2531
caller,
2532
BundleRemover::empty_pre_remove,
2533
)
2534
}
2535
.0;
2536
2537
self.location = Some(new_location);
2538
self.world.flush();
2539
self.update_location();
2540
self
2541
}
2542
2543
/// Despawns the current entity.
2544
///
2545
/// See [`World::despawn`] for more details.
2546
///
2547
/// # Note
2548
///
2549
/// This will also despawn any [`Children`](crate::hierarchy::Children) entities, and any other [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
2550
/// to despawn descendants. This results in "recursive despawn" behavior.
2551
///
2552
/// # Panics
2553
///
2554
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2555
#[track_caller]
2556
pub fn despawn(self) {
2557
self.despawn_with_caller(MaybeLocation::caller());
2558
}
2559
2560
pub(crate) fn despawn_with_caller(self, caller: MaybeLocation) {
2561
let location = self.location();
2562
let world = self.world;
2563
let archetype = &world.archetypes[location.archetype_id];
2564
2565
// SAFETY: Archetype cannot be mutably aliased by DeferredWorld
2566
let (archetype, mut deferred_world) = unsafe {
2567
let archetype: *const Archetype = archetype;
2568
let world = world.as_unsafe_world_cell();
2569
(&*archetype, world.into_deferred())
2570
};
2571
2572
// SAFETY: All components in the archetype exist in world
2573
unsafe {
2574
if archetype.has_despawn_observer() {
2575
// SAFETY: the DESPAWN event_key corresponds to the Despawn event's type
2576
deferred_world.trigger_raw(
2577
DESPAWN,
2578
&mut Despawn {
2579
entity: self.entity,
2580
},
2581
&mut EntityComponentsTrigger {
2582
components: archetype.components(),
2583
},
2584
caller,
2585
);
2586
}
2587
deferred_world.trigger_on_despawn(
2588
archetype,
2589
self.entity,
2590
archetype.iter_components(),
2591
caller,
2592
);
2593
if archetype.has_replace_observer() {
2594
// SAFETY: the REPLACE event_key corresponds to the Replace event's type
2595
deferred_world.trigger_raw(
2596
REPLACE,
2597
&mut Replace {
2598
entity: self.entity,
2599
},
2600
&mut EntityComponentsTrigger {
2601
components: archetype.components(),
2602
},
2603
caller,
2604
);
2605
}
2606
deferred_world.trigger_on_replace(
2607
archetype,
2608
self.entity,
2609
archetype.iter_components(),
2610
caller,
2611
RelationshipHookMode::Run,
2612
);
2613
if archetype.has_remove_observer() {
2614
// SAFETY: the REMOVE event_key corresponds to the Remove event's type
2615
deferred_world.trigger_raw(
2616
REMOVE,
2617
&mut Remove {
2618
entity: self.entity,
2619
},
2620
&mut EntityComponentsTrigger {
2621
components: archetype.components(),
2622
},
2623
caller,
2624
);
2625
}
2626
deferred_world.trigger_on_remove(
2627
archetype,
2628
self.entity,
2629
archetype.iter_components(),
2630
caller,
2631
);
2632
}
2633
2634
for component_id in archetype.iter_components() {
2635
world.removed_components.write(component_id, self.entity);
2636
}
2637
2638
// Observers and on_remove hooks may reserve new entities, which
2639
// requires a flush before Entities::free may be called.
2640
world.flush_entities();
2641
2642
let location = world
2643
.entities
2644
.free(self.entity)
2645
.flatten()
2646
.expect("entity should exist at this point.");
2647
let table_row;
2648
let moved_entity;
2649
let change_tick = world.change_tick();
2650
2651
{
2652
let archetype = &mut world.archetypes[location.archetype_id];
2653
let remove_result = archetype.swap_remove(location.archetype_row);
2654
if let Some(swapped_entity) = remove_result.swapped_entity {
2655
let swapped_location = world.entities.get(swapped_entity).unwrap();
2656
// SAFETY: swapped_entity is valid and the swapped entity's components are
2657
// moved to the new location immediately after.
2658
unsafe {
2659
world.entities.set(
2660
swapped_entity.index(),
2661
Some(EntityLocation {
2662
archetype_id: swapped_location.archetype_id,
2663
archetype_row: location.archetype_row,
2664
table_id: swapped_location.table_id,
2665
table_row: swapped_location.table_row,
2666
}),
2667
);
2668
world
2669
.entities
2670
.mark_spawn_despawn(swapped_entity.index(), caller, change_tick);
2671
}
2672
}
2673
table_row = remove_result.table_row;
2674
2675
for component_id in archetype.sparse_set_components() {
2676
// set must have existed for the component to be added.
2677
let sparse_set = world.storages.sparse_sets.get_mut(component_id).unwrap();
2678
sparse_set.remove(self.entity);
2679
}
2680
// SAFETY: table rows stored in archetypes always exist
2681
moved_entity = unsafe {
2682
world.storages.tables[archetype.table_id()].swap_remove_unchecked(table_row)
2683
};
2684
};
2685
2686
if let Some(moved_entity) = moved_entity {
2687
let moved_location = world.entities.get(moved_entity).unwrap();
2688
// SAFETY: `moved_entity` is valid and the provided `EntityLocation` accurately reflects
2689
// the current location of the entity and its component data.
2690
unsafe {
2691
world.entities.set(
2692
moved_entity.index(),
2693
Some(EntityLocation {
2694
archetype_id: moved_location.archetype_id,
2695
archetype_row: moved_location.archetype_row,
2696
table_id: moved_location.table_id,
2697
table_row,
2698
}),
2699
);
2700
world
2701
.entities
2702
.mark_spawn_despawn(moved_entity.index(), caller, change_tick);
2703
}
2704
world.archetypes[moved_location.archetype_id]
2705
.set_entity_table_row(moved_location.archetype_row, table_row);
2706
}
2707
world.flush();
2708
}
2709
2710
/// Ensures any commands triggered by the actions of Self are applied, equivalent to [`World::flush`]
2711
pub fn flush(self) -> Entity {
2712
self.world.flush();
2713
self.entity
2714
}
2715
2716
/// Gets read-only access to the world that the current entity belongs to.
2717
#[inline]
2718
pub fn world(&self) -> &World {
2719
self.world
2720
}
2721
2722
/// Returns this entity's world.
2723
///
2724
/// See [`EntityWorldMut::world_scope`] or [`EntityWorldMut::into_world_mut`] for a safe alternative.
2725
///
2726
/// # Safety
2727
/// Caller must not modify the world in a way that changes the current entity's location
2728
/// If the caller _does_ do something that could change the location, `self.update_location()`
2729
/// must be called before using any other methods on this [`EntityWorldMut`].
2730
#[inline]
2731
pub unsafe fn world_mut(&mut self) -> &mut World {
2732
self.world
2733
}
2734
2735
/// Returns this entity's [`World`], consuming itself.
2736
#[inline]
2737
pub fn into_world_mut(self) -> &'w mut World {
2738
self.world
2739
}
2740
2741
/// Gives mutable access to this entity's [`World`] in a temporary scope.
2742
/// This is a safe alternative to using [`EntityWorldMut::world_mut`].
2743
///
2744
/// # Examples
2745
///
2746
/// ```
2747
/// # use bevy_ecs::prelude::*;
2748
/// #[derive(Resource, Default, Clone, Copy)]
2749
/// struct R(u32);
2750
///
2751
/// # let mut world = World::new();
2752
/// # world.init_resource::<R>();
2753
/// # let mut entity = world.spawn_empty();
2754
/// // This closure gives us temporary access to the world.
2755
/// let new_r = entity.world_scope(|world: &mut World| {
2756
/// // Mutate the world while we have access to it.
2757
/// let mut r = world.resource_mut::<R>();
2758
/// r.0 += 1;
2759
///
2760
/// // Return a value from the world before giving it back to the `EntityWorldMut`.
2761
/// *r
2762
/// });
2763
/// # assert_eq!(new_r.0, 1);
2764
/// ```
2765
pub fn world_scope<U>(&mut self, f: impl FnOnce(&mut World) -> U) -> U {
2766
struct Guard<'w, 'a> {
2767
entity_mut: &'a mut EntityWorldMut<'w>,
2768
}
2769
2770
impl Drop for Guard<'_, '_> {
2771
#[inline]
2772
fn drop(&mut self) {
2773
self.entity_mut.update_location();
2774
}
2775
}
2776
2777
// When `guard` is dropped at the end of this scope,
2778
// it will update the cached `EntityLocation` for this instance.
2779
// This will run even in case the closure `f` unwinds.
2780
let guard = Guard { entity_mut: self };
2781
f(guard.entity_mut.world)
2782
}
2783
2784
/// Updates the internal entity location to match the current location in the internal
2785
/// [`World`].
2786
///
2787
/// This is *only* required when using the unsafe function [`EntityWorldMut::world_mut`],
2788
/// which enables the location to change.
2789
pub fn update_location(&mut self) {
2790
self.location = self.world.entities().get(self.entity);
2791
}
2792
2793
/// Returns if the entity has been despawned.
2794
///
2795
/// Normally it shouldn't be needed to explicitly check if the entity has been despawned
2796
/// between commands as this shouldn't happen. However, for some special cases where it
2797
/// is known that a hook or an observer might despawn the entity while a [`EntityWorldMut`]
2798
/// reference is still held, this method can be used to check if the entity is still alive
2799
/// to avoid panicking when calling further methods.
2800
#[inline]
2801
pub fn is_despawned(&self) -> bool {
2802
self.location.is_none()
2803
}
2804
2805
/// Gets an Entry into the world for this entity and component for in-place manipulation.
2806
///
2807
/// The type parameter specifies which component to get.
2808
///
2809
/// # Examples
2810
///
2811
/// ```
2812
/// # use bevy_ecs::prelude::*;
2813
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2814
/// struct Comp(u32);
2815
///
2816
/// # let mut world = World::new();
2817
/// let mut entity = world.spawn_empty();
2818
/// entity.entry().or_insert_with(|| Comp(4));
2819
/// # let entity_id = entity.id();
2820
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);
2821
///
2822
/// # let mut entity = world.get_entity_mut(entity_id).unwrap();
2823
/// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);
2824
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 5);
2825
/// ```
2826
///
2827
/// # Panics
2828
///
2829
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2830
pub fn entry<'a, T: Component>(&'a mut self) -> ComponentEntry<'w, 'a, T> {
2831
if self.contains::<T>() {
2832
ComponentEntry::Occupied(OccupiedComponentEntry {
2833
entity_world: self,
2834
_marker: PhantomData,
2835
})
2836
} else {
2837
ComponentEntry::Vacant(VacantComponentEntry {
2838
entity_world: self,
2839
_marker: PhantomData,
2840
})
2841
}
2842
}
2843
2844
/// Creates an [`Observer`] watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]
2845
/// targets this entity.
2846
///
2847
/// # Panics
2848
///
2849
/// If the entity has been despawned while this `EntityWorldMut` is still alive.
2850
///
2851
/// Panics if the given system is an exclusive system.
2852
#[track_caller]
2853
pub fn observe<E: EntityEvent, B: Bundle, M>(
2854
&mut self,
2855
observer: impl IntoObserverSystem<E, B, M>,
2856
) -> &mut Self {
2857
self.observe_with_caller(observer, MaybeLocation::caller())
2858
}
2859
2860
pub(crate) fn observe_with_caller<E: EntityEvent, B: Bundle, M>(
2861
&mut self,
2862
observer: impl IntoObserverSystem<E, B, M>,
2863
caller: MaybeLocation,
2864
) -> &mut Self {
2865
self.assert_not_despawned();
2866
let bundle = Observer::new(observer).with_entity(self.entity);
2867
move_as_ptr!(bundle);
2868
self.world.spawn_with_caller(bundle, caller);
2869
self.world.flush();
2870
self.update_location();
2871
self
2872
}
2873
2874
/// Clones parts of an entity (components, observers, etc.) onto another entity,
2875
/// configured through [`EntityClonerBuilder`].
2876
///
2877
/// The other entity will receive all the components of the original that implement
2878
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
2879
/// [denied](EntityClonerBuilder::deny) in the `config`.
2880
///
2881
/// # Example
2882
///
2883
/// ```
2884
/// # use bevy_ecs::prelude::*;
2885
/// # #[derive(Component, Clone, PartialEq, Debug)]
2886
/// # struct ComponentA;
2887
/// # #[derive(Component, Clone, PartialEq, Debug)]
2888
/// # struct ComponentB;
2889
/// # let mut world = World::new();
2890
/// # let entity = world.spawn((ComponentA, ComponentB)).id();
2891
/// # let target = world.spawn_empty().id();
2892
/// // Clone all components except ComponentA onto the target.
2893
/// world.entity_mut(entity).clone_with_opt_out(target, |builder| {
2894
/// builder.deny::<ComponentA>();
2895
/// });
2896
/// # assert_eq!(world.get::<ComponentA>(target), None);
2897
/// # assert_eq!(world.get::<ComponentB>(target), Some(&ComponentB));
2898
/// ```
2899
///
2900
/// See [`EntityClonerBuilder<OptOut>`] for more options.
2901
///
2902
/// # Panics
2903
///
2904
/// - If this entity has been despawned while this `EntityWorldMut` is still alive.
2905
/// - If the target entity does not exist.
2906
pub fn clone_with_opt_out(
2907
&mut self,
2908
target: Entity,
2909
config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
2910
) -> &mut Self {
2911
self.assert_not_despawned();
2912
2913
let mut builder = EntityCloner::build_opt_out(self.world);
2914
config(&mut builder);
2915
builder.clone_entity(self.entity, target);
2916
2917
self.world.flush();
2918
self.update_location();
2919
self
2920
}
2921
2922
/// Clones parts of an entity (components, observers, etc.) onto another entity,
2923
/// configured through [`EntityClonerBuilder`].
2924
///
2925
/// The other entity will receive only the components of the original that implement
2926
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
2927
/// [allowed](EntityClonerBuilder::allow) in the `config`.
2928
///
2929
/// # Example
2930
///
2931
/// ```
2932
/// # use bevy_ecs::prelude::*;
2933
/// # #[derive(Component, Clone, PartialEq, Debug)]
2934
/// # struct ComponentA;
2935
/// # #[derive(Component, Clone, PartialEq, Debug)]
2936
/// # struct ComponentB;
2937
/// # let mut world = World::new();
2938
/// # let entity = world.spawn((ComponentA, ComponentB)).id();
2939
/// # let target = world.spawn_empty().id();
2940
/// // Clone only ComponentA onto the target.
2941
/// world.entity_mut(entity).clone_with_opt_in(target, |builder| {
2942
/// builder.allow::<ComponentA>();
2943
/// });
2944
/// # assert_eq!(world.get::<ComponentA>(target), Some(&ComponentA));
2945
/// # assert_eq!(world.get::<ComponentB>(target), None);
2946
/// ```
2947
///
2948
/// See [`EntityClonerBuilder<OptIn>`] for more options.
2949
///
2950
/// # Panics
2951
///
2952
/// - If this entity has been despawned while this `EntityWorldMut` is still alive.
2953
/// - If the target entity does not exist.
2954
pub fn clone_with_opt_in(
2955
&mut self,
2956
target: Entity,
2957
config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
2958
) -> &mut Self {
2959
self.assert_not_despawned();
2960
2961
let mut builder = EntityCloner::build_opt_in(self.world);
2962
config(&mut builder);
2963
builder.clone_entity(self.entity, target);
2964
2965
self.world.flush();
2966
self.update_location();
2967
self
2968
}
2969
2970
/// Spawns a clone of this entity and returns the [`Entity`] of the clone.
2971
///
2972
/// The clone will receive all the components of the original that implement
2973
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
2974
///
2975
/// To configure cloning behavior (such as only cloning certain components),
2976
/// use [`EntityWorldMut::clone_and_spawn_with_opt_out`]/
2977
/// [`opt_in`](`EntityWorldMut::clone_and_spawn_with_opt_in`).
2978
///
2979
/// # Panics
2980
///
2981
/// If this entity has been despawned while this `EntityWorldMut` is still alive.
2982
pub fn clone_and_spawn(&mut self) -> Entity {
2983
self.clone_and_spawn_with_opt_out(|_| {})
2984
}
2985
2986
/// Spawns a clone of this entity and allows configuring cloning behavior
2987
/// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.
2988
///
2989
/// The clone will receive all the components of the original that implement
2990
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
2991
/// [denied](EntityClonerBuilder::deny) in the `config`.
2992
///
2993
/// # Example
2994
///
2995
/// ```
2996
/// # use bevy_ecs::prelude::*;
2997
/// # let mut world = World::new();
2998
/// # let entity = world.spawn((ComponentA, ComponentB)).id();
2999
/// # #[derive(Component, Clone, PartialEq, Debug)]
3000
/// # struct ComponentA;
3001
/// # #[derive(Component, Clone, PartialEq, Debug)]
3002
/// # struct ComponentB;
3003
/// // Create a clone of an entity but without ComponentA.
3004
/// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_out(|builder| {
3005
/// builder.deny::<ComponentA>();
3006
/// });
3007
/// # assert_eq!(world.get::<ComponentA>(entity_clone), None);
3008
/// # assert_eq!(world.get::<ComponentB>(entity_clone), Some(&ComponentB));
3009
/// ```
3010
///
3011
/// See [`EntityClonerBuilder<OptOut>`] for more options.
3012
///
3013
/// # Panics
3014
///
3015
/// If this entity has been despawned while this `EntityWorldMut` is still alive.
3016
pub fn clone_and_spawn_with_opt_out(
3017
&mut self,
3018
config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
3019
) -> Entity {
3020
self.assert_not_despawned();
3021
3022
let entity_clone = self.world.entities.reserve_entity();
3023
self.world.flush();
3024
3025
let mut builder = EntityCloner::build_opt_out(self.world);
3026
config(&mut builder);
3027
builder.clone_entity(self.entity, entity_clone);
3028
3029
self.world.flush();
3030
self.update_location();
3031
entity_clone
3032
}
3033
3034
/// Spawns a clone of this entity and allows configuring cloning behavior
3035
/// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.
3036
///
3037
/// The clone will receive only the components of the original that implement
3038
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
3039
/// [allowed](EntityClonerBuilder::allow) in the `config`.
3040
///
3041
/// # Example
3042
///
3043
/// ```
3044
/// # use bevy_ecs::prelude::*;
3045
/// # let mut world = World::new();
3046
/// # let entity = world.spawn((ComponentA, ComponentB)).id();
3047
/// # #[derive(Component, Clone, PartialEq, Debug)]
3048
/// # struct ComponentA;
3049
/// # #[derive(Component, Clone, PartialEq, Debug)]
3050
/// # struct ComponentB;
3051
/// // Create a clone of an entity but only with ComponentA.
3052
/// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_in(|builder| {
3053
/// builder.allow::<ComponentA>();
3054
/// });
3055
/// # assert_eq!(world.get::<ComponentA>(entity_clone), Some(&ComponentA));
3056
/// # assert_eq!(world.get::<ComponentB>(entity_clone), None);
3057
/// ```
3058
///
3059
/// See [`EntityClonerBuilder<OptIn>`] for more options.
3060
///
3061
/// # Panics
3062
///
3063
/// If this entity has been despawned while this `EntityWorldMut` is still alive.
3064
pub fn clone_and_spawn_with_opt_in(
3065
&mut self,
3066
config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
3067
) -> Entity {
3068
self.assert_not_despawned();
3069
3070
let entity_clone = self.world.entities.reserve_entity();
3071
self.world.flush();
3072
3073
let mut builder = EntityCloner::build_opt_in(self.world);
3074
config(&mut builder);
3075
builder.clone_entity(self.entity, entity_clone);
3076
3077
self.world.flush();
3078
self.update_location();
3079
entity_clone
3080
}
3081
3082
/// Clones the specified components of this entity and inserts them into another entity.
3083
///
3084
/// Components can only be cloned if they implement
3085
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
3086
///
3087
/// # Panics
3088
///
3089
/// - If this entity has been despawned while this `EntityWorldMut` is still alive.
3090
/// - If the target entity does not exist.
3091
pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
3092
self.assert_not_despawned();
3093
3094
EntityCloner::build_opt_in(self.world)
3095
.allow::<B>()
3096
.clone_entity(self.entity, target);
3097
3098
self.world.flush();
3099
self.update_location();
3100
self
3101
}
3102
3103
/// Clones the specified components of this entity and inserts them into another entity,
3104
/// then removes the components from this entity.
3105
///
3106
/// Components can only be cloned if they implement
3107
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
3108
///
3109
/// # Panics
3110
///
3111
/// - If this entity has been despawned while this `EntityWorldMut` is still alive.
3112
/// - If the target entity does not exist.
3113
pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
3114
self.assert_not_despawned();
3115
3116
EntityCloner::build_opt_in(self.world)
3117
.allow::<B>()
3118
.move_components(true)
3119
.clone_entity(self.entity, target);
3120
3121
self.world.flush();
3122
self.update_location();
3123
self
3124
}
3125
3126
/// Returns the source code location from which this entity has last been spawned.
3127
pub fn spawned_by(&self) -> MaybeLocation {
3128
self.world()
3129
.entities()
3130
.entity_get_spawned_or_despawned_by(self.entity)
3131
.map(|location| location.unwrap())
3132
}
3133
3134
/// Returns the [`Tick`] at which this entity has last been spawned.
3135
pub fn spawn_tick(&self) -> Tick {
3136
self.assert_not_despawned();
3137
3138
// SAFETY: entity being alive was asserted
3139
unsafe {
3140
self.world()
3141
.entities()
3142
.entity_get_spawned_or_despawned_unchecked(self.entity)
3143
.1
3144
}
3145
}
3146
3147
/// Reborrows this entity in a temporary scope.
3148
/// This is useful for executing a function that requires a `EntityWorldMut`
3149
/// but you do not want to move out the entity ownership.
3150
pub fn reborrow_scope<U>(&mut self, f: impl FnOnce(EntityWorldMut) -> U) -> U {
3151
let Self {
3152
entity, location, ..
3153
} = *self;
3154
self.world_scope(move |world| {
3155
f(EntityWorldMut {
3156
world,
3157
entity,
3158
location,
3159
})
3160
})
3161
}
3162
3163
/// Deprecated. Use [`World::trigger`] instead.
3164
#[track_caller]
3165
#[deprecated(
3166
since = "0.17.0",
3167
note = "Use World::trigger with an EntityEvent instead."
3168
)]
3169
pub fn trigger<'t>(&mut self, event: impl EntityEvent<Trigger<'t>: Default>) -> &mut Self {
3170
log::warn!("EntityWorldMut::trigger is deprecated and no longer triggers the event for the current EntityWorldMut entity. Use World::trigger instead with an EntityEvent.");
3171
self.world_scope(|world| {
3172
world.trigger(event);
3173
});
3174
self
3175
}
3176
}
3177
3178
/// A view into a single entity and component in a world, which may either be vacant or occupied.
3179
///
3180
/// This `enum` can only be constructed from the [`entry`] method on [`EntityWorldMut`].
3181
///
3182
/// [`entry`]: EntityWorldMut::entry
3183
pub enum ComponentEntry<'w, 'a, T: Component> {
3184
/// An occupied entry.
3185
Occupied(OccupiedComponentEntry<'w, 'a, T>),
3186
/// A vacant entry.
3187
Vacant(VacantComponentEntry<'w, 'a, T>),
3188
}
3189
3190
impl<'w, 'a, T: Component<Mutability = Mutable>> ComponentEntry<'w, 'a, T> {
3191
/// Provides in-place mutable access to an occupied entry.
3192
///
3193
/// # Examples
3194
///
3195
/// ```
3196
/// # use bevy_ecs::prelude::*;
3197
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3198
/// struct Comp(u32);
3199
///
3200
/// # let mut world = World::new();
3201
/// let mut entity = world.spawn(Comp(0));
3202
///
3203
/// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);
3204
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 1);
3205
/// ```
3206
#[inline]
3207
pub fn and_modify<F: FnOnce(Mut<'_, T>)>(self, f: F) -> Self {
3208
match self {
3209
ComponentEntry::Occupied(mut entry) => {
3210
f(entry.get_mut());
3211
ComponentEntry::Occupied(entry)
3212
}
3213
ComponentEntry::Vacant(entry) => ComponentEntry::Vacant(entry),
3214
}
3215
}
3216
}
3217
3218
impl<'w, 'a, T: Component> ComponentEntry<'w, 'a, T> {
3219
/// Replaces the component of the entry, and returns an [`OccupiedComponentEntry`].
3220
///
3221
/// # Examples
3222
///
3223
/// ```
3224
/// # use bevy_ecs::prelude::*;
3225
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3226
/// struct Comp(u32);
3227
///
3228
/// # let mut world = World::new();
3229
/// let mut entity = world.spawn_empty();
3230
///
3231
/// let entry = entity.entry().insert_entry(Comp(4));
3232
/// assert_eq!(entry.get(), &Comp(4));
3233
///
3234
/// let entry = entity.entry().insert_entry(Comp(2));
3235
/// assert_eq!(entry.get(), &Comp(2));
3236
/// ```
3237
#[inline]
3238
pub fn insert_entry(self, component: T) -> OccupiedComponentEntry<'w, 'a, T> {
3239
match self {
3240
ComponentEntry::Occupied(mut entry) => {
3241
entry.insert(component);
3242
entry
3243
}
3244
ComponentEntry::Vacant(entry) => entry.insert(component),
3245
}
3246
}
3247
3248
/// Ensures the entry has this component by inserting the given default if empty, and
3249
/// returns a mutable reference to this component in the entry.
3250
///
3251
/// # Examples
3252
///
3253
/// ```
3254
/// # use bevy_ecs::prelude::*;
3255
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3256
/// struct Comp(u32);
3257
///
3258
/// # let mut world = World::new();
3259
/// let mut entity = world.spawn_empty();
3260
///
3261
/// entity.entry().or_insert(Comp(4));
3262
/// # let entity_id = entity.id();
3263
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);
3264
///
3265
/// # let mut entity = world.get_entity_mut(entity_id).unwrap();
3266
/// entity.entry().or_insert(Comp(15)).into_mut().0 *= 2;
3267
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 8);
3268
/// ```
3269
#[inline]
3270
pub fn or_insert(self, default: T) -> OccupiedComponentEntry<'w, 'a, T> {
3271
match self {
3272
ComponentEntry::Occupied(entry) => entry,
3273
ComponentEntry::Vacant(entry) => entry.insert(default),
3274
}
3275
}
3276
3277
/// Ensures the entry has this component by inserting the result of the default function if
3278
/// empty, and returns a mutable reference to this component in the entry.
3279
///
3280
/// # Examples
3281
///
3282
/// ```
3283
/// # use bevy_ecs::prelude::*;
3284
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3285
/// struct Comp(u32);
3286
///
3287
/// # let mut world = World::new();
3288
/// let mut entity = world.spawn_empty();
3289
///
3290
/// entity.entry().or_insert_with(|| Comp(4));
3291
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);
3292
/// ```
3293
#[inline]
3294
pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> OccupiedComponentEntry<'w, 'a, T> {
3295
match self {
3296
ComponentEntry::Occupied(entry) => entry,
3297
ComponentEntry::Vacant(entry) => entry.insert(default()),
3298
}
3299
}
3300
}
3301
3302
impl<'w, 'a, T: Component + Default> ComponentEntry<'w, 'a, T> {
3303
/// Ensures the entry has this component by inserting the default value if empty, and
3304
/// returns a mutable reference to this component in the entry.
3305
///
3306
/// # Examples
3307
///
3308
/// ```
3309
/// # use bevy_ecs::prelude::*;
3310
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3311
/// struct Comp(u32);
3312
///
3313
/// # let mut world = World::new();
3314
/// let mut entity = world.spawn_empty();
3315
///
3316
/// entity.entry::<Comp>().or_default();
3317
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 0);
3318
/// ```
3319
#[inline]
3320
pub fn or_default(self) -> OccupiedComponentEntry<'w, 'a, T> {
3321
match self {
3322
ComponentEntry::Occupied(entry) => entry,
3323
ComponentEntry::Vacant(entry) => entry.insert(Default::default()),
3324
}
3325
}
3326
}
3327
3328
/// A view into an occupied entry in a [`EntityWorldMut`]. It is part of the [`OccupiedComponentEntry`] enum.
3329
///
3330
/// The contained entity must have the component type parameter if we have this struct.
3331
pub struct OccupiedComponentEntry<'w, 'a, T: Component> {
3332
entity_world: &'a mut EntityWorldMut<'w>,
3333
_marker: PhantomData<T>,
3334
}
3335
3336
impl<'w, 'a, T: Component> OccupiedComponentEntry<'w, 'a, T> {
3337
/// Gets a reference to the component in the entry.
3338
///
3339
/// # Examples
3340
///
3341
/// ```
3342
/// # use bevy_ecs::{prelude::*, world::ComponentEntry};
3343
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3344
/// struct Comp(u32);
3345
///
3346
/// # let mut world = World::new();
3347
/// let mut entity = world.spawn(Comp(5));
3348
///
3349
/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {
3350
/// assert_eq!(o.get().0, 5);
3351
/// }
3352
/// ```
3353
#[inline]
3354
pub fn get(&self) -> &T {
3355
// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.
3356
self.entity_world.get::<T>().unwrap()
3357
}
3358
3359
/// Replaces the component of the entry.
3360
///
3361
/// # Examples
3362
///
3363
/// ```
3364
/// # use bevy_ecs::{prelude::*, world::ComponentEntry};
3365
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3366
/// struct Comp(u32);
3367
///
3368
/// # let mut world = World::new();
3369
/// let mut entity = world.spawn(Comp(5));
3370
///
3371
/// if let ComponentEntry::Occupied(mut o) = entity.entry::<Comp>() {
3372
/// o.insert(Comp(10));
3373
/// }
3374
///
3375
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 10);
3376
/// ```
3377
#[inline]
3378
pub fn insert(&mut self, component: T) {
3379
self.entity_world.insert(component);
3380
}
3381
3382
/// Removes the component from the entry and returns it.
3383
///
3384
/// # Examples
3385
///
3386
/// ```
3387
/// # use bevy_ecs::{prelude::*, world::ComponentEntry};
3388
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3389
/// struct Comp(u32);
3390
///
3391
/// # let mut world = World::new();
3392
/// let mut entity = world.spawn(Comp(5));
3393
///
3394
/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {
3395
/// assert_eq!(o.take(), Comp(5));
3396
/// }
3397
///
3398
/// assert_eq!(world.query::<&Comp>().iter(&world).len(), 0);
3399
/// ```
3400
#[inline]
3401
pub fn take(self) -> T {
3402
// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.
3403
self.entity_world.take().unwrap()
3404
}
3405
}
3406
3407
impl<'w, 'a, T: Component<Mutability = Mutable>> OccupiedComponentEntry<'w, 'a, T> {
3408
/// Gets a mutable reference to the component in the entry.
3409
///
3410
/// If you need a reference to the [`OccupiedComponentEntry`] which may outlive the destruction of
3411
/// the [`OccupiedComponentEntry`] value, see [`into_mut`].
3412
///
3413
/// [`into_mut`]: Self::into_mut
3414
///
3415
/// # Examples
3416
///
3417
/// ```
3418
/// # use bevy_ecs::{prelude::*, world::ComponentEntry};
3419
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3420
/// struct Comp(u32);
3421
///
3422
/// # let mut world = World::new();
3423
/// let mut entity = world.spawn(Comp(5));
3424
///
3425
/// if let ComponentEntry::Occupied(mut o) = entity.entry::<Comp>() {
3426
/// o.get_mut().0 += 10;
3427
/// assert_eq!(o.get().0, 15);
3428
///
3429
/// // We can use the same Entry multiple times.
3430
/// o.get_mut().0 += 2
3431
/// }
3432
///
3433
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 17);
3434
/// ```
3435
#[inline]
3436
pub fn get_mut(&mut self) -> Mut<'_, T> {
3437
// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.
3438
self.entity_world.get_mut::<T>().unwrap()
3439
}
3440
3441
/// Converts the [`OccupiedComponentEntry`] into a mutable reference to the value in the entry with
3442
/// a lifetime bound to the `EntityWorldMut`.
3443
///
3444
/// If you need multiple references to the [`OccupiedComponentEntry`], see [`get_mut`].
3445
///
3446
/// [`get_mut`]: Self::get_mut
3447
///
3448
/// # Examples
3449
///
3450
/// ```
3451
/// # use bevy_ecs::{prelude::*, world::ComponentEntry};
3452
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3453
/// struct Comp(u32);
3454
///
3455
/// # let mut world = World::new();
3456
/// let mut entity = world.spawn(Comp(5));
3457
///
3458
/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {
3459
/// o.into_mut().0 += 10;
3460
/// }
3461
///
3462
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 15);
3463
/// ```
3464
#[inline]
3465
pub fn into_mut(self) -> Mut<'a, T> {
3466
// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.
3467
self.entity_world.get_mut().unwrap()
3468
}
3469
}
3470
3471
/// A view into a vacant entry in a [`EntityWorldMut`]. It is part of the [`ComponentEntry`] enum.
3472
pub struct VacantComponentEntry<'w, 'a, T: Component> {
3473
entity_world: &'a mut EntityWorldMut<'w>,
3474
_marker: PhantomData<T>,
3475
}
3476
3477
impl<'w, 'a, T: Component> VacantComponentEntry<'w, 'a, T> {
3478
/// Inserts the component into the [`VacantComponentEntry`] and returns an [`OccupiedComponentEntry`].
3479
///
3480
/// # Examples
3481
///
3482
/// ```
3483
/// # use bevy_ecs::{prelude::*, world::ComponentEntry};
3484
/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
3485
/// struct Comp(u32);
3486
///
3487
/// # let mut world = World::new();
3488
/// let mut entity = world.spawn_empty();
3489
///
3490
/// if let ComponentEntry::Vacant(v) = entity.entry::<Comp>() {
3491
/// v.insert(Comp(10));
3492
/// }
3493
///
3494
/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 10);
3495
/// ```
3496
#[inline]
3497
pub fn insert(self, component: T) -> OccupiedComponentEntry<'w, 'a, T> {
3498
self.entity_world.insert(component);
3499
OccupiedComponentEntry {
3500
entity_world: self.entity_world,
3501
_marker: PhantomData,
3502
}
3503
}
3504
}
3505
3506
/// Provides read-only access to a single entity and some of its components defined by the contained [`Access`].
3507
///
3508
/// To define the access when used as a [`QueryData`](crate::query::QueryData),
3509
/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).
3510
/// The [`FilteredEntityRef`] must be the entire [`QueryData`](crate::query::QueryData), and not nested inside a tuple with other data.
3511
///
3512
/// ```
3513
/// # use bevy_ecs::{prelude::*, world::FilteredEntityRef};
3514
/// #
3515
/// # #[derive(Component)]
3516
/// # struct A;
3517
/// #
3518
/// # let mut world = World::new();
3519
/// # world.spawn(A);
3520
/// #
3521
/// // This gives the `FilteredEntityRef` access to `&A`.
3522
/// let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
3523
/// .data::<&A>()
3524
/// .build();
3525
///
3526
/// let filtered_entity: FilteredEntityRef = query.single(&mut world).unwrap();
3527
/// let component: &A = filtered_entity.get().unwrap();
3528
/// ```
3529
#[derive(Clone, Copy)]
3530
pub struct FilteredEntityRef<'w, 's> {
3531
entity: UnsafeEntityCell<'w>,
3532
access: &'s Access,
3533
}
3534
3535
impl<'w, 's> FilteredEntityRef<'w, 's> {
3536
/// # Safety
3537
/// - No `&mut World` can exist from the underlying `UnsafeWorldCell`
3538
/// - If `access` takes read access to a component no mutable reference to that
3539
/// component can exist at the same time as the returned [`FilteredEntityMut`]
3540
/// - If `access` takes any access for a component `entity` must have that component.
3541
#[inline]
3542
pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {
3543
Self { entity, access }
3544
}
3545
3546
/// Returns the [ID](Entity) of the current entity.
3547
#[inline]
3548
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
3549
pub fn id(&self) -> Entity {
3550
self.entity.id()
3551
}
3552
3553
/// Gets metadata indicating the location where the current entity is stored.
3554
#[inline]
3555
pub fn location(&self) -> EntityLocation {
3556
self.entity.location()
3557
}
3558
3559
/// Returns the archetype that the current entity belongs to.
3560
#[inline]
3561
pub fn archetype(&self) -> &Archetype {
3562
self.entity.archetype()
3563
}
3564
3565
/// Returns a reference to the underlying [`Access`].
3566
#[inline]
3567
pub fn access(&self) -> &Access {
3568
self.access
3569
}
3570
3571
/// Returns `true` if the current entity has a component of type `T`.
3572
/// Otherwise, this returns `false`.
3573
///
3574
/// ## Notes
3575
///
3576
/// If you do not know the concrete type of a component, consider using
3577
/// [`Self::contains_id`] or [`Self::contains_type_id`].
3578
#[inline]
3579
pub fn contains<T: Component>(&self) -> bool {
3580
self.contains_type_id(TypeId::of::<T>())
3581
}
3582
3583
/// Returns `true` if the current entity has a component identified by `component_id`.
3584
/// Otherwise, this returns false.
3585
///
3586
/// ## Notes
3587
///
3588
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
3589
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
3590
/// [`Self::contains_type_id`].
3591
#[inline]
3592
pub fn contains_id(&self, component_id: ComponentId) -> bool {
3593
self.entity.contains_id(component_id)
3594
}
3595
3596
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
3597
/// Otherwise, this returns false.
3598
///
3599
/// ## Notes
3600
///
3601
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
3602
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
3603
#[inline]
3604
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
3605
self.entity.contains_type_id(type_id)
3606
}
3607
3608
/// Gets access to the component of type `T` for the current entity.
3609
/// Returns `None` if the entity does not have a component of type `T`.
3610
#[inline]
3611
pub fn get<T: Component>(&self) -> Option<&'w T> {
3612
let id = self
3613
.entity
3614
.world()
3615
.components()
3616
.get_valid_id(TypeId::of::<T>())?;
3617
self.access
3618
.has_component_read(id)
3619
// SAFETY: We have read access
3620
.then(|| unsafe { self.entity.get() })
3621
.flatten()
3622
}
3623
3624
/// Gets access to the component of type `T` for the current entity,
3625
/// including change detection information as a [`Ref`].
3626
///
3627
/// Returns `None` if the entity does not have a component of type `T`.
3628
#[inline]
3629
pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {
3630
let id = self
3631
.entity
3632
.world()
3633
.components()
3634
.get_valid_id(TypeId::of::<T>())?;
3635
self.access
3636
.has_component_read(id)
3637
// SAFETY: We have read access
3638
.then(|| unsafe { self.entity.get_ref() })
3639
.flatten()
3640
}
3641
3642
/// Retrieves the change ticks for the given component. This can be useful for implementing change
3643
/// detection in custom runtimes.
3644
#[inline]
3645
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
3646
let id = self
3647
.entity
3648
.world()
3649
.components()
3650
.get_valid_id(TypeId::of::<T>())?;
3651
self.access
3652
.has_component_read(id)
3653
// SAFETY: We have read access
3654
.then(|| unsafe { self.entity.get_change_ticks::<T>() })
3655
.flatten()
3656
}
3657
3658
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
3659
/// detection in custom runtimes.
3660
///
3661
/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only
3662
/// use this in cases where the actual component types are not known at
3663
/// compile time.**
3664
#[inline]
3665
pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
3666
self.access
3667
.has_component_read(component_id)
3668
// SAFETY: We have read access
3669
.then(|| unsafe { self.entity.get_change_ticks_by_id(component_id) })
3670
.flatten()
3671
}
3672
3673
/// Gets the component of the given [`ComponentId`] from the entity.
3674
///
3675
/// **You should prefer to use the typed API [`Self::get`] where possible and only
3676
/// use this in cases where the actual component types are not known at
3677
/// compile time.**
3678
///
3679
/// Unlike [`FilteredEntityRef::get`], this returns a raw pointer to the component,
3680
/// which is only valid while the [`FilteredEntityRef`] is alive.
3681
#[inline]
3682
pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {
3683
self.access
3684
.has_component_read(component_id)
3685
// SAFETY: We have read access
3686
.then(|| unsafe { self.entity.get_by_id(component_id) })
3687
.flatten()
3688
}
3689
3690
/// Returns the source code location from which this entity has been spawned.
3691
pub fn spawned_by(&self) -> MaybeLocation {
3692
self.entity.spawned_by()
3693
}
3694
3695
/// Returns the [`Tick`] at which this entity has been spawned.
3696
pub fn spawn_tick(&self) -> Tick {
3697
self.entity.spawn_tick()
3698
}
3699
}
3700
3701
impl<'w, 's> From<FilteredEntityMut<'w, 's>> for FilteredEntityRef<'w, 's> {
3702
#[inline]
3703
fn from(entity: FilteredEntityMut<'w, 's>) -> Self {
3704
// SAFETY:
3705
// - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
3706
unsafe { FilteredEntityRef::new(entity.entity, entity.access) }
3707
}
3708
}
3709
3710
impl<'w, 's> From<&'w FilteredEntityMut<'_, 's>> for FilteredEntityRef<'w, 's> {
3711
#[inline]
3712
fn from(entity: &'w FilteredEntityMut<'_, 's>) -> Self {
3713
// SAFETY:
3714
// - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
3715
unsafe { FilteredEntityRef::new(entity.entity, entity.access) }
3716
}
3717
}
3718
3719
impl<'a> From<EntityRef<'a>> for FilteredEntityRef<'a, 'static> {
3720
fn from(entity: EntityRef<'a>) -> Self {
3721
// SAFETY:
3722
// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.
3723
unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }
3724
}
3725
}
3726
3727
impl<'a> From<&'a EntityRef<'_>> for FilteredEntityRef<'a, 'static> {
3728
fn from(entity: &'a EntityRef<'_>) -> Self {
3729
// SAFETY:
3730
// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.
3731
unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }
3732
}
3733
}
3734
3735
impl<'a> From<EntityMut<'a>> for FilteredEntityRef<'a, 'static> {
3736
fn from(entity: EntityMut<'a>) -> Self {
3737
// SAFETY:
3738
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
3739
unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }
3740
}
3741
}
3742
3743
impl<'a> From<&'a EntityMut<'_>> for FilteredEntityRef<'a, 'static> {
3744
fn from(entity: &'a EntityMut<'_>) -> Self {
3745
// SAFETY:
3746
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
3747
unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }
3748
}
3749
}
3750
3751
impl<'a> From<EntityWorldMut<'a>> for FilteredEntityRef<'a, 'static> {
3752
fn from(entity: EntityWorldMut<'a>) -> Self {
3753
// SAFETY:
3754
// - `EntityWorldMut` guarantees exclusive access to the entire world.
3755
unsafe {
3756
FilteredEntityRef::new(
3757
entity.into_unsafe_entity_cell(),
3758
const { &Access::new_read_all() },
3759
)
3760
}
3761
}
3762
}
3763
3764
impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a, 'static> {
3765
fn from(entity: &'a EntityWorldMut<'_>) -> Self {
3766
// SAFETY:
3767
// - `EntityWorldMut` guarantees exclusive access to the entire world.
3768
unsafe {
3769
FilteredEntityRef::new(
3770
entity.as_unsafe_entity_cell_readonly(),
3771
const { &Access::new_read_all() },
3772
)
3773
}
3774
}
3775
}
3776
3777
impl<'w, 's, B: Bundle> From<&'w EntityRefExcept<'_, 's, B>> for FilteredEntityRef<'w, 's> {
3778
fn from(value: &'w EntityRefExcept<'_, 's, B>) -> Self {
3779
// SAFETY:
3780
// - The FilteredEntityRef has the same component access as the given EntityRefExcept.
3781
unsafe { FilteredEntityRef::new(value.entity, value.access) }
3782
}
3783
}
3784
3785
impl PartialEq for FilteredEntityRef<'_, '_> {
3786
fn eq(&self, other: &Self) -> bool {
3787
self.entity() == other.entity()
3788
}
3789
}
3790
3791
impl Eq for FilteredEntityRef<'_, '_> {}
3792
3793
impl PartialOrd for FilteredEntityRef<'_, '_> {
3794
/// [`FilteredEntityRef`]'s comparison trait implementations match the underlying [`Entity`],
3795
/// and cannot discern between different worlds.
3796
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
3797
Some(self.cmp(other))
3798
}
3799
}
3800
3801
impl Ord for FilteredEntityRef<'_, '_> {
3802
fn cmp(&self, other: &Self) -> Ordering {
3803
self.entity().cmp(&other.entity())
3804
}
3805
}
3806
3807
impl Hash for FilteredEntityRef<'_, '_> {
3808
fn hash<H: Hasher>(&self, state: &mut H) {
3809
self.entity().hash(state);
3810
}
3811
}
3812
3813
impl ContainsEntity for FilteredEntityRef<'_, '_> {
3814
fn entity(&self) -> Entity {
3815
self.id()
3816
}
3817
}
3818
3819
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
3820
unsafe impl EntityEquivalent for FilteredEntityRef<'_, '_> {}
3821
3822
/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
3823
///
3824
/// To define the access when used as a [`QueryData`](crate::query::QueryData),
3825
/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).
3826
/// The `FilteredEntityMut` must be the entire `QueryData`, and not nested inside a tuple with other data.
3827
///
3828
/// ```
3829
/// # use bevy_ecs::{prelude::*, world::FilteredEntityMut};
3830
/// #
3831
/// # #[derive(Component)]
3832
/// # struct A;
3833
/// #
3834
/// # let mut world = World::new();
3835
/// # world.spawn(A);
3836
/// #
3837
/// // This gives the `FilteredEntityMut` access to `&mut A`.
3838
/// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)
3839
/// .data::<&mut A>()
3840
/// .build();
3841
///
3842
/// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();
3843
/// let component: Mut<A> = filtered_entity.get_mut().unwrap();
3844
/// ```
3845
pub struct FilteredEntityMut<'w, 's> {
3846
entity: UnsafeEntityCell<'w>,
3847
access: &'s Access,
3848
}
3849
3850
impl<'w, 's> FilteredEntityMut<'w, 's> {
3851
/// # Safety
3852
/// - No `&mut World` can exist from the underlying `UnsafeWorldCell`
3853
/// - If `access` takes read access to a component no mutable reference to that
3854
/// component can exist at the same time as the returned [`FilteredEntityMut`]
3855
/// - If `access` takes write access to a component, no reference to that component
3856
/// may exist at the same time as the returned [`FilteredEntityMut`]
3857
/// - If `access` takes any access for a component `entity` must have that component.
3858
#[inline]
3859
pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {
3860
Self { entity, access }
3861
}
3862
3863
/// Returns a new instance with a shorter lifetime.
3864
/// This is useful if you have `&mut FilteredEntityMut`, but you need `FilteredEntityMut`.
3865
pub fn reborrow(&mut self) -> FilteredEntityMut<'_, 's> {
3866
// SAFETY: We have exclusive access to the entire entity and its components.
3867
unsafe { Self::new(self.entity, self.access) }
3868
}
3869
3870
/// Gets read-only access to all of the entity's components.
3871
#[inline]
3872
pub fn as_readonly(&self) -> FilteredEntityRef<'_, 's> {
3873
FilteredEntityRef::from(self)
3874
}
3875
3876
/// Returns the [ID](Entity) of the current entity.
3877
#[inline]
3878
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
3879
pub fn id(&self) -> Entity {
3880
self.entity.id()
3881
}
3882
3883
/// Gets metadata indicating the location where the current entity is stored.
3884
#[inline]
3885
pub fn location(&self) -> EntityLocation {
3886
self.entity.location()
3887
}
3888
3889
/// Returns the archetype that the current entity belongs to.
3890
#[inline]
3891
pub fn archetype(&self) -> &Archetype {
3892
self.entity.archetype()
3893
}
3894
3895
/// Returns a reference to the underlying [`Access`].
3896
#[inline]
3897
pub fn access(&self) -> &Access {
3898
self.access
3899
}
3900
3901
/// Returns `true` if the current entity has a component of type `T`.
3902
/// Otherwise, this returns `false`.
3903
///
3904
/// ## Notes
3905
///
3906
/// If you do not know the concrete type of a component, consider using
3907
/// [`Self::contains_id`] or [`Self::contains_type_id`].
3908
#[inline]
3909
pub fn contains<T: Component>(&self) -> bool {
3910
self.contains_type_id(TypeId::of::<T>())
3911
}
3912
3913
/// Returns `true` if the current entity has a component identified by `component_id`.
3914
/// Otherwise, this returns false.
3915
///
3916
/// ## Notes
3917
///
3918
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
3919
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
3920
/// [`Self::contains_type_id`].
3921
#[inline]
3922
pub fn contains_id(&self, component_id: ComponentId) -> bool {
3923
self.entity.contains_id(component_id)
3924
}
3925
3926
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
3927
/// Otherwise, this returns false.
3928
///
3929
/// ## Notes
3930
///
3931
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
3932
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
3933
#[inline]
3934
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
3935
self.entity.contains_type_id(type_id)
3936
}
3937
3938
/// Gets access to the component of type `T` for the current entity.
3939
/// Returns `None` if the entity does not have a component of type `T`.
3940
#[inline]
3941
pub fn get<T: Component>(&self) -> Option<&'_ T> {
3942
self.as_readonly().get()
3943
}
3944
3945
/// Gets access to the component of type `T` for the current entity,
3946
/// including change detection information as a [`Ref`].
3947
///
3948
/// Returns `None` if the entity does not have a component of type `T`.
3949
#[inline]
3950
pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
3951
self.as_readonly().get_ref()
3952
}
3953
3954
/// Gets mutable access to the component of type `T` for the current entity.
3955
/// Returns `None` if the entity does not have a component of type `T`.
3956
#[inline]
3957
pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {
3958
let id = self
3959
.entity
3960
.world()
3961
.components()
3962
.get_valid_id(TypeId::of::<T>())?;
3963
self.access
3964
.has_component_write(id)
3965
// SAFETY: We have write access
3966
.then(|| unsafe { self.entity.get_mut() })
3967
.flatten()
3968
}
3969
3970
/// Consumes self and gets mutable access to the component of type `T`
3971
/// with the world `'w` lifetime for the current entity.
3972
/// Returns `None` if the entity does not have a component of type `T`.
3973
#[inline]
3974
pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {
3975
// SAFETY:
3976
// - We have write access
3977
// - The bound `T: Component<Mutability = Mutable>` ensures the component is mutable
3978
unsafe { self.into_mut_assume_mutable() }
3979
}
3980
3981
/// Consumes self and gets mutable access to the component of type `T`
3982
/// with the world `'w` lifetime for the current entity.
3983
/// Returns `None` if the entity does not have a component of type `T`.
3984
///
3985
/// # Safety
3986
///
3987
/// - `T` must be a mutable component
3988
#[inline]
3989
pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {
3990
let id = self
3991
.entity
3992
.world()
3993
.components()
3994
.get_valid_id(TypeId::of::<T>())?;
3995
self.access
3996
.has_component_write(id)
3997
// SAFETY:
3998
// - We have write access
3999
// - Caller ensures `T` is a mutable component
4000
.then(|| unsafe { self.entity.get_mut_assume_mutable() })
4001
.flatten()
4002
}
4003
4004
/// Retrieves the change ticks for the given component. This can be useful for implementing change
4005
/// detection in custom runtimes.
4006
#[inline]
4007
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
4008
self.as_readonly().get_change_ticks::<T>()
4009
}
4010
4011
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
4012
/// detection in custom runtimes.
4013
///
4014
/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only
4015
/// use this in cases where the actual component types are not known at
4016
/// compile time.**
4017
#[inline]
4018
pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
4019
self.as_readonly().get_change_ticks_by_id(component_id)
4020
}
4021
4022
/// Gets the component of the given [`ComponentId`] from the entity.
4023
///
4024
/// **You should prefer to use the typed API [`Self::get`] where possible and only
4025
/// use this in cases where the actual component types are not known at
4026
/// compile time.**
4027
///
4028
/// Unlike [`FilteredEntityMut::get`], this returns a raw pointer to the component,
4029
/// which is only valid while the [`FilteredEntityMut`] is alive.
4030
#[inline]
4031
pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
4032
self.as_readonly().get_by_id(component_id)
4033
}
4034
4035
/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
4036
///
4037
/// **You should prefer to use the typed API [`Self::get_mut`] where possible and only
4038
/// use this in cases where the actual component types are not known at
4039
/// compile time.**
4040
///
4041
/// Unlike [`FilteredEntityMut::get_mut`], this returns a raw pointer to the component,
4042
/// which is only valid while the [`FilteredEntityMut`] is alive.
4043
#[inline]
4044
pub fn get_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
4045
self.access
4046
.has_component_write(component_id)
4047
// SAFETY: We have write access
4048
.then(|| unsafe { self.entity.get_mut_by_id(component_id).ok() })
4049
.flatten()
4050
}
4051
4052
/// Returns the source code location from which this entity has last been spawned.
4053
pub fn spawned_by(&self) -> MaybeLocation {
4054
self.entity.spawned_by()
4055
}
4056
4057
/// Returns the [`Tick`] at which this entity has been spawned.
4058
pub fn spawn_tick(&self) -> Tick {
4059
self.entity.spawn_tick()
4060
}
4061
}
4062
4063
impl<'a> From<EntityMut<'a>> for FilteredEntityMut<'a, 'static> {
4064
fn from(entity: EntityMut<'a>) -> Self {
4065
// SAFETY:
4066
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.
4067
unsafe { FilteredEntityMut::new(entity.cell, const { &Access::new_write_all() }) }
4068
}
4069
}
4070
4071
impl<'a> From<&'a mut EntityMut<'_>> for FilteredEntityMut<'a, 'static> {
4072
fn from(entity: &'a mut EntityMut<'_>) -> Self {
4073
// SAFETY:
4074
// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.
4075
unsafe { FilteredEntityMut::new(entity.cell, const { &Access::new_write_all() }) }
4076
}
4077
}
4078
4079
impl<'a> From<EntityWorldMut<'a>> for FilteredEntityMut<'a, 'static> {
4080
fn from(entity: EntityWorldMut<'a>) -> Self {
4081
// SAFETY:
4082
// - `EntityWorldMut` guarantees exclusive access to the entire world.
4083
unsafe {
4084
FilteredEntityMut::new(
4085
entity.into_unsafe_entity_cell(),
4086
const { &Access::new_write_all() },
4087
)
4088
}
4089
}
4090
}
4091
4092
impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a, 'static> {
4093
fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {
4094
// SAFETY:
4095
// - `EntityWorldMut` guarantees exclusive access to the entire world.
4096
unsafe {
4097
FilteredEntityMut::new(
4098
entity.as_unsafe_entity_cell(),
4099
const { &Access::new_write_all() },
4100
)
4101
}
4102
}
4103
}
4104
4105
impl<'w, 's, B: Bundle> From<&'w EntityMutExcept<'_, 's, B>> for FilteredEntityMut<'w, 's> {
4106
fn from(value: &'w EntityMutExcept<'_, 's, B>) -> Self {
4107
// SAFETY:
4108
// - The FilteredEntityMut has the same component access as the given EntityMutExcept.
4109
unsafe { FilteredEntityMut::new(value.entity, value.access) }
4110
}
4111
}
4112
4113
impl PartialEq for FilteredEntityMut<'_, '_> {
4114
fn eq(&self, other: &Self) -> bool {
4115
self.entity() == other.entity()
4116
}
4117
}
4118
4119
impl Eq for FilteredEntityMut<'_, '_> {}
4120
4121
impl PartialOrd for FilteredEntityMut<'_, '_> {
4122
/// [`FilteredEntityMut`]'s comparison trait implementations match the underlying [`Entity`],
4123
/// and cannot discern between different worlds.
4124
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
4125
Some(self.cmp(other))
4126
}
4127
}
4128
4129
impl Ord for FilteredEntityMut<'_, '_> {
4130
fn cmp(&self, other: &Self) -> Ordering {
4131
self.entity().cmp(&other.entity())
4132
}
4133
}
4134
4135
impl Hash for FilteredEntityMut<'_, '_> {
4136
fn hash<H: Hasher>(&self, state: &mut H) {
4137
self.entity().hash(state);
4138
}
4139
}
4140
4141
impl ContainsEntity for FilteredEntityMut<'_, '_> {
4142
fn entity(&self) -> Entity {
4143
self.id()
4144
}
4145
}
4146
4147
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
4148
unsafe impl EntityEquivalent for FilteredEntityMut<'_, '_> {}
4149
4150
/// Error type returned by [`TryFrom`] conversions from filtered entity types
4151
/// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types
4152
/// ([`EntityRef`]/[`EntityMut`]).
4153
#[derive(Error, Debug)]
4154
pub enum TryFromFilteredError {
4155
/// Error indicating that the filtered entity does not have read access to
4156
/// all components.
4157
#[error("Conversion failed, filtered entity ref does not have read access to all components")]
4158
MissingReadAllAccess,
4159
/// Error indicating that the filtered entity does not have write access to
4160
/// all components.
4161
#[error("Conversion failed, filtered entity ref does not have write access to all components")]
4162
MissingWriteAllAccess,
4163
}
4164
4165
/// Provides read-only access to a single entity and all its components, save
4166
/// for an explicitly-enumerated set.
4167
pub struct EntityRefExcept<'w, 's, B>
4168
where
4169
B: Bundle,
4170
{
4171
entity: UnsafeEntityCell<'w>,
4172
access: &'s Access,
4173
phantom: PhantomData<B>,
4174
}
4175
4176
impl<'w, 's, B> EntityRefExcept<'w, 's, B>
4177
where
4178
B: Bundle,
4179
{
4180
/// # Safety
4181
/// Other users of `UnsafeEntityCell` must only have mutable access to the components in `B`.
4182
pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {
4183
Self {
4184
entity,
4185
access,
4186
phantom: PhantomData,
4187
}
4188
}
4189
4190
/// Returns the [ID](Entity) of the current entity.
4191
#[inline]
4192
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
4193
pub fn id(&self) -> Entity {
4194
self.entity.id()
4195
}
4196
4197
/// Gets access to the component of type `C` for the current entity. Returns
4198
/// `None` if the component doesn't have a component of that type or if the
4199
/// type is one of the excluded components.
4200
#[inline]
4201
pub fn get<C>(&self) -> Option<&'w C>
4202
where
4203
C: Component,
4204
{
4205
let components = self.entity.world().components();
4206
let id = components.valid_component_id::<C>()?;
4207
if bundle_contains_component::<B>(components, id) {
4208
None
4209
} else {
4210
// SAFETY: We have read access for all components that weren't
4211
// covered by the `contains` check above.
4212
unsafe { self.entity.get() }
4213
}
4214
}
4215
4216
/// Gets access to the component of type `C` for the current entity,
4217
/// including change detection information. Returns `None` if the component
4218
/// doesn't have a component of that type or if the type is one of the
4219
/// excluded components.
4220
#[inline]
4221
pub fn get_ref<C>(&self) -> Option<Ref<'w, C>>
4222
where
4223
C: Component,
4224
{
4225
let components = self.entity.world().components();
4226
let id = components.valid_component_id::<C>()?;
4227
if bundle_contains_component::<B>(components, id) {
4228
None
4229
} else {
4230
// SAFETY: We have read access for all components that weren't
4231
// covered by the `contains` check above.
4232
unsafe { self.entity.get_ref() }
4233
}
4234
}
4235
4236
/// Returns the source code location from which this entity has been spawned.
4237
pub fn spawned_by(&self) -> MaybeLocation {
4238
self.entity.spawned_by()
4239
}
4240
4241
/// Returns the [`Tick`] at which this entity has been spawned.
4242
pub fn spawn_tick(&self) -> Tick {
4243
self.entity.spawn_tick()
4244
}
4245
4246
/// Gets the component of the given [`ComponentId`] from the entity.
4247
///
4248
/// **You should prefer to use the typed API [`Self::get`] where possible and only
4249
/// use this in cases where the actual component types are not known at
4250
/// compile time.**
4251
///
4252
/// Unlike [`EntityRefExcept::get`], this returns a raw pointer to the component,
4253
/// which is only valid while the [`EntityRefExcept`] is alive.
4254
#[inline]
4255
pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {
4256
let components = self.entity.world().components();
4257
(!bundle_contains_component::<B>(components, component_id))
4258
.then(|| {
4259
// SAFETY: We have read access for this component
4260
unsafe { self.entity.get_by_id(component_id) }
4261
})
4262
.flatten()
4263
}
4264
4265
/// Returns `true` if the current entity has a component of type `T`.
4266
/// Otherwise, this returns `false`.
4267
///
4268
/// ## Notes
4269
///
4270
/// If you do not know the concrete type of a component, consider using
4271
/// [`Self::contains_id`] or [`Self::contains_type_id`].
4272
#[inline]
4273
pub fn contains<T: Component>(&self) -> bool {
4274
self.contains_type_id(TypeId::of::<T>())
4275
}
4276
4277
/// Returns `true` if the current entity has a component identified by `component_id`.
4278
/// Otherwise, this returns false.
4279
///
4280
/// ## Notes
4281
///
4282
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
4283
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
4284
/// [`Self::contains_type_id`].
4285
#[inline]
4286
pub fn contains_id(&self, component_id: ComponentId) -> bool {
4287
self.entity.contains_id(component_id)
4288
}
4289
4290
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
4291
/// Otherwise, this returns false.
4292
///
4293
/// ## Notes
4294
///
4295
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
4296
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
4297
#[inline]
4298
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
4299
self.entity.contains_type_id(type_id)
4300
}
4301
4302
/// Retrieves the change ticks for the given component. This can be useful for implementing change
4303
/// detection in custom runtimes.
4304
#[inline]
4305
pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
4306
let component_id = self
4307
.entity
4308
.world()
4309
.components()
4310
.get_valid_id(TypeId::of::<T>())?;
4311
let components = self.entity.world().components();
4312
(!bundle_contains_component::<B>(components, component_id))
4313
.then(|| {
4314
// SAFETY: We have read access
4315
unsafe { self.entity.get_change_ticks::<T>() }
4316
})
4317
.flatten()
4318
}
4319
4320
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
4321
/// detection in custom runtimes.
4322
///
4323
/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only
4324
/// use this in cases where the actual component types are not known at
4325
/// compile time.**
4326
#[inline]
4327
pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
4328
let components = self.entity.world().components();
4329
(!bundle_contains_component::<B>(components, component_id))
4330
.then(|| {
4331
// SAFETY: We have read access
4332
unsafe { self.entity.get_change_ticks_by_id(component_id) }
4333
})
4334
.flatten()
4335
}
4336
}
4337
4338
impl<'w, 's, B> From<&'w EntityMutExcept<'_, 's, B>> for EntityRefExcept<'w, 's, B>
4339
where
4340
B: Bundle,
4341
{
4342
fn from(entity: &'w EntityMutExcept<'_, 's, B>) -> Self {
4343
// SAFETY: All accesses that `EntityRefExcept` provides are also
4344
// accesses that `EntityMutExcept` provides.
4345
unsafe { EntityRefExcept::new(entity.entity, entity.access) }
4346
}
4347
}
4348
4349
impl<B: Bundle> Clone for EntityRefExcept<'_, '_, B> {
4350
fn clone(&self) -> Self {
4351
*self
4352
}
4353
}
4354
4355
impl<B: Bundle> Copy for EntityRefExcept<'_, '_, B> {}
4356
4357
impl<B: Bundle> PartialEq for EntityRefExcept<'_, '_, B> {
4358
fn eq(&self, other: &Self) -> bool {
4359
self.entity() == other.entity()
4360
}
4361
}
4362
4363
impl<B: Bundle> Eq for EntityRefExcept<'_, '_, B> {}
4364
4365
impl<B: Bundle> PartialOrd for EntityRefExcept<'_, '_, B> {
4366
/// [`EntityRefExcept`]'s comparison trait implementations match the underlying [`Entity`],
4367
/// and cannot discern between different worlds.
4368
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
4369
Some(self.cmp(other))
4370
}
4371
}
4372
4373
impl<B: Bundle> Ord for EntityRefExcept<'_, '_, B> {
4374
fn cmp(&self, other: &Self) -> Ordering {
4375
self.entity().cmp(&other.entity())
4376
}
4377
}
4378
4379
impl<B: Bundle> Hash for EntityRefExcept<'_, '_, B> {
4380
fn hash<H: Hasher>(&self, state: &mut H) {
4381
self.entity().hash(state);
4382
}
4383
}
4384
4385
impl<B: Bundle> ContainsEntity for EntityRefExcept<'_, '_, B> {
4386
fn entity(&self) -> Entity {
4387
self.id()
4388
}
4389
}
4390
4391
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
4392
unsafe impl<B: Bundle> EntityEquivalent for EntityRefExcept<'_, '_, B> {}
4393
4394
/// Provides mutable access to all components of an entity, with the exception
4395
/// of an explicit set.
4396
///
4397
/// This is a rather niche type that should only be used if you need access to
4398
/// *all* components of an entity, while still allowing you to consult other
4399
/// queries that might match entities that this query also matches. If you don't
4400
/// need access to all components, prefer a standard query with a
4401
/// [`Without`](`crate::query::Without`) filter.
4402
pub struct EntityMutExcept<'w, 's, B>
4403
where
4404
B: Bundle,
4405
{
4406
entity: UnsafeEntityCell<'w>,
4407
access: &'s Access,
4408
phantom: PhantomData<B>,
4409
}
4410
4411
impl<'w, 's, B> EntityMutExcept<'w, 's, B>
4412
where
4413
B: Bundle,
4414
{
4415
/// # Safety
4416
/// Other users of `UnsafeEntityCell` must not have access to any components not in `B`.
4417
pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {
4418
Self {
4419
entity,
4420
access,
4421
phantom: PhantomData,
4422
}
4423
}
4424
4425
/// Returns the [ID](Entity) of the current entity.
4426
#[inline]
4427
#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
4428
pub fn id(&self) -> Entity {
4429
self.entity.id()
4430
}
4431
4432
/// Returns a new instance with a shorter lifetime.
4433
///
4434
/// This is useful if you have `&mut EntityMutExcept`, but you need
4435
/// `EntityMutExcept`.
4436
pub fn reborrow(&mut self) -> EntityMutExcept<'_, 's, B> {
4437
// SAFETY: We have exclusive access to the entire entity and the
4438
// applicable components.
4439
unsafe { Self::new(self.entity, self.access) }
4440
}
4441
4442
/// Gets read-only access to all of the entity's components, except for the
4443
/// ones in `CL`.
4444
#[inline]
4445
pub fn as_readonly(&self) -> EntityRefExcept<'_, 's, B> {
4446
EntityRefExcept::from(self)
4447
}
4448
4449
/// Gets access to the component of type `C` for the current entity. Returns
4450
/// `None` if the component doesn't have a component of that type or if the
4451
/// type is one of the excluded components.
4452
#[inline]
4453
pub fn get<C>(&self) -> Option<&'_ C>
4454
where
4455
C: Component,
4456
{
4457
self.as_readonly().get()
4458
}
4459
4460
/// Gets access to the component of type `C` for the current entity,
4461
/// including change detection information. Returns `None` if the component
4462
/// doesn't have a component of that type or if the type is one of the
4463
/// excluded components.
4464
#[inline]
4465
pub fn get_ref<C>(&self) -> Option<Ref<'_, C>>
4466
where
4467
C: Component,
4468
{
4469
self.as_readonly().get_ref()
4470
}
4471
4472
/// Gets mutable access to the component of type `C` for the current entity.
4473
/// Returns `None` if the component doesn't have a component of that type or
4474
/// if the type is one of the excluded components.
4475
#[inline]
4476
pub fn get_mut<C>(&mut self) -> Option<Mut<'_, C>>
4477
where
4478
C: Component<Mutability = Mutable>,
4479
{
4480
let components = self.entity.world().components();
4481
let id = components.valid_component_id::<C>()?;
4482
if bundle_contains_component::<B>(components, id) {
4483
None
4484
} else {
4485
// SAFETY: We have write access for all components that weren't
4486
// covered by the `contains` check above.
4487
unsafe { self.entity.get_mut() }
4488
}
4489
}
4490
4491
/// Returns the source code location from which this entity has been spawned.
4492
pub fn spawned_by(&self) -> MaybeLocation {
4493
self.entity.spawned_by()
4494
}
4495
4496
/// Returns the [`Tick`] at which this entity has been spawned.
4497
pub fn spawn_tick(&self) -> Tick {
4498
self.entity.spawn_tick()
4499
}
4500
4501
/// Returns `true` if the current entity has a component of type `T`.
4502
/// Otherwise, this returns `false`.
4503
///
4504
/// ## Notes
4505
///
4506
/// If you do not know the concrete type of a component, consider using
4507
/// [`Self::contains_id`] or [`Self::contains_type_id`].
4508
#[inline]
4509
pub fn contains<T: Component>(&self) -> bool {
4510
self.contains_type_id(TypeId::of::<T>())
4511
}
4512
4513
/// Returns `true` if the current entity has a component identified by `component_id`.
4514
/// Otherwise, this returns false.
4515
///
4516
/// ## Notes
4517
///
4518
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
4519
/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
4520
/// [`Self::contains_type_id`].
4521
#[inline]
4522
pub fn contains_id(&self, component_id: ComponentId) -> bool {
4523
self.entity.contains_id(component_id)
4524
}
4525
4526
/// Returns `true` if the current entity has a component with the type identified by `type_id`.
4527
/// Otherwise, this returns false.
4528
///
4529
/// ## Notes
4530
///
4531
/// - If you know the concrete type of the component, you should prefer [`Self::contains`].
4532
/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
4533
#[inline]
4534
pub fn contains_type_id(&self, type_id: TypeId) -> bool {
4535
self.entity.contains_type_id(type_id)
4536
}
4537
4538
/// Gets the component of the given [`ComponentId`] from the entity.
4539
///
4540
/// **You should prefer to use the typed API [`Self::get`] where possible and only
4541
/// use this in cases where the actual component types are not known at
4542
/// compile time.**
4543
///
4544
/// Unlike [`EntityMutExcept::get`], this returns a raw pointer to the component,
4545
/// which is only valid while the [`EntityMutExcept`] is alive.
4546
#[inline]
4547
pub fn get_by_id(&'w self, component_id: ComponentId) -> Option<Ptr<'w>> {
4548
self.as_readonly().get_by_id(component_id)
4549
}
4550
4551
/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
4552
///
4553
/// **You should prefer to use the typed API [`Self::get_mut`] where possible and only
4554
/// use this in cases where the actual component types are not known at
4555
/// compile time.**
4556
///
4557
/// Unlike [`EntityMutExcept::get_mut`], this returns a raw pointer to the component,
4558
/// which is only valid while the [`EntityMutExcept`] is alive.
4559
#[inline]
4560
pub fn get_mut_by_id<F: DynamicComponentFetch>(
4561
&mut self,
4562
component_id: ComponentId,
4563
) -> Option<MutUntyped<'_>> {
4564
let components = self.entity.world().components();
4565
(!bundle_contains_component::<B>(components, component_id))
4566
.then(|| {
4567
// SAFETY: We have write access
4568
unsafe { self.entity.get_mut_by_id(component_id).ok() }
4569
})
4570
.flatten()
4571
}
4572
}
4573
4574
impl<B: Bundle> PartialEq for EntityMutExcept<'_, '_, B> {
4575
fn eq(&self, other: &Self) -> bool {
4576
self.entity() == other.entity()
4577
}
4578
}
4579
4580
impl<B: Bundle> Eq for EntityMutExcept<'_, '_, B> {}
4581
4582
impl<B: Bundle> PartialOrd for EntityMutExcept<'_, '_, B> {
4583
/// [`EntityMutExcept`]'s comparison trait implementations match the underlying [`Entity`],
4584
/// and cannot discern between different worlds.
4585
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
4586
Some(self.cmp(other))
4587
}
4588
}
4589
4590
impl<B: Bundle> Ord for EntityMutExcept<'_, '_, B> {
4591
fn cmp(&self, other: &Self) -> Ordering {
4592
self.entity().cmp(&other.entity())
4593
}
4594
}
4595
4596
impl<B: Bundle> Hash for EntityMutExcept<'_, '_, B> {
4597
fn hash<H: Hasher>(&self, state: &mut H) {
4598
self.entity().hash(state);
4599
}
4600
}
4601
4602
impl<B: Bundle> ContainsEntity for EntityMutExcept<'_, '_, B> {
4603
fn entity(&self) -> Entity {
4604
self.id()
4605
}
4606
}
4607
4608
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
4609
unsafe impl<B: Bundle> EntityEquivalent for EntityMutExcept<'_, '_, B> {}
4610
4611
fn bundle_contains_component<B>(components: &Components, query_id: ComponentId) -> bool
4612
where
4613
B: Bundle,
4614
{
4615
let mut found = false;
4616
B::get_component_ids(components, &mut |maybe_id| {
4617
if let Some(id) = maybe_id {
4618
found = found || id == query_id;
4619
}
4620
});
4621
found
4622
}
4623
4624
/// Inserts a dynamic [`Bundle`] into the entity.
4625
///
4626
/// # Safety
4627
///
4628
/// - [`OwningPtr`] and [`StorageType`] iterators must correspond to the
4629
/// [`BundleInfo`](crate::bundle::BundleInfo) used to construct [`BundleInserter`]
4630
/// - [`Entity`] must correspond to [`EntityLocation`]
4631
unsafe fn insert_dynamic_bundle<
4632
'a,
4633
I: Iterator<Item = OwningPtr<'a>>,
4634
S: Iterator<Item = StorageType>,
4635
>(
4636
mut bundle_inserter: BundleInserter<'_>,
4637
entity: Entity,
4638
location: EntityLocation,
4639
components: I,
4640
storage_types: S,
4641
mode: InsertMode,
4642
caller: MaybeLocation,
4643
relationship_hook_insert_mode: RelationshipHookMode,
4644
) -> EntityLocation {
4645
struct DynamicInsertBundle<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> {
4646
components: I,
4647
}
4648
4649
impl<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> DynamicBundle
4650
for DynamicInsertBundle<'a, I>
4651
{
4652
type Effect = ();
4653
unsafe fn get_components(
4654
mut ptr: MovingPtr<'_, Self>,
4655
func: &mut impl FnMut(StorageType, OwningPtr<'_>),
4656
) {
4657
(&mut ptr.components).for_each(|(t, ptr)| func(t, ptr));
4658
}
4659
4660
unsafe fn apply_effect(
4661
_ptr: MovingPtr<'_, MaybeUninit<Self>>,
4662
_entity: &mut EntityWorldMut,
4663
) {
4664
}
4665
}
4666
4667
let bundle = DynamicInsertBundle {
4668
components: storage_types.zip(components),
4669
};
4670
4671
move_as_ptr!(bundle);
4672
4673
// SAFETY:
4674
// - `location` matches `entity`. and thus must currently exist in the source
4675
// archetype for this inserter and its location within the archetype.
4676
// - The caller must ensure that the iterators and storage types match up with the `BundleInserter`
4677
// - `apply_effect` is never called on this bundle.
4678
// - `bundle` is not used or dropped after this point.
4679
unsafe {
4680
bundle_inserter.insert(
4681
entity,
4682
location,
4683
bundle,
4684
mode,
4685
caller,
4686
relationship_hook_insert_mode,
4687
)
4688
}
4689
}
4690
4691
/// Types that can be used to fetch components from an entity dynamically by
4692
/// [`ComponentId`]s.
4693
///
4694
/// Provided implementations are:
4695
/// - [`ComponentId`]: Returns a single untyped reference.
4696
/// - `[ComponentId; N]` and `&[ComponentId; N]`: Returns a same-sized array of untyped references.
4697
/// - `&[ComponentId]`: Returns a [`Vec`] of untyped references.
4698
/// - [`&HashSet<ComponentId>`](HashSet): Returns a [`HashMap`] of IDs to untyped references.
4699
///
4700
/// # Performance
4701
///
4702
/// - The slice and array implementations perform an aliased mutability check in
4703
/// [`DynamicComponentFetch::fetch_mut`] that is `O(N^2)`.
4704
/// - The [`HashSet`] implementation performs no such check as the type itself
4705
/// guarantees unique IDs.
4706
/// - The single [`ComponentId`] implementation performs no such check as only
4707
/// one reference is returned.
4708
///
4709
/// # Safety
4710
///
4711
/// Implementor must ensure that:
4712
/// - No aliased mutability is caused by the returned references.
4713
/// - [`DynamicComponentFetch::fetch_ref`] returns only read-only references.
4714
pub unsafe trait DynamicComponentFetch {
4715
/// The read-only reference type returned by [`DynamicComponentFetch::fetch_ref`].
4716
type Ref<'w>;
4717
4718
/// The mutable reference type returned by [`DynamicComponentFetch::fetch_mut`].
4719
type Mut<'w>;
4720
4721
/// Returns untyped read-only reference(s) to the component(s) with the
4722
/// given [`ComponentId`]s, as determined by `self`.
4723
///
4724
/// # Safety
4725
///
4726
/// It is the caller's responsibility to ensure that:
4727
/// - The given [`UnsafeEntityCell`] has read-only access to the fetched components.
4728
/// - No other mutable references to the fetched components exist at the same time.
4729
///
4730
/// # Errors
4731
///
4732
/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.
4733
unsafe fn fetch_ref(
4734
self,
4735
cell: UnsafeEntityCell<'_>,
4736
) -> Result<Self::Ref<'_>, EntityComponentError>;
4737
4738
/// Returns untyped mutable reference(s) to the component(s) with the
4739
/// given [`ComponentId`]s, as determined by `self`.
4740
///
4741
/// # Safety
4742
///
4743
/// It is the caller's responsibility to ensure that:
4744
/// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.
4745
/// - No other references to the fetched components exist at the same time.
4746
///
4747
/// # Errors
4748
///
4749
/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.
4750
/// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.
4751
unsafe fn fetch_mut(
4752
self,
4753
cell: UnsafeEntityCell<'_>,
4754
) -> Result<Self::Mut<'_>, EntityComponentError>;
4755
4756
/// Returns untyped mutable reference(s) to the component(s) with the
4757
/// given [`ComponentId`]s, as determined by `self`.
4758
/// Assumes all [`ComponentId`]s refer to mutable components.
4759
///
4760
/// # Safety
4761
///
4762
/// It is the caller's responsibility to ensure that:
4763
/// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.
4764
/// - No other references to the fetched components exist at the same time.
4765
/// - The requested components are all mutable.
4766
///
4767
/// # Errors
4768
///
4769
/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.
4770
/// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.
4771
unsafe fn fetch_mut_assume_mutable(
4772
self,
4773
cell: UnsafeEntityCell<'_>,
4774
) -> Result<Self::Mut<'_>, EntityComponentError>;
4775
}
4776
4777
// SAFETY:
4778
// - No aliased mutability is caused because a single reference is returned.
4779
// - No mutable references are returned by `fetch_ref`.
4780
unsafe impl DynamicComponentFetch for ComponentId {
4781
type Ref<'w> = Ptr<'w>;
4782
type Mut<'w> = MutUntyped<'w>;
4783
4784
unsafe fn fetch_ref(
4785
self,
4786
cell: UnsafeEntityCell<'_>,
4787
) -> Result<Self::Ref<'_>, EntityComponentError> {
4788
// SAFETY: caller ensures that the cell has read access to the component.
4789
unsafe { cell.get_by_id(self) }.ok_or(EntityComponentError::MissingComponent(self))
4790
}
4791
4792
unsafe fn fetch_mut(
4793
self,
4794
cell: UnsafeEntityCell<'_>,
4795
) -> Result<Self::Mut<'_>, EntityComponentError> {
4796
// SAFETY: caller ensures that the cell has mutable access to the component.
4797
unsafe { cell.get_mut_by_id(self) }
4798
.map_err(|_| EntityComponentError::MissingComponent(self))
4799
}
4800
4801
unsafe fn fetch_mut_assume_mutable(
4802
self,
4803
cell: UnsafeEntityCell<'_>,
4804
) -> Result<Self::Mut<'_>, EntityComponentError> {
4805
// SAFETY: caller ensures that the cell has mutable access to the component.
4806
unsafe { cell.get_mut_assume_mutable_by_id(self) }
4807
.map_err(|_| EntityComponentError::MissingComponent(self))
4808
}
4809
}
4810
4811
// SAFETY:
4812
// - No aliased mutability is caused because the array is checked for duplicates.
4813
// - No mutable references are returned by `fetch_ref`.
4814
unsafe impl<const N: usize> DynamicComponentFetch for [ComponentId; N] {
4815
type Ref<'w> = [Ptr<'w>; N];
4816
type Mut<'w> = [MutUntyped<'w>; N];
4817
4818
unsafe fn fetch_ref(
4819
self,
4820
cell: UnsafeEntityCell<'_>,
4821
) -> Result<Self::Ref<'_>, EntityComponentError> {
4822
<&Self>::fetch_ref(&self, cell)
4823
}
4824
4825
unsafe fn fetch_mut(
4826
self,
4827
cell: UnsafeEntityCell<'_>,
4828
) -> Result<Self::Mut<'_>, EntityComponentError> {
4829
<&Self>::fetch_mut(&self, cell)
4830
}
4831
4832
unsafe fn fetch_mut_assume_mutable(
4833
self,
4834
cell: UnsafeEntityCell<'_>,
4835
) -> Result<Self::Mut<'_>, EntityComponentError> {
4836
<&Self>::fetch_mut_assume_mutable(&self, cell)
4837
}
4838
}
4839
4840
// SAFETY:
4841
// - No aliased mutability is caused because the array is checked for duplicates.
4842
// - No mutable references are returned by `fetch_ref`.
4843
unsafe impl<const N: usize> DynamicComponentFetch for &'_ [ComponentId; N] {
4844
type Ref<'w> = [Ptr<'w>; N];
4845
type Mut<'w> = [MutUntyped<'w>; N];
4846
4847
unsafe fn fetch_ref(
4848
self,
4849
cell: UnsafeEntityCell<'_>,
4850
) -> Result<Self::Ref<'_>, EntityComponentError> {
4851
let mut ptrs = [const { MaybeUninit::uninit() }; N];
4852
for (ptr, &id) in core::iter::zip(&mut ptrs, self) {
4853
*ptr = MaybeUninit::new(
4854
// SAFETY: caller ensures that the cell has read access to the component.
4855
unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,
4856
);
4857
}
4858
4859
// SAFETY: Each ptr was initialized in the loop above.
4860
let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });
4861
4862
Ok(ptrs)
4863
}
4864
4865
unsafe fn fetch_mut(
4866
self,
4867
cell: UnsafeEntityCell<'_>,
4868
) -> Result<Self::Mut<'_>, EntityComponentError> {
4869
// Check for duplicate component IDs.
4870
for i in 0..self.len() {
4871
for j in 0..i {
4872
if self[i] == self[j] {
4873
return Err(EntityComponentError::AliasedMutability(self[i]));
4874
}
4875
}
4876
}
4877
4878
let mut ptrs = [const { MaybeUninit::uninit() }; N];
4879
for (ptr, &id) in core::iter::zip(&mut ptrs, self) {
4880
*ptr = MaybeUninit::new(
4881
// SAFETY: caller ensures that the cell has mutable access to the component.
4882
unsafe { cell.get_mut_by_id(id) }
4883
.map_err(|_| EntityComponentError::MissingComponent(id))?,
4884
);
4885
}
4886
4887
// SAFETY: Each ptr was initialized in the loop above.
4888
let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });
4889
4890
Ok(ptrs)
4891
}
4892
4893
unsafe fn fetch_mut_assume_mutable(
4894
self,
4895
cell: UnsafeEntityCell<'_>,
4896
) -> Result<Self::Mut<'_>, EntityComponentError> {
4897
// Check for duplicate component IDs.
4898
for i in 0..self.len() {
4899
for j in 0..i {
4900
if self[i] == self[j] {
4901
return Err(EntityComponentError::AliasedMutability(self[i]));
4902
}
4903
}
4904
}
4905
4906
let mut ptrs = [const { MaybeUninit::uninit() }; N];
4907
for (ptr, &id) in core::iter::zip(&mut ptrs, self) {
4908
*ptr = MaybeUninit::new(
4909
// SAFETY: caller ensures that the cell has mutable access to the component.
4910
unsafe { cell.get_mut_assume_mutable_by_id(id) }
4911
.map_err(|_| EntityComponentError::MissingComponent(id))?,
4912
);
4913
}
4914
4915
// SAFETY: Each ptr was initialized in the loop above.
4916
let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });
4917
4918
Ok(ptrs)
4919
}
4920
}
4921
4922
// SAFETY:
4923
// - No aliased mutability is caused because the slice is checked for duplicates.
4924
// - No mutable references are returned by `fetch_ref`.
4925
unsafe impl DynamicComponentFetch for &'_ [ComponentId] {
4926
type Ref<'w> = Vec<Ptr<'w>>;
4927
type Mut<'w> = Vec<MutUntyped<'w>>;
4928
4929
unsafe fn fetch_ref(
4930
self,
4931
cell: UnsafeEntityCell<'_>,
4932
) -> Result<Self::Ref<'_>, EntityComponentError> {
4933
let mut ptrs = Vec::with_capacity(self.len());
4934
for &id in self {
4935
ptrs.push(
4936
// SAFETY: caller ensures that the cell has read access to the component.
4937
unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,
4938
);
4939
}
4940
Ok(ptrs)
4941
}
4942
4943
unsafe fn fetch_mut(
4944
self,
4945
cell: UnsafeEntityCell<'_>,
4946
) -> Result<Self::Mut<'_>, EntityComponentError> {
4947
// Check for duplicate component IDs.
4948
for i in 0..self.len() {
4949
for j in 0..i {
4950
if self[i] == self[j] {
4951
return Err(EntityComponentError::AliasedMutability(self[i]));
4952
}
4953
}
4954
}
4955
4956
let mut ptrs = Vec::with_capacity(self.len());
4957
for &id in self {
4958
ptrs.push(
4959
// SAFETY: caller ensures that the cell has mutable access to the component.
4960
unsafe { cell.get_mut_by_id(id) }
4961
.map_err(|_| EntityComponentError::MissingComponent(id))?,
4962
);
4963
}
4964
Ok(ptrs)
4965
}
4966
4967
unsafe fn fetch_mut_assume_mutable(
4968
self,
4969
cell: UnsafeEntityCell<'_>,
4970
) -> Result<Self::Mut<'_>, EntityComponentError> {
4971
// Check for duplicate component IDs.
4972
for i in 0..self.len() {
4973
for j in 0..i {
4974
if self[i] == self[j] {
4975
return Err(EntityComponentError::AliasedMutability(self[i]));
4976
}
4977
}
4978
}
4979
4980
let mut ptrs = Vec::with_capacity(self.len());
4981
for &id in self {
4982
ptrs.push(
4983
// SAFETY: caller ensures that the cell has mutable access to the component.
4984
unsafe { cell.get_mut_assume_mutable_by_id(id) }
4985
.map_err(|_| EntityComponentError::MissingComponent(id))?,
4986
);
4987
}
4988
Ok(ptrs)
4989
}
4990
}
4991
4992
// SAFETY:
4993
// - No aliased mutability is caused because `HashSet` guarantees unique elements.
4994
// - No mutable references are returned by `fetch_ref`.
4995
unsafe impl DynamicComponentFetch for &'_ HashSet<ComponentId> {
4996
type Ref<'w> = HashMap<ComponentId, Ptr<'w>>;
4997
type Mut<'w> = HashMap<ComponentId, MutUntyped<'w>>;
4998
4999
unsafe fn fetch_ref(
5000
self,
5001
cell: UnsafeEntityCell<'_>,
5002
) -> Result<Self::Ref<'_>, EntityComponentError> {
5003
let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());
5004
for &id in self {
5005
ptrs.insert(
5006
id,
5007
// SAFETY: caller ensures that the cell has read access to the component.
5008
unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,
5009
);
5010
}
5011
Ok(ptrs)
5012
}
5013
5014
unsafe fn fetch_mut(
5015
self,
5016
cell: UnsafeEntityCell<'_>,
5017
) -> Result<Self::Mut<'_>, EntityComponentError> {
5018
let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());
5019
for &id in self {
5020
ptrs.insert(
5021
id,
5022
// SAFETY: caller ensures that the cell has mutable access to the component.
5023
unsafe { cell.get_mut_by_id(id) }
5024
.map_err(|_| EntityComponentError::MissingComponent(id))?,
5025
);
5026
}
5027
Ok(ptrs)
5028
}
5029
5030
unsafe fn fetch_mut_assume_mutable(
5031
self,
5032
cell: UnsafeEntityCell<'_>,
5033
) -> Result<Self::Mut<'_>, EntityComponentError> {
5034
let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());
5035
for &id in self {
5036
ptrs.insert(
5037
id,
5038
// SAFETY: caller ensures that the cell has mutable access to the component.
5039
unsafe { cell.get_mut_assume_mutable_by_id(id) }
5040
.map_err(|_| EntityComponentError::MissingComponent(id))?,
5041
);
5042
}
5043
Ok(ptrs)
5044
}
5045
}
5046
5047
#[cfg(test)]
5048
mod tests {
5049
use alloc::{vec, vec::Vec};
5050
use bevy_ptr::{OwningPtr, Ptr};
5051
use core::panic::AssertUnwindSafe;
5052
use std::sync::OnceLock;
5053
5054
use crate::component::Tick;
5055
use crate::lifecycle::HookContext;
5056
use crate::{
5057
change_detection::{MaybeLocation, MutUntyped},
5058
component::ComponentId,
5059
prelude::*,
5060
system::{assert_is_system, RunSystemOnce as _},
5061
world::{error::EntityComponentError, DeferredWorld, FilteredEntityMut, FilteredEntityRef},
5062
};
5063
5064
use super::{EntityMutExcept, EntityRefExcept};
5065
5066
#[derive(Component, Clone, Copy, Debug, PartialEq)]
5067
struct TestComponent(u32);
5068
5069
#[derive(Component, Clone, Copy, Debug, PartialEq)]
5070
#[component(storage = "SparseSet")]
5071
struct TestComponent2(u32);
5072
5073
#[test]
5074
fn entity_ref_get_by_id() {
5075
let mut world = World::new();
5076
let entity = world.spawn(TestComponent(42)).id();
5077
let component_id = world
5078
.components()
5079
.get_valid_id(core::any::TypeId::of::<TestComponent>())
5080
.unwrap();
5081
5082
let entity = world.entity(entity);
5083
let test_component = entity.get_by_id(component_id).unwrap();
5084
// SAFETY: points to a valid `TestComponent`
5085
let test_component = unsafe { test_component.deref::<TestComponent>() };
5086
5087
assert_eq!(test_component.0, 42);
5088
}
5089
5090
#[test]
5091
fn entity_mut_get_by_id() {
5092
let mut world = World::new();
5093
let entity = world.spawn(TestComponent(42)).id();
5094
let component_id = world
5095
.components()
5096
.get_valid_id(core::any::TypeId::of::<TestComponent>())
5097
.unwrap();
5098
5099
let mut entity_mut = world.entity_mut(entity);
5100
let mut test_component = entity_mut.get_mut_by_id(component_id).unwrap();
5101
{
5102
test_component.set_changed();
5103
let test_component =
5104
// SAFETY: `test_component` has unique access of the `EntityWorldMut` and is not used afterwards
5105
unsafe { test_component.into_inner().deref_mut::<TestComponent>() };
5106
test_component.0 = 43;
5107
}
5108
5109
let entity = world.entity(entity);
5110
let test_component = entity.get_by_id(component_id).unwrap();
5111
// SAFETY: `TestComponent` is the correct component type
5112
let test_component = unsafe { test_component.deref::<TestComponent>() };
5113
5114
assert_eq!(test_component.0, 43);
5115
}
5116
5117
#[test]
5118
fn entity_ref_get_by_id_invalid_component_id() {
5119
let invalid_component_id = ComponentId::new(usize::MAX);
5120
5121
let mut world = World::new();
5122
let entity = world.spawn_empty().id();
5123
let entity = world.entity(entity);
5124
assert!(entity.get_by_id(invalid_component_id).is_err());
5125
}
5126
5127
#[test]
5128
fn entity_mut_get_by_id_invalid_component_id() {
5129
let invalid_component_id = ComponentId::new(usize::MAX);
5130
5131
let mut world = World::new();
5132
let mut entity = world.spawn_empty();
5133
assert!(entity.get_by_id(invalid_component_id).is_err());
5134
assert!(entity.get_mut_by_id(invalid_component_id).is_err());
5135
}
5136
5137
#[derive(Resource)]
5138
struct R(usize);
5139
5140
#[test]
5141
fn entity_mut_resource_scope() {
5142
// Keep in sync with the `resource_scope` test in lib.rs
5143
let mut world = World::new();
5144
let mut entity = world.spawn_empty();
5145
5146
assert!(entity.try_resource_scope::<R, _>(|_, _| {}).is_none());
5147
entity.world_scope(|world| world.insert_resource(R(0)));
5148
entity.resource_scope(|entity: &mut EntityWorldMut, mut value: Mut<R>| {
5149
value.0 += 1;
5150
assert!(!entity.world().contains_resource::<R>());
5151
});
5152
assert_eq!(entity.resource::<R>().0, 1);
5153
}
5154
5155
#[test]
5156
fn entity_mut_resource_scope_panic() {
5157
let mut world = World::new();
5158
world.insert_resource(R(0));
5159
5160
let mut entity = world.spawn_empty();
5161
let old_location = entity.location();
5162
let result = std::panic::catch_unwind(AssertUnwindSafe(|| {
5163
entity.resource_scope(|entity: &mut EntityWorldMut, _: Mut<R>| {
5164
// Change the entity's `EntityLocation`.
5165
entity.insert(TestComponent(0));
5166
5167
// Ensure that the entity location still gets updated even in case of a panic.
5168
panic!("this should get caught by the outer scope")
5169
});
5170
}));
5171
assert!(result.is_err());
5172
5173
// Ensure that the location has been properly updated.
5174
assert_ne!(entity.location(), old_location);
5175
}
5176
5177
// regression test for https://github.com/bevyengine/bevy/pull/7387
5178
#[test]
5179
fn entity_mut_world_scope_panic() {
5180
let mut world = World::new();
5181
5182
let mut entity = world.spawn_empty();
5183
let old_location = entity.location();
5184
let id = entity.id();
5185
let res = std::panic::catch_unwind(AssertUnwindSafe(|| {
5186
entity.world_scope(|w| {
5187
// Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.
5188
// This will get updated at the end of the scope.
5189
w.entity_mut(id).insert(TestComponent(0));
5190
5191
// Ensure that the entity location still gets updated even in case of a panic.
5192
panic!("this should get caught by the outer scope")
5193
});
5194
}));
5195
assert!(res.is_err());
5196
5197
// Ensure that the location has been properly updated.
5198
assert_ne!(entity.location(), old_location);
5199
}
5200
5201
#[test]
5202
fn entity_mut_reborrow_scope_panic() {
5203
let mut world = World::new();
5204
5205
let mut entity = world.spawn_empty();
5206
let old_location = entity.location();
5207
let res = std::panic::catch_unwind(AssertUnwindSafe(|| {
5208
entity.reborrow_scope(|mut entity| {
5209
// Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.
5210
// This will get updated at the end of the scope.
5211
entity.insert(TestComponent(0));
5212
5213
// Ensure that the entity location still gets updated even in case of a panic.
5214
panic!("this should get caught by the outer scope")
5215
});
5216
}));
5217
assert!(res.is_err());
5218
5219
// Ensure that the location has been properly updated.
5220
assert_ne!(entity.location(), old_location);
5221
}
5222
5223
// regression test for https://github.com/bevyengine/bevy/pull/7805
5224
#[test]
5225
fn removing_sparse_updates_archetype_row() {
5226
#[derive(Component, PartialEq, Debug)]
5227
struct Dense(u8);
5228
5229
#[derive(Component)]
5230
#[component(storage = "SparseSet")]
5231
struct Sparse;
5232
5233
let mut world = World::new();
5234
let e1 = world.spawn((Dense(0), Sparse)).id();
5235
let e2 = world.spawn((Dense(1), Sparse)).id();
5236
5237
world.entity_mut(e1).remove::<Sparse>();
5238
assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
5239
}
5240
5241
// regression test for https://github.com/bevyengine/bevy/pull/7805
5242
#[test]
5243
fn removing_dense_updates_table_row() {
5244
#[derive(Component, PartialEq, Debug)]
5245
struct Dense(u8);
5246
5247
#[derive(Component)]
5248
#[component(storage = "SparseSet")]
5249
struct Sparse;
5250
5251
let mut world = World::new();
5252
let e1 = world.spawn((Dense(0), Sparse)).id();
5253
let e2 = world.spawn((Dense(1), Sparse)).id();
5254
5255
world.entity_mut(e1).remove::<Dense>();
5256
assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
5257
}
5258
5259
// Test that calling retain with `()` removes all components.
5260
#[test]
5261
fn retain_nothing() {
5262
#[derive(Component)]
5263
struct Marker<const N: usize>;
5264
5265
let mut world = World::new();
5266
let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();
5267
5268
world.entity_mut(ent).retain::<()>();
5269
assert_eq!(world.entity(ent).archetype().components().len(), 0);
5270
}
5271
5272
// Test removing some components with `retain`, including components not on the entity.
5273
#[test]
5274
fn retain_some_components() {
5275
#[derive(Component)]
5276
struct Marker<const N: usize>;
5277
5278
let mut world = World::new();
5279
let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();
5280
5281
world.entity_mut(ent).retain::<(Marker<2>, Marker<4>)>();
5282
// Check that marker 2 was retained.
5283
assert!(world.entity(ent).get::<Marker<2>>().is_some());
5284
// Check that only marker 2 was retained.
5285
assert_eq!(world.entity(ent).archetype().components().len(), 1);
5286
}
5287
5288
// regression test for https://github.com/bevyengine/bevy/pull/7805
5289
#[test]
5290
fn inserting_sparse_updates_archetype_row() {
5291
#[derive(Component, PartialEq, Debug)]
5292
struct Dense(u8);
5293
5294
#[derive(Component)]
5295
#[component(storage = "SparseSet")]
5296
struct Sparse;
5297
5298
let mut world = World::new();
5299
let e1 = world.spawn(Dense(0)).id();
5300
let e2 = world.spawn(Dense(1)).id();
5301
5302
world.entity_mut(e1).insert(Sparse);
5303
assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
5304
}
5305
5306
// regression test for https://github.com/bevyengine/bevy/pull/7805
5307
#[test]
5308
fn inserting_dense_updates_archetype_row() {
5309
#[derive(Component, PartialEq, Debug)]
5310
struct Dense(u8);
5311
5312
#[derive(Component)]
5313
struct Dense2;
5314
5315
#[derive(Component)]
5316
#[component(storage = "SparseSet")]
5317
struct Sparse;
5318
5319
let mut world = World::new();
5320
let e1 = world.spawn(Dense(0)).id();
5321
let e2 = world.spawn(Dense(1)).id();
5322
5323
world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
5324
5325
// archetype with [e2, e1]
5326
// table with [e1, e2]
5327
5328
world.entity_mut(e2).insert(Dense2);
5329
5330
assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));
5331
}
5332
5333
#[test]
5334
fn inserting_dense_updates_table_row() {
5335
#[derive(Component, PartialEq, Debug)]
5336
struct Dense(u8);
5337
5338
#[derive(Component)]
5339
struct Dense2;
5340
5341
#[derive(Component)]
5342
#[component(storage = "SparseSet")]
5343
struct Sparse;
5344
5345
let mut world = World::new();
5346
let e1 = world.spawn(Dense(0)).id();
5347
let e2 = world.spawn(Dense(1)).id();
5348
5349
world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
5350
5351
// archetype with [e2, e1]
5352
// table with [e1, e2]
5353
5354
world.entity_mut(e1).insert(Dense2);
5355
5356
assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
5357
}
5358
5359
// regression test for https://github.com/bevyengine/bevy/pull/7805
5360
#[test]
5361
fn despawning_entity_updates_archetype_row() {
5362
#[derive(Component, PartialEq, Debug)]
5363
struct Dense(u8);
5364
5365
#[derive(Component)]
5366
#[component(storage = "SparseSet")]
5367
struct Sparse;
5368
5369
let mut world = World::new();
5370
let e1 = world.spawn(Dense(0)).id();
5371
let e2 = world.spawn(Dense(1)).id();
5372
5373
world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
5374
5375
// archetype with [e2, e1]
5376
// table with [e1, e2]
5377
5378
world.entity_mut(e2).despawn();
5379
5380
assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));
5381
}
5382
5383
// regression test for https://github.com/bevyengine/bevy/pull/7805
5384
#[test]
5385
fn despawning_entity_updates_table_row() {
5386
#[derive(Component, PartialEq, Debug)]
5387
struct Dense(u8);
5388
5389
#[derive(Component)]
5390
#[component(storage = "SparseSet")]
5391
struct Sparse;
5392
5393
let mut world = World::new();
5394
let e1 = world.spawn(Dense(0)).id();
5395
let e2 = world.spawn(Dense(1)).id();
5396
5397
world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
5398
5399
// archetype with [e2, e1]
5400
// table with [e1, e2]
5401
5402
world.entity_mut(e1).despawn();
5403
5404
assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
5405
}
5406
5407
#[test]
5408
fn entity_mut_insert_by_id() {
5409
let mut world = World::new();
5410
let test_component_id = world.register_component::<TestComponent>();
5411
5412
let mut entity = world.spawn_empty();
5413
OwningPtr::make(TestComponent(42), |ptr| {
5414
// SAFETY: `ptr` matches the component id
5415
unsafe { entity.insert_by_id(test_component_id, ptr) };
5416
});
5417
5418
let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();
5419
5420
assert_eq!(components, vec![&TestComponent(42)]);
5421
5422
// Compare with `insert_bundle_by_id`
5423
5424
let mut entity = world.spawn_empty();
5425
OwningPtr::make(TestComponent(84), |ptr| {
5426
// SAFETY: `ptr` matches the component id
5427
unsafe { entity.insert_by_ids(&[test_component_id], vec![ptr].into_iter()) };
5428
});
5429
5430
let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();
5431
5432
assert_eq!(components, vec![&TestComponent(42), &TestComponent(84)]);
5433
}
5434
5435
#[test]
5436
fn entity_mut_insert_bundle_by_id() {
5437
let mut world = World::new();
5438
let test_component_id = world.register_component::<TestComponent>();
5439
let test_component_2_id = world.register_component::<TestComponent2>();
5440
5441
let component_ids = [test_component_id, test_component_2_id];
5442
let test_component_value = TestComponent(42);
5443
let test_component_2_value = TestComponent2(84);
5444
5445
let mut entity = world.spawn_empty();
5446
OwningPtr::make(test_component_value, |ptr1| {
5447
OwningPtr::make(test_component_2_value, |ptr2| {
5448
// SAFETY: `ptr1` and `ptr2` match the component ids
5449
unsafe { entity.insert_by_ids(&component_ids, vec![ptr1, ptr2].into_iter()) };
5450
});
5451
});
5452
5453
let dynamic_components: Vec<_> = world
5454
.query::<(&TestComponent, &TestComponent2)>()
5455
.iter(&world)
5456
.collect();
5457
5458
assert_eq!(
5459
dynamic_components,
5460
vec![(&TestComponent(42), &TestComponent2(84))]
5461
);
5462
5463
// Compare with `World` generated using static type equivalents
5464
let mut static_world = World::new();
5465
5466
static_world.spawn((test_component_value, test_component_2_value));
5467
let static_components: Vec<_> = static_world
5468
.query::<(&TestComponent, &TestComponent2)>()
5469
.iter(&static_world)
5470
.collect();
5471
5472
assert_eq!(dynamic_components, static_components);
5473
}
5474
5475
#[test]
5476
fn entity_mut_remove_by_id() {
5477
let mut world = World::new();
5478
let test_component_id = world.register_component::<TestComponent>();
5479
5480
let mut entity = world.spawn(TestComponent(42));
5481
entity.remove_by_id(test_component_id);
5482
5483
let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();
5484
5485
assert_eq!(components, vec![] as Vec<&TestComponent>);
5486
5487
// remove non-existent component does not panic
5488
world.spawn_empty().remove_by_id(test_component_id);
5489
}
5490
5491
/// Tests that components can be accessed through an `EntityRefExcept`.
5492
#[test]
5493
fn entity_ref_except() {
5494
let mut world = World::new();
5495
world.register_component::<TestComponent>();
5496
world.register_component::<TestComponent2>();
5497
5498
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5499
5500
let mut query = world.query::<EntityRefExcept<TestComponent>>();
5501
5502
let mut found = false;
5503
for entity_ref in query.iter_mut(&mut world) {
5504
found = true;
5505
assert!(entity_ref.get::<TestComponent>().is_none());
5506
assert!(entity_ref.get_ref::<TestComponent>().is_none());
5507
assert!(matches!(
5508
entity_ref.get::<TestComponent2>(),
5509
Some(TestComponent2(0))
5510
));
5511
}
5512
5513
assert!(found);
5514
}
5515
5516
// Test that a single query can't both contain a mutable reference to a
5517
// component C and an `EntityRefExcept` that doesn't include C among its
5518
// exclusions.
5519
#[test]
5520
#[should_panic]
5521
fn entity_ref_except_conflicts_with_self() {
5522
let mut world = World::new();
5523
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5524
5525
// This should panic, because we have a mutable borrow on
5526
// `TestComponent` but have a simultaneous indirect immutable borrow on
5527
// that component via `EntityRefExcept`.
5528
world.run_system_once(system).unwrap();
5529
5530
fn system(_: Query<(&mut TestComponent, EntityRefExcept<TestComponent2>)>) {}
5531
}
5532
5533
// Test that an `EntityRefExcept` that doesn't include a component C among
5534
// its exclusions can't coexist with a mutable query for that component.
5535
#[test]
5536
#[should_panic]
5537
fn entity_ref_except_conflicts_with_other() {
5538
let mut world = World::new();
5539
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5540
5541
// This should panic, because we have a mutable borrow on
5542
// `TestComponent` but have a simultaneous indirect immutable borrow on
5543
// that component via `EntityRefExcept`.
5544
world.run_system_once(system).unwrap();
5545
5546
fn system(_: Query<&mut TestComponent>, _: Query<EntityRefExcept<TestComponent2>>) {}
5547
}
5548
5549
// Test that an `EntityRefExcept` with an exception for some component C can
5550
// coexist with a query for that component C.
5551
#[test]
5552
fn entity_ref_except_doesnt_conflict() {
5553
let mut world = World::new();
5554
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5555
5556
world.run_system_once(system).unwrap();
5557
5558
fn system(_: Query<&mut TestComponent>, query: Query<EntityRefExcept<TestComponent>>) {
5559
for entity_ref in query.iter() {
5560
assert!(matches!(
5561
entity_ref.get::<TestComponent2>(),
5562
Some(TestComponent2(0))
5563
));
5564
}
5565
}
5566
}
5567
5568
/// Tests that components can be mutably accessed through an
5569
/// `EntityMutExcept`.
5570
#[test]
5571
fn entity_mut_except() {
5572
let mut world = World::new();
5573
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5574
5575
let mut query = world.query::<EntityMutExcept<TestComponent>>();
5576
5577
let mut found = false;
5578
for mut entity_mut in query.iter_mut(&mut world) {
5579
found = true;
5580
assert!(entity_mut.get::<TestComponent>().is_none());
5581
assert!(entity_mut.get_ref::<TestComponent>().is_none());
5582
assert!(entity_mut.get_mut::<TestComponent>().is_none());
5583
assert!(matches!(
5584
entity_mut.get::<TestComponent2>(),
5585
Some(TestComponent2(0))
5586
));
5587
}
5588
5589
assert!(found);
5590
}
5591
5592
// Test that a single query can't both contain a mutable reference to a
5593
// component C and an `EntityMutExcept` that doesn't include C among its
5594
// exclusions.
5595
#[test]
5596
#[should_panic]
5597
fn entity_mut_except_conflicts_with_self() {
5598
let mut world = World::new();
5599
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5600
5601
// This should panic, because we have a mutable borrow on
5602
// `TestComponent` but have a simultaneous indirect immutable borrow on
5603
// that component via `EntityRefExcept`.
5604
world.run_system_once(system).unwrap();
5605
5606
fn system(_: Query<(&mut TestComponent, EntityMutExcept<TestComponent2>)>) {}
5607
}
5608
5609
// Test that an `EntityMutExcept` that doesn't include a component C among
5610
// its exclusions can't coexist with a query for that component.
5611
#[test]
5612
#[should_panic]
5613
fn entity_mut_except_conflicts_with_other() {
5614
let mut world = World::new();
5615
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5616
5617
// This should panic, because we have a mutable borrow on
5618
// `TestComponent` but have a simultaneous indirect immutable borrow on
5619
// that component via `EntityRefExcept`.
5620
world.run_system_once(system).unwrap();
5621
5622
fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent2>>) {
5623
for mut entity_mut in query.iter_mut() {
5624
assert!(entity_mut
5625
.get_mut::<TestComponent2>()
5626
.is_some_and(|component| component.0 == 0));
5627
}
5628
}
5629
}
5630
5631
// Test that an `EntityMutExcept` with an exception for some component C can
5632
// coexist with a query for that component C.
5633
#[test]
5634
fn entity_mut_except_doesnt_conflict() {
5635
let mut world = World::new();
5636
world.spawn(TestComponent(0)).insert(TestComponent2(0));
5637
5638
world.run_system_once(system).unwrap();
5639
5640
fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent>>) {
5641
for mut entity_mut in query.iter_mut() {
5642
assert!(entity_mut
5643
.get_mut::<TestComponent2>()
5644
.is_some_and(|component| component.0 == 0));
5645
}
5646
}
5647
}
5648
5649
#[test]
5650
fn entity_mut_except_registers_components() {
5651
// Checks for a bug where `EntityMutExcept` would not register the component and
5652
// would therefore not include an exception, causing it to conflict with the later query.
5653
fn system1(_query: Query<EntityMutExcept<TestComponent>>, _: Query<&mut TestComponent>) {}
5654
let mut world = World::new();
5655
world.run_system_once(system1).unwrap();
5656
5657
fn system2(_: Query<&mut TestComponent>, _query: Query<EntityMutExcept<TestComponent>>) {}
5658
let mut world = World::new();
5659
world.run_system_once(system2).unwrap();
5660
}
5661
5662
#[derive(Component)]
5663
struct A;
5664
5665
#[test]
5666
fn disjoint_access() {
5667
fn disjoint_readonly(_: Query<EntityMut, With<A>>, _: Query<EntityRef, Without<A>>) {}
5668
5669
fn disjoint_mutable(_: Query<EntityMut, With<A>>, _: Query<EntityMut, Without<A>>) {}
5670
5671
assert_is_system(disjoint_readonly);
5672
assert_is_system(disjoint_mutable);
5673
}
5674
5675
#[test]
5676
fn ref_compatible() {
5677
fn borrow_system(_: Query<(EntityRef, &A)>, _: Query<&A>) {}
5678
5679
assert_is_system(borrow_system);
5680
}
5681
5682
#[test]
5683
fn ref_compatible_with_resource() {
5684
fn borrow_system(_: Query<EntityRef>, _: Res<R>) {}
5685
5686
assert_is_system(borrow_system);
5687
}
5688
5689
#[test]
5690
fn ref_compatible_with_resource_mut() {
5691
fn borrow_system(_: Query<EntityRef>, _: ResMut<R>) {}
5692
5693
assert_is_system(borrow_system);
5694
}
5695
5696
#[test]
5697
#[should_panic]
5698
fn ref_incompatible_with_mutable_component() {
5699
fn incompatible_system(_: Query<(EntityRef, &mut A)>) {}
5700
5701
assert_is_system(incompatible_system);
5702
}
5703
5704
#[test]
5705
#[should_panic]
5706
fn ref_incompatible_with_mutable_query() {
5707
fn incompatible_system(_: Query<EntityRef>, _: Query<&mut A>) {}
5708
5709
assert_is_system(incompatible_system);
5710
}
5711
5712
#[test]
5713
fn mut_compatible_with_entity() {
5714
fn borrow_mut_system(_: Query<(Entity, EntityMut)>) {}
5715
5716
assert_is_system(borrow_mut_system);
5717
}
5718
5719
#[test]
5720
fn mut_compatible_with_resource() {
5721
fn borrow_mut_system(_: Res<R>, _: Query<EntityMut>) {}
5722
5723
assert_is_system(borrow_mut_system);
5724
}
5725
5726
#[test]
5727
fn mut_compatible_with_resource_mut() {
5728
fn borrow_mut_system(_: ResMut<R>, _: Query<EntityMut>) {}
5729
5730
assert_is_system(borrow_mut_system);
5731
}
5732
5733
#[test]
5734
#[should_panic]
5735
fn mut_incompatible_with_read_only_component() {
5736
fn incompatible_system(_: Query<(EntityMut, &A)>) {}
5737
5738
assert_is_system(incompatible_system);
5739
}
5740
5741
#[test]
5742
#[should_panic]
5743
fn mut_incompatible_with_mutable_component() {
5744
fn incompatible_system(_: Query<(EntityMut, &mut A)>) {}
5745
5746
assert_is_system(incompatible_system);
5747
}
5748
5749
#[test]
5750
#[should_panic]
5751
fn mut_incompatible_with_read_only_query() {
5752
fn incompatible_system(_: Query<EntityMut>, _: Query<&A>) {}
5753
5754
assert_is_system(incompatible_system);
5755
}
5756
5757
#[test]
5758
#[should_panic]
5759
fn mut_incompatible_with_mutable_query() {
5760
fn incompatible_system(_: Query<EntityMut>, _: Query<&mut A>) {}
5761
5762
assert_is_system(incompatible_system);
5763
}
5764
5765
#[test]
5766
fn filtered_entity_ref_normal() {
5767
let mut world = World::new();
5768
let a_id = world.register_component::<A>();
5769
5770
let e: FilteredEntityRef = world.spawn(A).into();
5771
5772
assert!(e.get::<A>().is_some());
5773
assert!(e.get_ref::<A>().is_some());
5774
assert!(e.get_change_ticks::<A>().is_some());
5775
assert!(e.get_by_id(a_id).is_some());
5776
assert!(e.get_change_ticks_by_id(a_id).is_some());
5777
}
5778
5779
#[test]
5780
fn filtered_entity_ref_missing() {
5781
let mut world = World::new();
5782
let a_id = world.register_component::<A>();
5783
5784
let e: FilteredEntityRef = world.spawn(()).into();
5785
5786
assert!(e.get::<A>().is_none());
5787
assert!(e.get_ref::<A>().is_none());
5788
assert!(e.get_change_ticks::<A>().is_none());
5789
assert!(e.get_by_id(a_id).is_none());
5790
assert!(e.get_change_ticks_by_id(a_id).is_none());
5791
}
5792
5793
#[test]
5794
fn filtered_entity_mut_normal() {
5795
let mut world = World::new();
5796
let a_id = world.register_component::<A>();
5797
5798
let mut e: FilteredEntityMut = world.spawn(A).into();
5799
5800
assert!(e.get::<A>().is_some());
5801
assert!(e.get_ref::<A>().is_some());
5802
assert!(e.get_mut::<A>().is_some());
5803
assert!(e.get_change_ticks::<A>().is_some());
5804
assert!(e.get_by_id(a_id).is_some());
5805
assert!(e.get_mut_by_id(a_id).is_some());
5806
assert!(e.get_change_ticks_by_id(a_id).is_some());
5807
}
5808
5809
#[test]
5810
fn filtered_entity_mut_missing() {
5811
let mut world = World::new();
5812
let a_id = world.register_component::<A>();
5813
5814
let mut e: FilteredEntityMut = world.spawn(()).into();
5815
5816
assert!(e.get::<A>().is_none());
5817
assert!(e.get_ref::<A>().is_none());
5818
assert!(e.get_mut::<A>().is_none());
5819
assert!(e.get_change_ticks::<A>().is_none());
5820
assert!(e.get_by_id(a_id).is_none());
5821
assert!(e.get_mut_by_id(a_id).is_none());
5822
assert!(e.get_change_ticks_by_id(a_id).is_none());
5823
}
5824
5825
#[derive(Component, PartialEq, Eq, Debug)]
5826
struct X(usize);
5827
5828
#[derive(Component, PartialEq, Eq, Debug)]
5829
struct Y(usize);
5830
5831
#[test]
5832
fn get_components() {
5833
let mut world = World::default();
5834
let e1 = world.spawn((X(7), Y(10))).id();
5835
let e2 = world.spawn(X(8)).id();
5836
let e3 = world.spawn_empty().id();
5837
5838
assert_eq!(
5839
Some((&X(7), &Y(10))),
5840
world.entity(e1).get_components::<(&X, &Y)>()
5841
);
5842
assert_eq!(None, world.entity(e2).get_components::<(&X, &Y)>());
5843
assert_eq!(None, world.entity(e3).get_components::<(&X, &Y)>());
5844
}
5845
5846
#[test]
5847
fn get_by_id_array() {
5848
let mut world = World::default();
5849
let e1 = world.spawn((X(7), Y(10))).id();
5850
let e2 = world.spawn(X(8)).id();
5851
let e3 = world.spawn_empty().id();
5852
5853
let x_id = world.register_component::<X>();
5854
let y_id = world.register_component::<Y>();
5855
5856
assert_eq!(
5857
Ok((&X(7), &Y(10))),
5858
world
5859
.entity(e1)
5860
.get_by_id([x_id, y_id])
5861
.map(|[x_ptr, y_ptr]| {
5862
// SAFETY: components match the id they were fetched with
5863
(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
5864
})
5865
);
5866
assert_eq!(
5867
Err(EntityComponentError::MissingComponent(y_id)),
5868
world
5869
.entity(e2)
5870
.get_by_id([x_id, y_id])
5871
.map(|[x_ptr, y_ptr]| {
5872
// SAFETY: components match the id they were fetched with
5873
(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
5874
})
5875
);
5876
assert_eq!(
5877
Err(EntityComponentError::MissingComponent(x_id)),
5878
world
5879
.entity(e3)
5880
.get_by_id([x_id, y_id])
5881
.map(|[x_ptr, y_ptr]| {
5882
// SAFETY: components match the id they were fetched with
5883
(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
5884
})
5885
);
5886
}
5887
5888
#[test]
5889
fn get_by_id_vec() {
5890
let mut world = World::default();
5891
let e1 = world.spawn((X(7), Y(10))).id();
5892
let e2 = world.spawn(X(8)).id();
5893
let e3 = world.spawn_empty().id();
5894
5895
let x_id = world.register_component::<X>();
5896
let y_id = world.register_component::<Y>();
5897
5898
assert_eq!(
5899
Ok((&X(7), &Y(10))),
5900
world
5901
.entity(e1)
5902
.get_by_id(&[x_id, y_id] as &[ComponentId])
5903
.map(|ptrs| {
5904
let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {
5905
panic!("get_by_id(slice) didn't return 2 elements")
5906
};
5907
5908
// SAFETY: components match the id they were fetched with
5909
(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
5910
})
5911
);
5912
assert_eq!(
5913
Err(EntityComponentError::MissingComponent(y_id)),
5914
world
5915
.entity(e2)
5916
.get_by_id(&[x_id, y_id] as &[ComponentId])
5917
.map(|ptrs| {
5918
let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {
5919
panic!("get_by_id(slice) didn't return 2 elements")
5920
};
5921
5922
// SAFETY: components match the id they were fetched with
5923
(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
5924
})
5925
);
5926
assert_eq!(
5927
Err(EntityComponentError::MissingComponent(x_id)),
5928
world
5929
.entity(e3)
5930
.get_by_id(&[x_id, y_id] as &[ComponentId])
5931
.map(|ptrs| {
5932
let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {
5933
panic!("get_by_id(slice) didn't return 2 elements")
5934
};
5935
5936
// SAFETY: components match the id they were fetched with
5937
(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
5938
})
5939
);
5940
}
5941
5942
#[test]
5943
fn get_mut_by_id_array() {
5944
let mut world = World::default();
5945
let e1 = world.spawn((X(7), Y(10))).id();
5946
let e2 = world.spawn(X(8)).id();
5947
let e3 = world.spawn_empty().id();
5948
5949
let x_id = world.register_component::<X>();
5950
let y_id = world.register_component::<Y>();
5951
5952
assert_eq!(
5953
Ok((&mut X(7), &mut Y(10))),
5954
world
5955
.entity_mut(e1)
5956
.get_mut_by_id([x_id, y_id])
5957
.map(|[x_ptr, y_ptr]| {
5958
// SAFETY: components match the id they were fetched with
5959
(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
5960
y_ptr.into_inner().deref_mut::<Y>()
5961
})
5962
})
5963
);
5964
assert_eq!(
5965
Err(EntityComponentError::MissingComponent(y_id)),
5966
world
5967
.entity_mut(e2)
5968
.get_mut_by_id([x_id, y_id])
5969
.map(|[x_ptr, y_ptr]| {
5970
// SAFETY: components match the id they were fetched with
5971
(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
5972
y_ptr.into_inner().deref_mut::<Y>()
5973
})
5974
})
5975
);
5976
assert_eq!(
5977
Err(EntityComponentError::MissingComponent(x_id)),
5978
world
5979
.entity_mut(e3)
5980
.get_mut_by_id([x_id, y_id])
5981
.map(|[x_ptr, y_ptr]| {
5982
// SAFETY: components match the id they were fetched with
5983
(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
5984
y_ptr.into_inner().deref_mut::<Y>()
5985
})
5986
})
5987
);
5988
5989
assert_eq!(
5990
Err(EntityComponentError::AliasedMutability(x_id)),
5991
world
5992
.entity_mut(e1)
5993
.get_mut_by_id([x_id, x_id])
5994
.map(|_| { unreachable!() })
5995
);
5996
assert_eq!(
5997
Err(EntityComponentError::AliasedMutability(x_id)),
5998
world
5999
.entity_mut(e3)
6000
.get_mut_by_id([x_id, x_id])
6001
.map(|_| { unreachable!() })
6002
);
6003
}
6004
6005
#[test]
6006
fn get_mut_by_id_vec() {
6007
let mut world = World::default();
6008
let e1 = world.spawn((X(7), Y(10))).id();
6009
let e2 = world.spawn(X(8)).id();
6010
let e3 = world.spawn_empty().id();
6011
6012
let x_id = world.register_component::<X>();
6013
let y_id = world.register_component::<Y>();
6014
6015
assert_eq!(
6016
Ok((&mut X(7), &mut Y(10))),
6017
world
6018
.entity_mut(e1)
6019
.get_mut_by_id(&[x_id, y_id] as &[ComponentId])
6020
.map(|ptrs| {
6021
let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {
6022
panic!("get_mut_by_id(slice) didn't return 2 elements")
6023
};
6024
6025
// SAFETY: components match the id they were fetched with
6026
(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
6027
y_ptr.into_inner().deref_mut::<Y>()
6028
})
6029
})
6030
);
6031
assert_eq!(
6032
Err(EntityComponentError::MissingComponent(y_id)),
6033
world
6034
.entity_mut(e2)
6035
.get_mut_by_id(&[x_id, y_id] as &[ComponentId])
6036
.map(|ptrs| {
6037
let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {
6038
panic!("get_mut_by_id(slice) didn't return 2 elements")
6039
};
6040
6041
// SAFETY: components match the id they were fetched with
6042
(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
6043
y_ptr.into_inner().deref_mut::<Y>()
6044
})
6045
})
6046
);
6047
assert_eq!(
6048
Err(EntityComponentError::MissingComponent(x_id)),
6049
world
6050
.entity_mut(e3)
6051
.get_mut_by_id(&[x_id, y_id] as &[ComponentId])
6052
.map(|ptrs| {
6053
let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {
6054
panic!("get_mut_by_id(slice) didn't return 2 elements")
6055
};
6056
6057
// SAFETY: components match the id they were fetched with
6058
(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
6059
y_ptr.into_inner().deref_mut::<Y>()
6060
})
6061
})
6062
);
6063
6064
assert_eq!(
6065
Err(EntityComponentError::AliasedMutability(x_id)),
6066
world
6067
.entity_mut(e1)
6068
.get_mut_by_id(&[x_id, x_id])
6069
.map(|_| { unreachable!() })
6070
);
6071
assert_eq!(
6072
Err(EntityComponentError::AliasedMutability(x_id)),
6073
world
6074
.entity_mut(e3)
6075
.get_mut_by_id(&[x_id, x_id])
6076
.map(|_| { unreachable!() })
6077
);
6078
}
6079
6080
#[test]
6081
fn get_mut_by_id_unchecked() {
6082
let mut world = World::default();
6083
let e1 = world.spawn((X(7), Y(10))).id();
6084
let x_id = world.register_component::<X>();
6085
let y_id = world.register_component::<Y>();
6086
6087
let e1_mut = &world.get_entity_mut([e1]).unwrap()[0];
6088
// SAFETY: The entity e1 contains component X.
6089
let x_ptr = unsafe { e1_mut.get_mut_by_id_unchecked(x_id) }.unwrap();
6090
// SAFETY: The entity e1 contains component Y, with components X and Y being mutually independent.
6091
let y_ptr = unsafe { e1_mut.get_mut_by_id_unchecked(y_id) }.unwrap();
6092
6093
// SAFETY: components match the id they were fetched with
6094
let x_component = unsafe { x_ptr.into_inner().deref_mut::<X>() };
6095
x_component.0 += 1;
6096
// SAFETY: components match the id they were fetched with
6097
let y_component = unsafe { y_ptr.into_inner().deref_mut::<Y>() };
6098
y_component.0 -= 1;
6099
6100
assert_eq!((&mut X(8), &mut Y(9)), (x_component, y_component));
6101
}
6102
6103
#[derive(EntityEvent)]
6104
struct TestEvent(Entity);
6105
6106
#[test]
6107
fn adding_observer_updates_location() {
6108
let mut world = World::new();
6109
let entity = world
6110
.spawn_empty()
6111
.observe(|event: On<TestEvent>, mut commands: Commands| {
6112
commands
6113
.entity(event.event_target())
6114
.insert(TestComponent(0));
6115
})
6116
.id();
6117
6118
// this should not be needed, but is currently required to tease out the bug
6119
world.flush();
6120
6121
let mut a = world.entity_mut(entity);
6122
// SAFETY: this _intentionally_ doesn't update the location, to ensure that we're actually testing
6123
// that observe() updates location
6124
unsafe { a.world_mut().trigger(TestEvent(entity)) }
6125
a.observe(|_: On<TestEvent>| {}); // this flushes commands implicitly by spawning
6126
let location = a.location();
6127
assert_eq!(world.entities().get(entity), Some(location));
6128
}
6129
6130
#[test]
6131
#[should_panic]
6132
fn location_on_despawned_entity_panics() {
6133
let mut world = World::new();
6134
world.add_observer(|add: On<Add, TestComponent>, mut commands: Commands| {
6135
commands.entity(add.entity).despawn();
6136
});
6137
let entity = world.spawn_empty().id();
6138
let mut a = world.entity_mut(entity);
6139
a.insert(TestComponent(0));
6140
a.location();
6141
}
6142
6143
#[derive(Resource)]
6144
struct TestFlush(usize);
6145
6146
fn count_flush(world: &mut World) {
6147
world.resource_mut::<TestFlush>().0 += 1;
6148
}
6149
6150
#[test]
6151
fn archetype_modifications_trigger_flush() {
6152
let mut world = World::new();
6153
world.insert_resource(TestFlush(0));
6154
world.add_observer(|_: On<Add, TestComponent>, mut commands: Commands| {
6155
commands.queue(count_flush);
6156
});
6157
world.add_observer(|_: On<Remove, TestComponent>, mut commands: Commands| {
6158
commands.queue(count_flush);
6159
});
6160
world.commands().queue(count_flush);
6161
let entity = world.spawn_empty().id();
6162
assert_eq!(world.resource::<TestFlush>().0, 1);
6163
world.commands().queue(count_flush);
6164
world.flush_commands();
6165
let mut a = world.entity_mut(entity);
6166
assert_eq!(a.world().resource::<TestFlush>().0, 2);
6167
a.insert(TestComponent(0));
6168
assert_eq!(a.world().resource::<TestFlush>().0, 3);
6169
a.remove::<TestComponent>();
6170
assert_eq!(a.world().resource::<TestFlush>().0, 4);
6171
a.insert(TestComponent(0));
6172
assert_eq!(a.world().resource::<TestFlush>().0, 5);
6173
let _ = a.take::<TestComponent>();
6174
assert_eq!(a.world().resource::<TestFlush>().0, 6);
6175
a.insert(TestComponent(0));
6176
assert_eq!(a.world().resource::<TestFlush>().0, 7);
6177
a.retain::<()>();
6178
assert_eq!(a.world().resource::<TestFlush>().0, 8);
6179
a.insert(TestComponent(0));
6180
assert_eq!(a.world().resource::<TestFlush>().0, 9);
6181
a.clear();
6182
assert_eq!(a.world().resource::<TestFlush>().0, 10);
6183
a.insert(TestComponent(0));
6184
assert_eq!(a.world().resource::<TestFlush>().0, 11);
6185
a.despawn();
6186
assert_eq!(world.resource::<TestFlush>().0, 12);
6187
}
6188
6189
#[derive(Resource)]
6190
struct TestVec(Vec<&'static str>);
6191
6192
#[derive(Component)]
6193
#[component(on_add = ord_a_hook_on_add, on_insert = ord_a_hook_on_insert, on_replace = ord_a_hook_on_replace, on_remove = ord_a_hook_on_remove)]
6194
struct OrdA;
6195
6196
fn ord_a_hook_on_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
6197
world.resource_mut::<TestVec>().0.push("OrdA hook on_add");
6198
world.commands().entity(entity).insert(OrdB);
6199
}
6200
6201
fn ord_a_hook_on_insert(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
6202
world
6203
.resource_mut::<TestVec>()
6204
.0
6205
.push("OrdA hook on_insert");
6206
world.commands().entity(entity).remove::<OrdA>();
6207
world.commands().entity(entity).remove::<OrdB>();
6208
}
6209
6210
fn ord_a_hook_on_replace(mut world: DeferredWorld, _: HookContext) {
6211
world
6212
.resource_mut::<TestVec>()
6213
.0
6214
.push("OrdA hook on_replace");
6215
}
6216
6217
fn ord_a_hook_on_remove(mut world: DeferredWorld, _: HookContext) {
6218
world
6219
.resource_mut::<TestVec>()
6220
.0
6221
.push("OrdA hook on_remove");
6222
}
6223
6224
fn ord_a_observer_on_add(_event: On<Add, OrdA>, mut res: ResMut<TestVec>) {
6225
res.0.push("OrdA observer on_add");
6226
}
6227
6228
fn ord_a_observer_on_insert(_event: On<Insert, OrdA>, mut res: ResMut<TestVec>) {
6229
res.0.push("OrdA observer on_insert");
6230
}
6231
6232
fn ord_a_observer_on_replace(_event: On<Replace, OrdA>, mut res: ResMut<TestVec>) {
6233
res.0.push("OrdA observer on_replace");
6234
}
6235
6236
fn ord_a_observer_on_remove(_event: On<Remove, OrdA>, mut res: ResMut<TestVec>) {
6237
res.0.push("OrdA observer on_remove");
6238
}
6239
6240
#[derive(Component)]
6241
#[component(on_add = ord_b_hook_on_add, on_insert = ord_b_hook_on_insert, on_replace = ord_b_hook_on_replace, on_remove = ord_b_hook_on_remove)]
6242
struct OrdB;
6243
6244
fn ord_b_hook_on_add(mut world: DeferredWorld, _: HookContext) {
6245
world.resource_mut::<TestVec>().0.push("OrdB hook on_add");
6246
world.commands().queue(|world: &mut World| {
6247
world
6248
.resource_mut::<TestVec>()
6249
.0
6250
.push("OrdB command on_add");
6251
});
6252
}
6253
6254
fn ord_b_hook_on_insert(mut world: DeferredWorld, _: HookContext) {
6255
world
6256
.resource_mut::<TestVec>()
6257
.0
6258
.push("OrdB hook on_insert");
6259
}
6260
6261
fn ord_b_hook_on_replace(mut world: DeferredWorld, _: HookContext) {
6262
world
6263
.resource_mut::<TestVec>()
6264
.0
6265
.push("OrdB hook on_replace");
6266
}
6267
6268
fn ord_b_hook_on_remove(mut world: DeferredWorld, _: HookContext) {
6269
world
6270
.resource_mut::<TestVec>()
6271
.0
6272
.push("OrdB hook on_remove");
6273
}
6274
6275
fn ord_b_observer_on_add(_event: On<Add, OrdB>, mut res: ResMut<TestVec>) {
6276
res.0.push("OrdB observer on_add");
6277
}
6278
6279
fn ord_b_observer_on_insert(_event: On<Insert, OrdB>, mut res: ResMut<TestVec>) {
6280
res.0.push("OrdB observer on_insert");
6281
}
6282
6283
fn ord_b_observer_on_replace(_event: On<Replace, OrdB>, mut res: ResMut<TestVec>) {
6284
res.0.push("OrdB observer on_replace");
6285
}
6286
6287
fn ord_b_observer_on_remove(_event: On<Remove, OrdB>, mut res: ResMut<TestVec>) {
6288
res.0.push("OrdB observer on_remove");
6289
}
6290
6291
#[test]
6292
fn command_ordering_is_correct() {
6293
let mut world = World::new();
6294
world.insert_resource(TestVec(Vec::new()));
6295
world.add_observer(ord_a_observer_on_add);
6296
world.add_observer(ord_a_observer_on_insert);
6297
world.add_observer(ord_a_observer_on_replace);
6298
world.add_observer(ord_a_observer_on_remove);
6299
world.add_observer(ord_b_observer_on_add);
6300
world.add_observer(ord_b_observer_on_insert);
6301
world.add_observer(ord_b_observer_on_replace);
6302
world.add_observer(ord_b_observer_on_remove);
6303
let _entity = world.spawn(OrdA).id();
6304
let expected = [
6305
"OrdA hook on_add", // adds command to insert OrdB
6306
"OrdA observer on_add",
6307
"OrdA hook on_insert", // adds command to despawn entity
6308
"OrdA observer on_insert",
6309
"OrdB hook on_add", // adds command to just add to this log
6310
"OrdB observer on_add",
6311
"OrdB hook on_insert",
6312
"OrdB observer on_insert",
6313
"OrdB command on_add", // command added by OrdB hook on_add, needs to run before despawn command
6314
"OrdA observer on_replace", // start of despawn
6315
"OrdA hook on_replace",
6316
"OrdA observer on_remove",
6317
"OrdA hook on_remove",
6318
"OrdB observer on_replace",
6319
"OrdB hook on_replace",
6320
"OrdB observer on_remove",
6321
"OrdB hook on_remove",
6322
];
6323
world.flush();
6324
assert_eq!(world.resource_mut::<TestVec>().0.as_slice(), &expected[..]);
6325
}
6326
6327
#[test]
6328
fn entity_world_mut_clone_and_move_components() {
6329
#[derive(Component, Clone, PartialEq, Debug)]
6330
struct A;
6331
6332
#[derive(Component, Clone, PartialEq, Debug)]
6333
struct B;
6334
6335
#[derive(Component, Clone, PartialEq, Debug)]
6336
struct C(u32);
6337
6338
let mut world = World::new();
6339
let entity_a = world.spawn((A, B, C(5))).id();
6340
let entity_b = world.spawn((A, C(4))).id();
6341
6342
world.entity_mut(entity_a).clone_components::<B>(entity_b);
6343
assert_eq!(world.entity(entity_a).get::<B>(), Some(&B));
6344
assert_eq!(world.entity(entity_b).get::<B>(), Some(&B));
6345
6346
world.entity_mut(entity_a).move_components::<C>(entity_b);
6347
assert_eq!(world.entity(entity_a).get::<C>(), None);
6348
assert_eq!(world.entity(entity_b).get::<C>(), Some(&C(5)));
6349
6350
assert_eq!(world.entity(entity_a).get::<A>(), Some(&A));
6351
assert_eq!(world.entity(entity_b).get::<A>(), Some(&A));
6352
}
6353
6354
#[test]
6355
fn entity_world_mut_clone_with_move_and_require() {
6356
#[derive(Component, Clone, PartialEq, Debug)]
6357
#[require(B(3))]
6358
struct A;
6359
6360
#[derive(Component, Clone, PartialEq, Debug, Default)]
6361
#[require(C(3))]
6362
struct B(u32);
6363
6364
#[derive(Component, Clone, PartialEq, Debug, Default)]
6365
#[require(D)]
6366
struct C(u32);
6367
6368
#[derive(Component, Clone, PartialEq, Debug, Default)]
6369
struct D;
6370
6371
let mut world = World::new();
6372
let entity_a = world.spawn((A, B(5))).id();
6373
let entity_b = world.spawn_empty().id();
6374
6375
world
6376
.entity_mut(entity_a)
6377
.clone_with_opt_in(entity_b, |builder| {
6378
builder
6379
.move_components(true)
6380
.allow::<C>()
6381
.without_required_components(|builder| {
6382
builder.allow::<A>();
6383
});
6384
});
6385
6386
assert_eq!(world.entity(entity_a).get::<A>(), None);
6387
assert_eq!(world.entity(entity_b).get::<A>(), Some(&A));
6388
6389
assert_eq!(world.entity(entity_a).get::<B>(), Some(&B(5)));
6390
assert_eq!(world.entity(entity_b).get::<B>(), Some(&B(3)));
6391
6392
assert_eq!(world.entity(entity_a).get::<C>(), None);
6393
assert_eq!(world.entity(entity_b).get::<C>(), Some(&C(3)));
6394
6395
assert_eq!(world.entity(entity_a).get::<D>(), None);
6396
assert_eq!(world.entity(entity_b).get::<D>(), Some(&D));
6397
}
6398
6399
#[test]
6400
fn update_despawned_by_after_observers() {
6401
let mut world = World::new();
6402
6403
#[derive(Component)]
6404
#[component(on_remove = get_tracked)]
6405
struct C;
6406
6407
static TRACKED: OnceLock<(MaybeLocation, Tick)> = OnceLock::new();
6408
fn get_tracked(world: DeferredWorld, HookContext { entity, .. }: HookContext) {
6409
TRACKED.get_or_init(|| {
6410
let by = world
6411
.entities
6412
.entity_get_spawned_or_despawned_by(entity)
6413
.map(|l| l.unwrap());
6414
let at = world
6415
.entities
6416
.entity_get_spawn_or_despawn_tick(entity)
6417
.unwrap();
6418
(by, at)
6419
});
6420
}
6421
6422
#[track_caller]
6423
fn caller_spawn(world: &mut World) -> (Entity, MaybeLocation, Tick) {
6424
let caller = MaybeLocation::caller();
6425
(world.spawn(C).id(), caller, world.change_tick())
6426
}
6427
let (entity, spawner, spawn_tick) = caller_spawn(&mut world);
6428
6429
assert_eq!(
6430
spawner,
6431
world
6432
.entities()
6433
.entity_get_spawned_or_despawned_by(entity)
6434
.map(|l| l.unwrap())
6435
);
6436
6437
#[track_caller]
6438
fn caller_despawn(world: &mut World, entity: Entity) -> (MaybeLocation, Tick) {
6439
world.despawn(entity);
6440
(MaybeLocation::caller(), world.change_tick())
6441
}
6442
let (despawner, despawn_tick) = caller_despawn(&mut world, entity);
6443
6444
assert_eq!((spawner, spawn_tick), *TRACKED.get().unwrap());
6445
assert_eq!(
6446
despawner,
6447
world
6448
.entities()
6449
.entity_get_spawned_or_despawned_by(entity)
6450
.map(|l| l.unwrap())
6451
);
6452
assert_eq!(
6453
despawn_tick,
6454
world
6455
.entities()
6456
.entity_get_spawn_or_despawn_tick(entity)
6457
.unwrap()
6458
);
6459
}
6460
6461
#[test]
6462
fn with_component_activates_hooks() {
6463
use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
6464
6465
#[derive(Component, PartialEq, Eq, Debug)]
6466
#[component(immutable)]
6467
struct Foo(bool);
6468
6469
static EXPECTED_VALUE: AtomicBool = AtomicBool::new(false);
6470
6471
static ADD_COUNT: AtomicU8 = AtomicU8::new(0);
6472
static REMOVE_COUNT: AtomicU8 = AtomicU8::new(0);
6473
static REPLACE_COUNT: AtomicU8 = AtomicU8::new(0);
6474
static INSERT_COUNT: AtomicU8 = AtomicU8::new(0);
6475
6476
let mut world = World::default();
6477
6478
world.register_component::<Foo>();
6479
world
6480
.register_component_hooks::<Foo>()
6481
.on_add(|world, context| {
6482
ADD_COUNT.fetch_add(1, Ordering::Relaxed);
6483
6484
assert_eq!(
6485
world.get(context.entity),
6486
Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))
6487
);
6488
})
6489
.on_remove(|world, context| {
6490
REMOVE_COUNT.fetch_add(1, Ordering::Relaxed);
6491
6492
assert_eq!(
6493
world.get(context.entity),
6494
Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))
6495
);
6496
})
6497
.on_replace(|world, context| {
6498
REPLACE_COUNT.fetch_add(1, Ordering::Relaxed);
6499
6500
assert_eq!(
6501
world.get(context.entity),
6502
Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))
6503
);
6504
})
6505
.on_insert(|world, context| {
6506
INSERT_COUNT.fetch_add(1, Ordering::Relaxed);
6507
6508
assert_eq!(
6509
world.get(context.entity),
6510
Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))
6511
);
6512
});
6513
6514
let entity = world.spawn(Foo(false)).id();
6515
6516
assert_eq!(ADD_COUNT.load(Ordering::Relaxed), 1);
6517
assert_eq!(REMOVE_COUNT.load(Ordering::Relaxed), 0);
6518
assert_eq!(REPLACE_COUNT.load(Ordering::Relaxed), 0);
6519
assert_eq!(INSERT_COUNT.load(Ordering::Relaxed), 1);
6520
6521
let mut entity = world.entity_mut(entity);
6522
6523
let archetype_pointer_before = &raw const *entity.archetype();
6524
6525
assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));
6526
6527
entity.modify_component(|foo: &mut Foo| {
6528
foo.0 = true;
6529
EXPECTED_VALUE.store(foo.0, Ordering::Relaxed);
6530
});
6531
6532
let archetype_pointer_after = &raw const *entity.archetype();
6533
6534
assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));
6535
6536
assert_eq!(ADD_COUNT.load(Ordering::Relaxed), 1);
6537
assert_eq!(REMOVE_COUNT.load(Ordering::Relaxed), 0);
6538
assert_eq!(REPLACE_COUNT.load(Ordering::Relaxed), 1);
6539
assert_eq!(INSERT_COUNT.load(Ordering::Relaxed), 2);
6540
6541
assert_eq!(archetype_pointer_before, archetype_pointer_after);
6542
}
6543
6544
#[test]
6545
fn bundle_remove_only_triggers_for_present_components() {
6546
let mut world = World::default();
6547
6548
#[derive(Component)]
6549
struct A;
6550
6551
#[derive(Component)]
6552
struct B;
6553
6554
#[derive(Resource, PartialEq, Eq, Debug)]
6555
struct Tracker {
6556
a: bool,
6557
b: bool,
6558
}
6559
6560
world.insert_resource(Tracker { a: false, b: false });
6561
let entity = world.spawn(A).id();
6562
6563
world.add_observer(|_: On<Remove, A>, mut tracker: ResMut<Tracker>| {
6564
tracker.a = true;
6565
});
6566
world.add_observer(|_: On<Remove, B>, mut tracker: ResMut<Tracker>| {
6567
tracker.b = true;
6568
});
6569
6570
world.entity_mut(entity).remove::<(A, B)>();
6571
6572
assert_eq!(
6573
world.resource::<Tracker>(),
6574
&Tracker {
6575
a: true,
6576
// The entity didn't have a B component, so it should not have been triggered.
6577
b: false,
6578
}
6579
);
6580
}
6581
}
6582
6583