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