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