bevy_ecs/world/entity_ref.rs
1use crate::{
2 archetype::{Archetype, ArchetypeId, Archetypes},
3 bundle::{Bundle, BundleId, BundleInfo, BundleInserter, DynamicBundle, InsertMode},
4 change_detection::MutUntyped,
5 component::{Component, ComponentId, ComponentTicks, Components, StorageType},
6 entity::{Entities, Entity, EntityLocation},
7 event::Event,
8 observer::{Observer, Observers},
9 query::{Access, ReadOnlyQueryData},
10 removal_detection::RemovedComponentEvents,
11 storage::Storages,
12 system::IntoObserverSystem,
13 world::{error::EntityComponentError, DeferredWorld, Mut, World},
14};
15use bevy_ptr::{OwningPtr, Ptr};
16use bevy_utils::{HashMap, HashSet};
17use core::{any::TypeId, marker::PhantomData, mem::MaybeUninit};
18use derive_more::derive::{Display, Error};
19
20use super::{unsafe_world_cell::UnsafeEntityCell, Ref, ON_REMOVE, ON_REPLACE};
21
22/// A read-only reference to a particular [`Entity`] and all of its components.
23///
24/// # Examples
25///
26/// Read-only access disjoint with mutable access.
27///
28/// ```
29/// # use bevy_ecs::prelude::*;
30/// # #[derive(Component)] pub struct A;
31/// # #[derive(Component)] pub struct B;
32/// fn disjoint_system(
33/// query1: Query<&mut A>,
34/// query2: Query<EntityRef, Without<A>>,
35/// ) {
36/// // ...
37/// }
38/// # bevy_ecs::system::assert_is_system(disjoint_system);
39/// ```
40#[derive(Copy, Clone)]
41pub struct EntityRef<'w>(UnsafeEntityCell<'w>);
42
43impl<'w> EntityRef<'w> {
44 /// # Safety
45 /// - `cell` must have permission to read every component of the entity.
46 /// - No mutable accesses to any of the entity's components may exist
47 /// at the same time as the returned [`EntityRef`].
48 #[inline]
49 pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {
50 Self(cell)
51 }
52
53 /// Returns the [ID](Entity) of the current entity.
54 #[inline]
55 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
56 pub fn id(&self) -> Entity {
57 self.0.id()
58 }
59
60 /// Gets metadata indicating the location where the current entity is stored.
61 #[inline]
62 pub fn location(&self) -> EntityLocation {
63 self.0.location()
64 }
65
66 /// Returns the archetype that the current entity belongs to.
67 #[inline]
68 pub fn archetype(&self) -> &Archetype {
69 self.0.archetype()
70 }
71
72 /// Returns `true` if the current entity has a component of type `T`.
73 /// Otherwise, this returns `false`.
74 ///
75 /// ## Notes
76 ///
77 /// If you do not know the concrete type of a component, consider using
78 /// [`Self::contains_id`] or [`Self::contains_type_id`].
79 #[inline]
80 pub fn contains<T: Component>(&self) -> bool {
81 self.contains_type_id(TypeId::of::<T>())
82 }
83
84 /// Returns `true` if the current entity has a component identified by `component_id`.
85 /// Otherwise, this returns false.
86 ///
87 /// ## Notes
88 ///
89 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
90 /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
91 /// [`Self::contains_type_id`].
92 #[inline]
93 pub fn contains_id(&self, component_id: ComponentId) -> bool {
94 self.0.contains_id(component_id)
95 }
96
97 /// Returns `true` if the current entity has a component with the type identified by `type_id`.
98 /// Otherwise, this returns false.
99 ///
100 /// ## Notes
101 ///
102 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
103 /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
104 #[inline]
105 pub fn contains_type_id(&self, type_id: TypeId) -> bool {
106 self.0.contains_type_id(type_id)
107 }
108
109 /// Gets access to the component of type `T` for the current entity.
110 /// Returns `None` if the entity does not have a component of type `T`.
111 #[inline]
112 pub fn get<T: Component>(&self) -> Option<&'w T> {
113 // SAFETY: We have read-only access to all components of this entity.
114 unsafe { self.0.get::<T>() }
115 }
116
117 /// Gets access to the component of type `T` for the current entity,
118 /// including change detection information as a [`Ref`].
119 ///
120 /// Returns `None` if the entity does not have a component of type `T`.
121 #[inline]
122 pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {
123 // SAFETY: We have read-only access to all components of this entity.
124 unsafe { self.0.get_ref::<T>() }
125 }
126
127 /// Retrieves the change ticks for the given component. This can be useful for implementing change
128 /// detection in custom runtimes.
129 #[inline]
130 pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
131 // SAFETY: We have read-only access to all components of this entity.
132 unsafe { self.0.get_change_ticks::<T>() }
133 }
134
135 /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
136 /// detection in custom runtimes.
137 ///
138 /// **You should prefer to use the typed API [`EntityRef::get_change_ticks`] where possible and only
139 /// use this in cases where the actual component types are not known at
140 /// compile time.**
141 #[inline]
142 pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
143 // SAFETY: We have read-only access to all components of this entity.
144 unsafe { self.0.get_change_ticks_by_id(component_id) }
145 }
146
147 /// Returns [untyped read-only reference(s)](Ptr) to component(s) for the
148 /// current entity, based on the given [`ComponentId`]s.
149 ///
150 /// **You should prefer to use the typed API [`EntityRef::get`] where
151 /// possible and only use this in cases where the actual component types
152 /// are not known at compile time.**
153 ///
154 /// Unlike [`EntityRef::get`], this returns untyped reference(s) to
155 /// component(s), and it's the job of the caller to ensure the correct
156 /// type(s) are dereferenced (if necessary).
157 ///
158 /// # Errors
159 ///
160 /// Returns [`EntityComponentError::MissingComponent`] if the entity does
161 /// not have a component.
162 ///
163 /// # Examples
164 ///
165 /// ## Single [`ComponentId`]
166 ///
167 /// ```
168 /// # use bevy_ecs::prelude::*;
169 /// #
170 /// # #[derive(Component, PartialEq, Debug)]
171 /// # pub struct Foo(i32);
172 /// # let mut world = World::new();
173 /// let entity = world.spawn(Foo(42)).id();
174 ///
175 /// // Grab the component ID for `Foo` in whatever way you like.
176 /// let component_id = world.register_component::<Foo>();
177 ///
178 /// // Then, get the component by ID.
179 /// let ptr = world.entity(entity).get_by_id(component_id);
180 /// # assert_eq!(unsafe { ptr.unwrap().deref::<Foo>() }, &Foo(42));
181 /// ```
182 ///
183 /// ## Array of [`ComponentId`]s
184 ///
185 /// ```
186 /// # use bevy_ecs::prelude::*;
187 /// #
188 /// # #[derive(Component, PartialEq, Debug)]
189 /// # pub struct X(i32);
190 /// # #[derive(Component, PartialEq, Debug)]
191 /// # pub struct Y(i32);
192 /// # let mut world = World::new();
193 /// let entity = world.spawn((X(42), Y(10))).id();
194 ///
195 /// // Grab the component IDs for `X` and `Y` in whatever way you like.
196 /// let x_id = world.register_component::<X>();
197 /// let y_id = world.register_component::<Y>();
198 ///
199 /// // Then, get the components by ID. You'll receive a same-sized array.
200 /// let Ok([x_ptr, y_ptr]) = world.entity(entity).get_by_id([x_id, y_id]) else {
201 /// // Up to you to handle if a component is missing from the entity.
202 /// # unreachable!();
203 /// };
204 /// # assert_eq!((unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() }), (&X(42), &Y(10)));
205 /// ```
206 ///
207 /// ## Slice of [`ComponentId`]s
208 ///
209 /// ```
210 /// # use bevy_ecs::{prelude::*, component::ComponentId};
211 /// #
212 /// # #[derive(Component, PartialEq, Debug)]
213 /// # pub struct X(i32);
214 /// # #[derive(Component, PartialEq, Debug)]
215 /// # pub struct Y(i32);
216 /// # let mut world = World::new();
217 /// let entity = world.spawn((X(42), Y(10))).id();
218 ///
219 /// // Grab the component IDs for `X` and `Y` in whatever way you like.
220 /// let x_id = world.register_component::<X>();
221 /// let y_id = world.register_component::<Y>();
222 ///
223 /// // Then, get the components by ID. You'll receive a vec of ptrs.
224 /// let ptrs = world.entity(entity).get_by_id(&[x_id, y_id] as &[ComponentId]);
225 /// # let ptrs = ptrs.unwrap();
226 /// # assert_eq!((unsafe { ptrs[0].deref::<X>() }, unsafe { ptrs[1].deref::<Y>() }), (&X(42), &Y(10)));
227 /// ```
228 ///
229 /// ## [`HashSet`] of [`ComponentId`]s
230 ///
231 /// ```
232 /// # use bevy_utils::HashSet;
233 /// # use bevy_ecs::{prelude::*, component::ComponentId};
234 /// #
235 /// # #[derive(Component, PartialEq, Debug)]
236 /// # pub struct X(i32);
237 /// # #[derive(Component, PartialEq, Debug)]
238 /// # pub struct Y(i32);
239 /// # let mut world = World::new();
240 /// let entity = world.spawn((X(42), Y(10))).id();
241 ///
242 /// // Grab the component IDs for `X` and `Y` in whatever way you like.
243 /// let x_id = world.register_component::<X>();
244 /// let y_id = world.register_component::<Y>();
245 ///
246 /// // Then, get the components by ID. You'll receive a vec of ptrs.
247 /// let ptrs = world.entity(entity).get_by_id(&HashSet::from_iter([x_id, y_id]));
248 /// # let ptrs = ptrs.unwrap();
249 /// # assert_eq!((unsafe { ptrs[&x_id].deref::<X>() }, unsafe { ptrs[&y_id].deref::<Y>() }), (&X(42), &Y(10)));
250 /// ```
251 #[inline]
252 pub fn get_by_id<F: DynamicComponentFetch>(
253 &self,
254 component_ids: F,
255 ) -> Result<F::Ref<'w>, EntityComponentError> {
256 // SAFETY: We have read-only access to all components of this entity.
257 unsafe { component_ids.fetch_ref(self.0) }
258 }
259
260 /// Returns read-only components for the current entity that match the query `Q`.
261 ///
262 /// # Panics
263 ///
264 /// If the entity does not have the components required by the query `Q`.
265 pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'w> {
266 self.get_components::<Q>().expect(QUERY_MISMATCH_ERROR)
267 }
268
269 /// Returns read-only components for the current entity that match the query `Q`,
270 /// or `None` if the entity does not have the components required by the query `Q`.
271 pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'w>> {
272 // SAFETY: We have read-only access to all components of this entity.
273 unsafe { self.0.get_components::<Q>() }
274 }
275}
276
277impl<'w> From<EntityWorldMut<'w>> for EntityRef<'w> {
278 fn from(entity_mut: EntityWorldMut<'w>) -> EntityRef<'w> {
279 // SAFETY:
280 // - `EntityWorldMut` guarantees exclusive access to the entire world.
281 unsafe { EntityRef::new(entity_mut.into_unsafe_entity_cell()) }
282 }
283}
284
285impl<'a> From<&'a EntityWorldMut<'_>> for EntityRef<'a> {
286 fn from(value: &'a EntityWorldMut<'_>) -> Self {
287 // SAFETY:
288 // - `EntityWorldMut` guarantees exclusive access to the entire world.
289 // - `&value` ensures no mutable accesses are active.
290 unsafe { EntityRef::new(value.as_unsafe_entity_cell_readonly()) }
291 }
292}
293
294impl<'w> From<EntityMut<'w>> for EntityRef<'w> {
295 fn from(value: EntityMut<'w>) -> Self {
296 // SAFETY:
297 // - `EntityMut` guarantees exclusive access to all of the entity's components.
298 unsafe { EntityRef::new(value.0) }
299 }
300}
301
302impl<'a> From<&'a EntityMut<'_>> for EntityRef<'a> {
303 fn from(value: &'a EntityMut<'_>) -> Self {
304 // SAFETY:
305 // - `EntityMut` guarantees exclusive access to all of the entity's components.
306 // - `&value` ensures there are no mutable accesses.
307 unsafe { EntityRef::new(value.0) }
308 }
309}
310
311impl<'a> TryFrom<FilteredEntityRef<'a>> for EntityRef<'a> {
312 type Error = TryFromFilteredError;
313
314 fn try_from(value: FilteredEntityRef<'a>) -> Result<Self, Self::Error> {
315 if !value.access.has_read_all() {
316 Err(TryFromFilteredError::MissingReadAllAccess)
317 } else {
318 // SAFETY: check above guarantees read-only access to all components of the entity.
319 Ok(unsafe { EntityRef::new(value.entity) })
320 }
321 }
322}
323
324impl<'a> TryFrom<&'a FilteredEntityRef<'_>> for EntityRef<'a> {
325 type Error = TryFromFilteredError;
326
327 fn try_from(value: &'a FilteredEntityRef<'_>) -> Result<Self, Self::Error> {
328 if !value.access.has_read_all() {
329 Err(TryFromFilteredError::MissingReadAllAccess)
330 } else {
331 // SAFETY: check above guarantees read-only access to all components of the entity.
332 Ok(unsafe { EntityRef::new(value.entity) })
333 }
334 }
335}
336
337impl<'a> TryFrom<FilteredEntityMut<'a>> for EntityRef<'a> {
338 type Error = TryFromFilteredError;
339
340 fn try_from(value: FilteredEntityMut<'a>) -> Result<Self, Self::Error> {
341 if !value.access.has_read_all() {
342 Err(TryFromFilteredError::MissingReadAllAccess)
343 } else {
344 // SAFETY: check above guarantees read-only access to all components of the entity.
345 Ok(unsafe { EntityRef::new(value.entity) })
346 }
347 }
348}
349
350impl<'a> TryFrom<&'a FilteredEntityMut<'_>> for EntityRef<'a> {
351 type Error = TryFromFilteredError;
352
353 fn try_from(value: &'a FilteredEntityMut<'_>) -> Result<Self, Self::Error> {
354 if !value.access.has_read_all() {
355 Err(TryFromFilteredError::MissingReadAllAccess)
356 } else {
357 // SAFETY: check above guarantees read-only access to all components of the entity.
358 Ok(unsafe { EntityRef::new(value.entity) })
359 }
360 }
361}
362
363/// Provides mutable access to a single entity and all of its components.
364///
365/// Contrast with [`EntityWorldMut`], which allows adding and removing components,
366/// despawning the entity, and provides mutable access to the entire world.
367/// Because of this, `EntityWorldMut` cannot coexist with any other world accesses.
368///
369/// # Examples
370///
371/// Disjoint mutable access.
372///
373/// ```
374/// # use bevy_ecs::prelude::*;
375/// # #[derive(Component)] pub struct A;
376/// fn disjoint_system(
377/// query1: Query<EntityMut, With<A>>,
378/// query2: Query<EntityMut, Without<A>>,
379/// ) {
380/// // ...
381/// }
382/// # bevy_ecs::system::assert_is_system(disjoint_system);
383/// ```
384pub struct EntityMut<'w>(UnsafeEntityCell<'w>);
385
386impl<'w> EntityMut<'w> {
387 /// # Safety
388 /// - `cell` must have permission to mutate every component of the entity.
389 /// - No accesses to any of the entity's components may exist
390 /// at the same time as the returned [`EntityMut`].
391 pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {
392 Self(cell)
393 }
394
395 /// Returns a new instance with a shorter lifetime.
396 /// This is useful if you have `&mut EntityMut`, but you need `EntityMut`.
397 pub fn reborrow(&mut self) -> EntityMut<'_> {
398 // SAFETY: We have exclusive access to the entire entity and its components.
399 unsafe { Self::new(self.0) }
400 }
401
402 /// Gets read-only access to all of the entity's components.
403 pub fn as_readonly(&self) -> EntityRef<'_> {
404 EntityRef::from(self)
405 }
406
407 /// Returns the [ID](Entity) of the current entity.
408 #[inline]
409 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
410 pub fn id(&self) -> Entity {
411 self.0.id()
412 }
413
414 /// Gets metadata indicating the location where the current entity is stored.
415 #[inline]
416 pub fn location(&self) -> EntityLocation {
417 self.0.location()
418 }
419
420 /// Returns the archetype that the current entity belongs to.
421 #[inline]
422 pub fn archetype(&self) -> &Archetype {
423 self.0.archetype()
424 }
425
426 /// Returns `true` if the current entity has a component of type `T`.
427 /// Otherwise, this returns `false`.
428 ///
429 /// ## Notes
430 ///
431 /// If you do not know the concrete type of a component, consider using
432 /// [`Self::contains_id`] or [`Self::contains_type_id`].
433 #[inline]
434 pub fn contains<T: Component>(&self) -> bool {
435 self.contains_type_id(TypeId::of::<T>())
436 }
437
438 /// Returns `true` if the current entity has a component identified by `component_id`.
439 /// Otherwise, this returns false.
440 ///
441 /// ## Notes
442 ///
443 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
444 /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
445 /// [`Self::contains_type_id`].
446 #[inline]
447 pub fn contains_id(&self, component_id: ComponentId) -> bool {
448 self.0.contains_id(component_id)
449 }
450
451 /// Returns `true` if the current entity has a component with the type identified by `type_id`.
452 /// Otherwise, this returns false.
453 ///
454 /// ## Notes
455 ///
456 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
457 /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
458 #[inline]
459 pub fn contains_type_id(&self, type_id: TypeId) -> bool {
460 self.0.contains_type_id(type_id)
461 }
462
463 /// Gets access to the component of type `T` for the current entity.
464 /// Returns `None` if the entity does not have a component of type `T`.
465 #[inline]
466 pub fn get<T: Component>(&self) -> Option<&'_ T> {
467 self.as_readonly().get()
468 }
469
470 /// Returns read-only components for the current entity that match the query `Q`.
471 ///
472 /// # Panics
473 ///
474 /// If the entity does not have the components required by the query `Q`.
475 pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'_> {
476 self.get_components::<Q>().expect(QUERY_MISMATCH_ERROR)
477 }
478
479 /// Returns read-only components for the current entity that match the query `Q`,
480 /// or `None` if the entity does not have the components required by the query `Q`.
481 pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'_>> {
482 // SAFETY: We have read-only access to all components of this entity.
483 unsafe { self.0.get_components::<Q>() }
484 }
485
486 /// Consumes `self` and gets access to the component of type `T` with the
487 /// world `'w` lifetime for the current entity.
488 ///
489 /// Returns `None` if the entity does not have a component of type `T`.
490 #[inline]
491 pub fn into_borrow<T: Component>(self) -> Option<&'w T> {
492 // SAFETY: consuming `self` implies exclusive access
493 unsafe { self.0.get() }
494 }
495
496 /// Gets access to the component of type `T` for the current entity,
497 /// including change detection information as a [`Ref`].
498 ///
499 /// Returns `None` if the entity does not have a component of type `T`.
500 #[inline]
501 pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
502 self.as_readonly().get_ref()
503 }
504
505 /// Consumes `self` and gets access to the component of type `T` with world
506 /// `'w` lifetime for the current entity, including change detection information
507 /// as a [`Ref<'w>`].
508 ///
509 /// Returns `None` if the entity does not have a component of type `T`.
510 #[inline]
511 pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {
512 // SAFETY: consuming `self` implies exclusive access
513 unsafe { self.0.get_ref() }
514 }
515
516 /// Gets mutable access to the component of type `T` for the current entity.
517 /// Returns `None` if the entity does not have a component of type `T`.
518 #[inline]
519 pub fn get_mut<T: Component>(&mut self) -> Option<Mut<'_, T>> {
520 // SAFETY: &mut self implies exclusive access for duration of returned value
521 unsafe { self.0.get_mut() }
522 }
523
524 /// Consumes self and gets mutable access to the component of type `T`
525 /// with the world `'w` lifetime for the current entity.
526 /// Returns `None` if the entity does not have a component of type `T`.
527 #[inline]
528 pub fn into_mut<T: Component>(self) -> Option<Mut<'w, T>> {
529 // SAFETY: consuming `self` implies exclusive access
530 unsafe { self.0.get_mut() }
531 }
532
533 /// Retrieves the change ticks for the given component. This can be useful for implementing change
534 /// detection in custom runtimes.
535 #[inline]
536 pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
537 self.as_readonly().get_change_ticks::<T>()
538 }
539
540 /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
541 /// detection in custom runtimes.
542 ///
543 /// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only
544 /// use this in cases where the actual component types are not known at
545 /// compile time.**
546 #[inline]
547 pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
548 self.as_readonly().get_change_ticks_by_id(component_id)
549 }
550
551 /// Returns [untyped read-only reference(s)](Ptr) to component(s) for the
552 /// current entity, based on the given [`ComponentId`]s.
553 ///
554 /// **You should prefer to use the typed API [`EntityMut::get`] where
555 /// possible and only use this in cases where the actual component types
556 /// are not known at compile time.**
557 ///
558 /// Unlike [`EntityMut::get`], this returns untyped reference(s) to
559 /// component(s), and it's the job of the caller to ensure the correct
560 /// type(s) are dereferenced (if necessary).
561 ///
562 /// # Errors
563 ///
564 /// Returns [`EntityComponentError::MissingComponent`] if the entity does
565 /// not have a component.
566 ///
567 /// # Examples
568 ///
569 /// For examples on how to use this method, see [`EntityRef::get_by_id`].
570 #[inline]
571 pub fn get_by_id<F: DynamicComponentFetch>(
572 &self,
573 component_ids: F,
574 ) -> Result<F::Ref<'_>, EntityComponentError> {
575 self.as_readonly().get_by_id(component_ids)
576 }
577
578 /// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to
579 /// component(s) with lifetime `'w` for the current entity, based on the
580 /// given [`ComponentId`]s.
581 ///
582 /// **You should prefer to use the typed API [`EntityMut::into_borrow`]
583 /// where possible and only use this in cases where the actual component
584 /// types are not known at compile time.**
585 ///
586 /// Unlike [`EntityMut::into_borrow`], this returns untyped reference(s) to
587 /// component(s), and it's the job of the caller to ensure the correct
588 /// type(s) are dereferenced (if necessary).
589 ///
590 /// # Errors
591 ///
592 /// Returns [`EntityComponentError::MissingComponent`] if the entity does
593 /// not have a component.
594 ///
595 /// # Examples
596 ///
597 /// For examples on how to use this method, see [`EntityRef::get_by_id`].
598 #[inline]
599 pub fn into_borrow_by_id<F: DynamicComponentFetch>(
600 self,
601 component_ids: F,
602 ) -> Result<F::Ref<'w>, EntityComponentError> {
603 // SAFETY:
604 // - We have read-only access to all components of this entity.
605 // - consuming `self` ensures that no references exist to this entity's components.
606 unsafe { component_ids.fetch_ref(self.0) }
607 }
608
609 /// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
610 /// the current entity, based on the given [`ComponentId`]s.
611 ///
612 /// **You should prefer to use the typed API [`EntityMut::get_mut`] where
613 /// possible and only use this in cases where the actual component types
614 /// are not known at compile time.**
615 ///
616 /// Unlike [`EntityMut::get_mut`], this returns untyped reference(s) to
617 /// component(s), and it's the job of the caller to ensure the correct
618 /// type(s) are dereferenced (if necessary).
619 ///
620 /// # Errors
621 ///
622 /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
623 /// not have a component.
624 /// - Returns [`EntityComponentError::AliasedMutability`] if a component
625 /// is requested multiple times.
626 ///
627 /// # Examples
628 ///
629 /// ## Single [`ComponentId`]
630 ///
631 /// ```
632 /// # use bevy_ecs::prelude::*;
633 /// #
634 /// # #[derive(Component, PartialEq, Debug)]
635 /// # pub struct Foo(i32);
636 /// # let mut world = World::new();
637 /// let entity = world.spawn(Foo(42)).id();
638 ///
639 /// // Grab the component ID for `Foo` in whatever way you like.
640 /// let component_id = world.register_component::<Foo>();
641 ///
642 /// // Then, get the component by ID.
643 /// let mut entity_mut = world.entity_mut(entity);
644 /// let mut ptr = entity_mut.get_mut_by_id(component_id)
645 /// # .unwrap();
646 /// # assert_eq!(unsafe { ptr.as_mut().deref_mut::<Foo>() }, &mut Foo(42));
647 /// ```
648 ///
649 /// ## Array of [`ComponentId`]s
650 ///
651 /// ```
652 /// # use bevy_ecs::prelude::*;
653 /// #
654 /// # #[derive(Component, PartialEq, Debug)]
655 /// # pub struct X(i32);
656 /// # #[derive(Component, PartialEq, Debug)]
657 /// # pub struct Y(i32);
658 /// # let mut world = World::new();
659 /// let entity = world.spawn((X(42), Y(10))).id();
660 ///
661 /// // Grab the component IDs for `X` and `Y` in whatever way you like.
662 /// let x_id = world.register_component::<X>();
663 /// let y_id = world.register_component::<Y>();
664 ///
665 /// // Then, get the components by ID. You'll receive a same-sized array.
666 /// let mut entity_mut = world.entity_mut(entity);
667 /// let Ok([mut x_ptr, mut y_ptr]) = entity_mut.get_mut_by_id([x_id, y_id]) else {
668 /// // Up to you to handle if a component is missing from the entity.
669 /// # unreachable!();
670 /// };
671 /// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));
672 /// ```
673 ///
674 /// ## Slice of [`ComponentId`]s
675 ///
676 /// ```
677 /// # use bevy_ecs::{prelude::*, component::ComponentId, change_detection::MutUntyped};
678 /// #
679 /// # #[derive(Component, PartialEq, Debug)]
680 /// # pub struct X(i32);
681 /// # #[derive(Component, PartialEq, Debug)]
682 /// # pub struct Y(i32);
683 /// # let mut world = World::new();
684 /// let entity = world.spawn((X(42), Y(10))).id();
685 ///
686 /// // Grab the component IDs for `X` and `Y` in whatever way you like.
687 /// let x_id = world.register_component::<X>();
688 /// let y_id = world.register_component::<Y>();
689 ///
690 /// // Then, get the components by ID. You'll receive a vec of ptrs.
691 /// let mut entity_mut = world.entity_mut(entity);
692 /// let ptrs = entity_mut.get_mut_by_id(&[x_id, y_id] as &[ComponentId])
693 /// # .unwrap();
694 /// # let [mut x_ptr, mut y_ptr]: [MutUntyped; 2] = ptrs.try_into().unwrap();
695 /// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));
696 /// ```
697 ///
698 /// ## [`HashSet`] of [`ComponentId`]s
699 ///
700 /// ```
701 /// # use bevy_utils::HashSet;
702 /// # use bevy_ecs::{prelude::*, component::ComponentId};
703 /// #
704 /// # #[derive(Component, PartialEq, Debug)]
705 /// # pub struct X(i32);
706 /// # #[derive(Component, PartialEq, Debug)]
707 /// # pub struct Y(i32);
708 /// # let mut world = World::new();
709 /// let entity = world.spawn((X(42), Y(10))).id();
710 ///
711 /// // Grab the component IDs for `X` and `Y` in whatever way you like.
712 /// let x_id = world.register_component::<X>();
713 /// let y_id = world.register_component::<Y>();
714 ///
715 /// // Then, get the components by ID. You'll receive a `HashMap` of ptrs.
716 /// let mut entity_mut = world.entity_mut(entity);
717 /// let mut ptrs = entity_mut.get_mut_by_id(&HashSet::from_iter([x_id, y_id]))
718 /// # .unwrap();
719 /// # let [mut x_ptr, mut y_ptr] = ptrs.get_many_mut([&x_id, &y_id]).unwrap();
720 /// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));
721 /// ```
722 #[inline]
723 pub fn get_mut_by_id<F: DynamicComponentFetch>(
724 &mut self,
725 component_ids: F,
726 ) -> Result<F::Mut<'_>, EntityComponentError> {
727 // SAFETY:
728 // - `&mut self` ensures that no references exist to this entity's components.
729 // - We have exclusive access to all components of this entity.
730 unsafe { component_ids.fetch_mut(self.0) }
731 }
732
733 /// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
734 /// to component(s) with lifetime `'w` for the current entity, based on the
735 /// given [`ComponentId`]s.
736 ///
737 /// **You should prefer to use the typed API [`EntityMut::into_mut`] where
738 /// possible and only use this in cases where the actual component types
739 /// are not known at compile time.**
740 ///
741 /// Unlike [`EntityMut::into_mut`], this returns untyped reference(s) to
742 /// component(s), and it's the job of the caller to ensure the correct
743 /// type(s) are dereferenced (if necessary).
744 ///
745 /// # Errors
746 ///
747 /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
748 /// not have a component.
749 /// - Returns [`EntityComponentError::AliasedMutability`] if a component
750 /// is requested multiple times.
751 ///
752 /// # Examples
753 ///
754 /// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
755 #[inline]
756 pub fn into_mut_by_id<F: DynamicComponentFetch>(
757 self,
758 component_ids: F,
759 ) -> Result<F::Mut<'w>, EntityComponentError> {
760 // SAFETY:
761 // - consuming `self` ensures that no references exist to this entity's components.
762 // - We have exclusive access to all components of this entity.
763 unsafe { component_ids.fetch_mut(self.0) }
764 }
765}
766
767impl<'w> From<&'w mut EntityMut<'_>> for EntityMut<'w> {
768 fn from(value: &'w mut EntityMut<'_>) -> Self {
769 value.reborrow()
770 }
771}
772
773impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {
774 fn from(value: EntityWorldMut<'w>) -> Self {
775 // SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
776 unsafe { EntityMut::new(value.into_unsafe_entity_cell()) }
777 }
778}
779
780impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {
781 fn from(value: &'a mut EntityWorldMut<'_>) -> Self {
782 // SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
783 unsafe { EntityMut::new(value.as_unsafe_entity_cell()) }
784 }
785}
786
787impl<'a> TryFrom<FilteredEntityMut<'a>> for EntityMut<'a> {
788 type Error = TryFromFilteredError;
789
790 fn try_from(value: FilteredEntityMut<'a>) -> Result<Self, Self::Error> {
791 if !value.access.has_read_all() {
792 Err(TryFromFilteredError::MissingReadAllAccess)
793 } else if !value.access.has_write_all() {
794 Err(TryFromFilteredError::MissingWriteAllAccess)
795 } else {
796 // SAFETY: check above guarantees exclusive access to all components of the entity.
797 Ok(unsafe { EntityMut::new(value.entity) })
798 }
799 }
800}
801
802impl<'a> TryFrom<&'a mut FilteredEntityMut<'_>> for EntityMut<'a> {
803 type Error = TryFromFilteredError;
804
805 fn try_from(value: &'a mut FilteredEntityMut<'_>) -> Result<Self, Self::Error> {
806 if !value.access.has_read_all() {
807 Err(TryFromFilteredError::MissingReadAllAccess)
808 } else if !value.access.has_write_all() {
809 Err(TryFromFilteredError::MissingWriteAllAccess)
810 } else {
811 // SAFETY: check above guarantees exclusive access to all components of the entity.
812 Ok(unsafe { EntityMut::new(value.entity) })
813 }
814 }
815}
816
817/// A mutable reference to a particular [`Entity`], and the entire world.
818///
819/// This is essentially a performance-optimized `(Entity, &mut World)` tuple,
820/// which caches the [`EntityLocation`] to reduce duplicate lookups.
821///
822/// Since this type provides mutable access to the entire world, only one
823/// [`EntityWorldMut`] can exist at a time for a given world.
824///
825/// See also [`EntityMut`], which allows disjoint mutable access to multiple
826/// entities at once. Unlike `EntityMut`, this type allows adding and
827/// removing components, and despawning the entity.
828pub struct EntityWorldMut<'w> {
829 world: &'w mut World,
830 entity: Entity,
831 location: EntityLocation,
832}
833
834impl<'w> EntityWorldMut<'w> {
835 fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {
836 UnsafeEntityCell::new(
837 self.world.as_unsafe_world_cell_readonly(),
838 self.entity,
839 self.location,
840 )
841 }
842 fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {
843 UnsafeEntityCell::new(
844 self.world.as_unsafe_world_cell(),
845 self.entity,
846 self.location,
847 )
848 }
849 fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {
850 UnsafeEntityCell::new(
851 self.world.as_unsafe_world_cell(),
852 self.entity,
853 self.location,
854 )
855 }
856
857 /// # Safety
858 ///
859 /// - `entity` must be valid for `world`: the generation should match that of the entity at the same index.
860 /// - `location` must be sourced from `world`'s `Entities` and must exactly match the location for `entity`
861 ///
862 /// The above is trivially satisfied if `location` was sourced from `world.entities().get(entity)`.
863 #[inline]
864 pub(crate) unsafe fn new(
865 world: &'w mut World,
866 entity: Entity,
867 location: EntityLocation,
868 ) -> Self {
869 debug_assert!(world.entities().contains(entity));
870 debug_assert_eq!(world.entities().get(entity), Some(location));
871
872 EntityWorldMut {
873 world,
874 entity,
875 location,
876 }
877 }
878
879 /// Returns the [ID](Entity) of the current entity.
880 #[inline]
881 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
882 pub fn id(&self) -> Entity {
883 self.entity
884 }
885
886 /// Gets metadata indicating the location where the current entity is stored.
887 #[inline]
888 pub fn location(&self) -> EntityLocation {
889 self.location
890 }
891
892 /// Returns the archetype that the current entity belongs to.
893 #[inline]
894 pub fn archetype(&self) -> &Archetype {
895 &self.world.archetypes[self.location.archetype_id]
896 }
897
898 /// Returns `true` if the current entity has a component of type `T`.
899 /// Otherwise, this returns `false`.
900 ///
901 /// ## Notes
902 ///
903 /// If you do not know the concrete type of a component, consider using
904 /// [`Self::contains_id`] or [`Self::contains_type_id`].
905 #[inline]
906 pub fn contains<T: Component>(&self) -> bool {
907 self.contains_type_id(TypeId::of::<T>())
908 }
909
910 /// Returns `true` if the current entity has a component identified by `component_id`.
911 /// Otherwise, this returns false.
912 ///
913 /// ## Notes
914 ///
915 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
916 /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
917 /// [`Self::contains_type_id`].
918 #[inline]
919 pub fn contains_id(&self, component_id: ComponentId) -> bool {
920 self.as_unsafe_entity_cell_readonly()
921 .contains_id(component_id)
922 }
923
924 /// Returns `true` if the current entity has a component with the type identified by `type_id`.
925 /// Otherwise, this returns false.
926 ///
927 /// ## Notes
928 ///
929 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
930 /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
931 #[inline]
932 pub fn contains_type_id(&self, type_id: TypeId) -> bool {
933 self.as_unsafe_entity_cell_readonly()
934 .contains_type_id(type_id)
935 }
936
937 /// Gets access to the component of type `T` for the current entity.
938 /// Returns `None` if the entity does not have a component of type `T`.
939 #[inline]
940 pub fn get<T: Component>(&self) -> Option<&'_ T> {
941 EntityRef::from(self).get()
942 }
943
944 /// Returns read-only components for the current entity that match the query `Q`.
945 ///
946 /// # Panics
947 ///
948 /// If the entity does not have the components required by the query `Q`.
949 #[inline]
950 pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'_> {
951 EntityRef::from(self).components::<Q>()
952 }
953
954 /// Returns read-only components for the current entity that match the query `Q`,
955 /// or `None` if the entity does not have the components required by the query `Q`.
956 #[inline]
957 pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'_>> {
958 EntityRef::from(self).get_components::<Q>()
959 }
960
961 /// Consumes `self` and gets access to the component of type `T` with
962 /// the world `'w` lifetime for the current entity.
963 /// Returns `None` if the entity does not have a component of type `T`.
964 #[inline]
965 pub fn into_borrow<T: Component>(self) -> Option<&'w T> {
966 // SAFETY: consuming `self` implies exclusive access
967 unsafe { self.into_unsafe_entity_cell().get() }
968 }
969
970 /// Gets access to the component of type `T` for the current entity,
971 /// including change detection information as a [`Ref`].
972 ///
973 /// Returns `None` if the entity does not have a component of type `T`.
974 #[inline]
975 pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
976 EntityRef::from(self).get_ref()
977 }
978
979 /// Consumes `self` and gets access to the component of type `T`
980 /// with the world `'w` lifetime for the current entity,
981 /// including change detection information as a [`Ref`].
982 ///
983 /// Returns `None` if the entity does not have a component of type `T`.
984 #[inline]
985 pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {
986 EntityRef::from(self).get_ref()
987 }
988
989 /// Gets mutable access to the component of type `T` for the current entity.
990 /// Returns `None` if the entity does not have a component of type `T`.
991 #[inline]
992 pub fn get_mut<T: Component>(&mut self) -> Option<Mut<'_, T>> {
993 // SAFETY: &mut self implies exclusive access for duration of returned value
994 unsafe { self.as_unsafe_entity_cell().get_mut() }
995 }
996
997 /// Consumes `self` and gets mutable access to the component of type `T`
998 /// with the world `'w` lifetime for the current entity.
999 /// Returns `None` if the entity does not have a component of type `T`.
1000 #[inline]
1001 pub fn into_mut<T: Component>(self) -> Option<Mut<'w, T>> {
1002 // SAFETY: consuming `self` implies exclusive access
1003 unsafe { self.into_unsafe_entity_cell().get_mut() }
1004 }
1005
1006 /// Retrieves the change ticks for the given component. This can be useful for implementing change
1007 /// detection in custom runtimes.
1008 #[inline]
1009 pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
1010 EntityRef::from(self).get_change_ticks::<T>()
1011 }
1012
1013 /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
1014 /// detection in custom runtimes.
1015 ///
1016 /// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only
1017 /// use this in cases where the actual component types are not known at
1018 /// compile time.**
1019 #[inline]
1020 pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
1021 EntityRef::from(self).get_change_ticks_by_id(component_id)
1022 }
1023
1024 /// Returns [untyped read-only reference(s)](Ptr) to component(s) for the
1025 /// current entity, based on the given [`ComponentId`]s.
1026 ///
1027 /// **You should prefer to use the typed API [`EntityWorldMut::get`] where
1028 /// possible and only use this in cases where the actual component types
1029 /// are not known at compile time.**
1030 ///
1031 /// Unlike [`EntityWorldMut::get`], this returns untyped reference(s) to
1032 /// component(s), and it's the job of the caller to ensure the correct
1033 /// type(s) are dereferenced (if necessary).
1034 ///
1035 /// # Errors
1036 ///
1037 /// Returns [`EntityComponentError::MissingComponent`] if the entity does
1038 /// not have a component.
1039 ///
1040 /// # Examples
1041 ///
1042 /// For examples on how to use this method, see [`EntityRef::get_by_id`].
1043 #[inline]
1044 pub fn get_by_id<F: DynamicComponentFetch>(
1045 &self,
1046 component_ids: F,
1047 ) -> Result<F::Ref<'_>, EntityComponentError> {
1048 EntityRef::from(self).get_by_id(component_ids)
1049 }
1050
1051 /// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to
1052 /// component(s) with lifetime `'w` for the current entity, based on the
1053 /// given [`ComponentId`]s.
1054 ///
1055 /// **You should prefer to use the typed API [`EntityWorldMut::into_borrow`]
1056 /// where possible and only use this in cases where the actual component
1057 /// types are not known at compile time.**
1058 ///
1059 /// Unlike [`EntityWorldMut::into_borrow`], this returns untyped reference(s) to
1060 /// component(s), and it's the job of the caller to ensure the correct
1061 /// type(s) are dereferenced (if necessary).
1062 ///
1063 /// # Errors
1064 ///
1065 /// Returns [`EntityComponentError::MissingComponent`] if the entity does
1066 /// not have a component.
1067 ///
1068 /// # Examples
1069 ///
1070 /// For examples on how to use this method, see [`EntityRef::get_by_id`].
1071 #[inline]
1072 pub fn into_borrow_by_id<F: DynamicComponentFetch>(
1073 self,
1074 component_ids: F,
1075 ) -> Result<F::Ref<'w>, EntityComponentError> {
1076 // SAFETY:
1077 // - We have read-only access to all components of this entity.
1078 // - consuming `self` ensures that no references exist to this entity's components.
1079 unsafe { component_ids.fetch_ref(self.into_unsafe_entity_cell()) }
1080 }
1081
1082 /// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
1083 /// the current entity, based on the given [`ComponentId`]s.
1084 ///
1085 /// **You should prefer to use the typed API [`EntityWorldMut::get_mut`] where
1086 /// possible and only use this in cases where the actual component types
1087 /// are not known at compile time.**
1088 ///
1089 /// Unlike [`EntityWorldMut::get_mut`], this returns untyped reference(s) to
1090 /// component(s), and it's the job of the caller to ensure the correct
1091 /// type(s) are dereferenced (if necessary).
1092 ///
1093 /// # Errors
1094 ///
1095 /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1096 /// not have a component.
1097 /// - Returns [`EntityComponentError::AliasedMutability`] if a component
1098 /// is requested multiple times.
1099 ///
1100 /// # Examples
1101 ///
1102 /// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
1103 #[inline]
1104 pub fn get_mut_by_id<F: DynamicComponentFetch>(
1105 &mut self,
1106 component_ids: F,
1107 ) -> Result<F::Mut<'_>, EntityComponentError> {
1108 // SAFETY:
1109 // - `&mut self` ensures that no references exist to this entity's components.
1110 // - We have exclusive access to all components of this entity.
1111 unsafe { component_ids.fetch_mut(self.as_unsafe_entity_cell()) }
1112 }
1113
1114 /// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
1115 /// to component(s) with lifetime `'w` for the current entity, based on the
1116 /// given [`ComponentId`]s.
1117 ///
1118 /// **You should prefer to use the typed API [`EntityWorldMut::into_mut`] where
1119 /// possible and only use this in cases where the actual component types
1120 /// are not known at compile time.**
1121 ///
1122 /// Unlike [`EntityWorldMut::into_mut`], this returns untyped reference(s) to
1123 /// component(s), and it's the job of the caller to ensure the correct
1124 /// type(s) are dereferenced (if necessary).
1125 ///
1126 /// # Errors
1127 ///
1128 /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
1129 /// not have a component.
1130 /// - Returns [`EntityComponentError::AliasedMutability`] if a component
1131 /// is requested multiple times.
1132 ///
1133 /// # Examples
1134 ///
1135 /// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
1136 #[inline]
1137 pub fn into_mut_by_id<F: DynamicComponentFetch>(
1138 self,
1139 component_ids: F,
1140 ) -> Result<F::Mut<'w>, EntityComponentError> {
1141 // SAFETY:
1142 // - consuming `self` ensures that no references exist to this entity's components.
1143 // - We have exclusive access to all components of this entity.
1144 unsafe { component_ids.fetch_mut(self.into_unsafe_entity_cell()) }
1145 }
1146
1147 /// Adds a [`Bundle`] of components to the entity.
1148 ///
1149 /// This will overwrite any previous value(s) of the same component type.
1150 #[track_caller]
1151 pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {
1152 self.insert_with_caller(
1153 bundle,
1154 InsertMode::Replace,
1155 #[cfg(feature = "track_change_detection")]
1156 core::panic::Location::caller(),
1157 )
1158 }
1159
1160 /// Adds a [`Bundle`] of components to the entity without overwriting.
1161 ///
1162 /// This will leave any previous value(s) of the same component type
1163 /// unchanged.
1164 #[track_caller]
1165 pub fn insert_if_new<T: Bundle>(&mut self, bundle: T) -> &mut Self {
1166 self.insert_with_caller(
1167 bundle,
1168 InsertMode::Keep,
1169 #[cfg(feature = "track_change_detection")]
1170 core::panic::Location::caller(),
1171 )
1172 }
1173
1174 /// Split into a new function so we can pass the calling location into the function when using
1175 /// as a command.
1176 #[inline]
1177 pub(crate) fn insert_with_caller<T: Bundle>(
1178 &mut self,
1179 bundle: T,
1180 mode: InsertMode,
1181 #[cfg(feature = "track_change_detection")] caller: &'static core::panic::Location,
1182 ) -> &mut Self {
1183 let change_tick = self.world.change_tick();
1184 let mut bundle_inserter =
1185 BundleInserter::new::<T>(self.world, self.location.archetype_id, change_tick);
1186 self.location =
1187 // SAFETY: location matches current entity. `T` matches `bundle_info`
1188 unsafe {
1189 bundle_inserter.insert(self.entity, self.location, bundle, mode, #[cfg(feature = "track_change_detection")] caller)
1190 };
1191 self
1192 }
1193
1194 /// Inserts a dynamic [`Component`] into the entity.
1195 ///
1196 /// This will overwrite any previous value(s) of the same component type.
1197 ///
1198 /// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.
1199 ///
1200 /// # Safety
1201 ///
1202 /// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]
1203 /// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
1204 #[track_caller]
1205 pub unsafe fn insert_by_id(
1206 &mut self,
1207 component_id: ComponentId,
1208 component: OwningPtr<'_>,
1209 ) -> &mut Self {
1210 let change_tick = self.world.change_tick();
1211 let bundle_id = self
1212 .world
1213 .bundles
1214 .init_component_info(&self.world.components, component_id);
1215 let storage_type = self.world.bundles.get_storage_unchecked(bundle_id);
1216
1217 let bundle_inserter = BundleInserter::new_with_id(
1218 self.world,
1219 self.location.archetype_id,
1220 bundle_id,
1221 change_tick,
1222 );
1223
1224 self.location = insert_dynamic_bundle(
1225 bundle_inserter,
1226 self.entity,
1227 self.location,
1228 Some(component).into_iter(),
1229 Some(storage_type).iter().cloned(),
1230 );
1231 self
1232 }
1233
1234 /// Inserts a dynamic [`Bundle`] into the entity.
1235 ///
1236 /// This will overwrite any previous value(s) of the same component type.
1237 ///
1238 /// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.
1239 /// If your [`Bundle`] only has one component, use the cached API [`EntityWorldMut::insert_by_id`].
1240 ///
1241 /// If possible, pass a sorted slice of `ComponentId` to maximize caching potential.
1242 ///
1243 /// # Safety
1244 /// - Each [`ComponentId`] must be from the same world as [`EntityWorldMut`]
1245 /// - Each [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
1246 #[track_caller]
1247 pub unsafe fn insert_by_ids<'a, I: Iterator<Item = OwningPtr<'a>>>(
1248 &mut self,
1249 component_ids: &[ComponentId],
1250 iter_components: I,
1251 ) -> &mut Self {
1252 let change_tick = self.world.change_tick();
1253 let bundle_id = self
1254 .world
1255 .bundles
1256 .init_dynamic_info(&self.world.components, component_ids);
1257 let mut storage_types =
1258 core::mem::take(self.world.bundles.get_storages_unchecked(bundle_id));
1259 let bundle_inserter = BundleInserter::new_with_id(
1260 self.world,
1261 self.location.archetype_id,
1262 bundle_id,
1263 change_tick,
1264 );
1265
1266 self.location = insert_dynamic_bundle(
1267 bundle_inserter,
1268 self.entity,
1269 self.location,
1270 iter_components,
1271 (*storage_types).iter().cloned(),
1272 );
1273 *self.world.bundles.get_storages_unchecked(bundle_id) = core::mem::take(&mut storage_types);
1274 self
1275 }
1276
1277 /// Removes all components in the [`Bundle`] from the entity and returns their previous values.
1278 ///
1279 /// **Note:** If the entity does not have every component in the bundle, this method will not
1280 /// remove any of them.
1281 // TODO: BundleRemover?
1282 #[must_use]
1283 pub fn take<T: Bundle>(&mut self) -> Option<T> {
1284 let world = &mut self.world;
1285 let storages = &mut world.storages;
1286 let components = &mut world.components;
1287 let bundle_id = world.bundles.register_info::<T>(components, storages);
1288 // SAFETY: We just ensured this bundle exists
1289 let bundle_info = unsafe { world.bundles.get_unchecked(bundle_id) };
1290 let old_location = self.location;
1291 // SAFETY: `archetype_id` exists because it is referenced in the old `EntityLocation` which is valid,
1292 // components exist in `bundle_info` because `Bundles::init_info` initializes a `BundleInfo` containing all components of the bundle type `T`
1293 let new_archetype_id = unsafe {
1294 remove_bundle_from_archetype(
1295 &mut world.archetypes,
1296 storages,
1297 components,
1298 &world.observers,
1299 old_location.archetype_id,
1300 bundle_info,
1301 false,
1302 )?
1303 };
1304
1305 if new_archetype_id == old_location.archetype_id {
1306 return None;
1307 }
1308
1309 let entity = self.entity;
1310 // SAFETY: Archetypes and Bundles cannot be mutably aliased through DeferredWorld
1311 let (old_archetype, bundle_info, mut deferred_world) = unsafe {
1312 let bundle_info: *const BundleInfo = bundle_info;
1313 let world = world.as_unsafe_world_cell();
1314 (
1315 &world.archetypes()[old_location.archetype_id],
1316 &*bundle_info,
1317 world.into_deferred(),
1318 )
1319 };
1320
1321 // SAFETY: all bundle components exist in World
1322 unsafe {
1323 trigger_on_replace_and_on_remove_hooks_and_observers(
1324 &mut deferred_world,
1325 old_archetype,
1326 entity,
1327 bundle_info,
1328 );
1329 }
1330
1331 let archetypes = &mut world.archetypes;
1332 let storages = &mut world.storages;
1333 let components = &mut world.components;
1334 let entities = &mut world.entities;
1335 let removed_components = &mut world.removed_components;
1336
1337 let entity = self.entity;
1338 let mut bundle_components = bundle_info.iter_explicit_components();
1339 // SAFETY: bundle components are iterated in order, which guarantees that the component type
1340 // matches
1341 let result = unsafe {
1342 T::from_components(storages, &mut |storages| {
1343 let component_id = bundle_components.next().unwrap();
1344 // SAFETY:
1345 // - entity location is valid
1346 // - table row is removed below, without dropping the contents
1347 // - `components` comes from the same world as `storages`
1348 take_component(
1349 storages,
1350 components,
1351 removed_components,
1352 component_id,
1353 entity,
1354 old_location,
1355 )
1356 })
1357 };
1358
1359 #[allow(clippy::undocumented_unsafe_blocks)] // TODO: document why this is safe
1360 unsafe {
1361 Self::move_entity_from_remove::<false>(
1362 entity,
1363 &mut self.location,
1364 old_location.archetype_id,
1365 old_location,
1366 entities,
1367 archetypes,
1368 storages,
1369 new_archetype_id,
1370 );
1371 }
1372 Some(result)
1373 }
1374
1375 /// # Safety
1376 ///
1377 /// `new_archetype_id` must have the same or a subset of the components
1378 /// in `old_archetype_id`. Probably more safety stuff too, audit a call to
1379 /// this fn as if the code here was written inline
1380 ///
1381 /// when DROP is true removed components will be dropped otherwise they will be forgotten
1382 // We use a const generic here so that we are less reliant on
1383 // inlining for rustc to optimize out the `match DROP`
1384 #[allow(clippy::too_many_arguments)]
1385 unsafe fn move_entity_from_remove<const DROP: bool>(
1386 entity: Entity,
1387 self_location: &mut EntityLocation,
1388 old_archetype_id: ArchetypeId,
1389 old_location: EntityLocation,
1390 entities: &mut Entities,
1391 archetypes: &mut Archetypes,
1392 storages: &mut Storages,
1393 new_archetype_id: ArchetypeId,
1394 ) {
1395 let old_archetype = &mut archetypes[old_archetype_id];
1396 let remove_result = old_archetype.swap_remove(old_location.archetype_row);
1397 // if an entity was moved into this entity's archetype row, update its archetype row
1398 if let Some(swapped_entity) = remove_result.swapped_entity {
1399 let swapped_location = entities.get(swapped_entity).unwrap();
1400
1401 entities.set(
1402 swapped_entity.index(),
1403 EntityLocation {
1404 archetype_id: swapped_location.archetype_id,
1405 archetype_row: old_location.archetype_row,
1406 table_id: swapped_location.table_id,
1407 table_row: swapped_location.table_row,
1408 },
1409 );
1410 }
1411 let old_table_row = remove_result.table_row;
1412 let old_table_id = old_archetype.table_id();
1413 let new_archetype = &mut archetypes[new_archetype_id];
1414
1415 let new_location = if old_table_id == new_archetype.table_id() {
1416 new_archetype.allocate(entity, old_table_row)
1417 } else {
1418 let (old_table, new_table) = storages
1419 .tables
1420 .get_2_mut(old_table_id, new_archetype.table_id());
1421
1422 let move_result = if DROP {
1423 // SAFETY: old_table_row exists
1424 unsafe { old_table.move_to_and_drop_missing_unchecked(old_table_row, new_table) }
1425 } else {
1426 // SAFETY: old_table_row exists
1427 unsafe { old_table.move_to_and_forget_missing_unchecked(old_table_row, new_table) }
1428 };
1429
1430 // SAFETY: move_result.new_row is a valid position in new_archetype's table
1431 let new_location = unsafe { new_archetype.allocate(entity, move_result.new_row) };
1432
1433 // if an entity was moved into this entity's table row, update its table row
1434 if let Some(swapped_entity) = move_result.swapped_entity {
1435 let swapped_location = entities.get(swapped_entity).unwrap();
1436
1437 entities.set(
1438 swapped_entity.index(),
1439 EntityLocation {
1440 archetype_id: swapped_location.archetype_id,
1441 archetype_row: swapped_location.archetype_row,
1442 table_id: swapped_location.table_id,
1443 table_row: old_location.table_row,
1444 },
1445 );
1446 archetypes[swapped_location.archetype_id]
1447 .set_entity_table_row(swapped_location.archetype_row, old_table_row);
1448 }
1449
1450 new_location
1451 };
1452
1453 *self_location = new_location;
1454 // SAFETY: The entity is valid and has been moved to the new location already.
1455 unsafe {
1456 entities.set(entity.index(), new_location);
1457 }
1458 }
1459
1460 /// Remove the components of `bundle` from `entity`.
1461 ///
1462 /// # Safety
1463 /// - A `BundleInfo` with the corresponding `BundleId` must have been initialized.
1464 #[allow(clippy::too_many_arguments)]
1465 unsafe fn remove_bundle(&mut self, bundle: BundleId) -> EntityLocation {
1466 let entity = self.entity;
1467 let world = &mut self.world;
1468 let location = self.location;
1469 // SAFETY: the caller guarantees that the BundleInfo for this id has been initialized.
1470 let bundle_info = world.bundles.get_unchecked(bundle);
1471
1472 // SAFETY: `archetype_id` exists because it is referenced in `location` which is valid
1473 // and components in `bundle_info` must exist due to this function's safety invariants.
1474 let new_archetype_id = remove_bundle_from_archetype(
1475 &mut world.archetypes,
1476 &mut world.storages,
1477 &world.components,
1478 &world.observers,
1479 location.archetype_id,
1480 bundle_info,
1481 // components from the bundle that are not present on the entity are ignored
1482 true,
1483 )
1484 .expect("intersections should always return a result");
1485
1486 if new_archetype_id == location.archetype_id {
1487 return location;
1488 }
1489
1490 // SAFETY: Archetypes and Bundles cannot be mutably aliased through DeferredWorld
1491 let (old_archetype, bundle_info, mut deferred_world) = unsafe {
1492 let bundle_info: *const BundleInfo = bundle_info;
1493 let world = world.as_unsafe_world_cell();
1494 (
1495 &world.archetypes()[location.archetype_id],
1496 &*bundle_info,
1497 world.into_deferred(),
1498 )
1499 };
1500
1501 // SAFETY: all bundle components exist in World
1502 unsafe {
1503 trigger_on_replace_and_on_remove_hooks_and_observers(
1504 &mut deferred_world,
1505 old_archetype,
1506 entity,
1507 bundle_info,
1508 );
1509 }
1510
1511 let old_archetype = &world.archetypes[location.archetype_id];
1512 for component_id in bundle_info.iter_explicit_components() {
1513 if old_archetype.contains(component_id) {
1514 world.removed_components.send(component_id, entity);
1515
1516 // Make sure to drop components stored in sparse sets.
1517 // Dense components are dropped later in `move_to_and_drop_missing_unchecked`.
1518 if let Some(StorageType::SparseSet) = old_archetype.get_storage_type(component_id) {
1519 world
1520 .storages
1521 .sparse_sets
1522 .get_mut(component_id)
1523 .unwrap()
1524 .remove(entity);
1525 }
1526 }
1527 }
1528
1529 // SAFETY: `new_archetype_id` is a subset of the components in `old_location.archetype_id`
1530 // because it is created by removing a bundle from these components.
1531 let mut new_location = location;
1532 Self::move_entity_from_remove::<true>(
1533 entity,
1534 &mut new_location,
1535 location.archetype_id,
1536 location,
1537 &mut world.entities,
1538 &mut world.archetypes,
1539 &mut world.storages,
1540 new_archetype_id,
1541 );
1542
1543 new_location
1544 }
1545
1546 /// Removes any components in the [`Bundle`] from the entity.
1547 ///
1548 /// See [`EntityCommands::remove`](crate::system::EntityCommands::remove) for more details.
1549 // TODO: BundleRemover?
1550 pub fn remove<T: Bundle>(&mut self) -> &mut Self {
1551 let storages = &mut self.world.storages;
1552 let components = &mut self.world.components;
1553 let bundle_info = self.world.bundles.register_info::<T>(components, storages);
1554
1555 // SAFETY: the `BundleInfo` is initialized above
1556 self.location = unsafe { self.remove_bundle(bundle_info) };
1557
1558 self
1559 }
1560
1561 /// Removes all components in the [`Bundle`] and remove all required components for each component in the bundle
1562 pub fn remove_with_requires<T: Bundle>(&mut self) -> &mut Self {
1563 let storages = &mut self.world.storages;
1564 let components = &mut self.world.components;
1565 let bundles = &mut self.world.bundles;
1566
1567 let bundle_id = bundles.register_contributed_bundle_info::<T>(components, storages);
1568
1569 // SAFETY: the dynamic `BundleInfo` is initialized above
1570 self.location = unsafe { self.remove_bundle(bundle_id) };
1571
1572 self
1573 }
1574
1575 /// Removes any components except those in the [`Bundle`] (and its Required Components) from the entity.
1576 ///
1577 /// See [`EntityCommands::retain`](crate::system::EntityCommands::retain) for more details.
1578 pub fn retain<T: Bundle>(&mut self) -> &mut Self {
1579 let archetypes = &mut self.world.archetypes;
1580 let storages = &mut self.world.storages;
1581 let components = &mut self.world.components;
1582
1583 let retained_bundle = self.world.bundles.register_info::<T>(components, storages);
1584 // SAFETY: `retained_bundle` exists as we just initialized it.
1585 let retained_bundle_info = unsafe { self.world.bundles.get_unchecked(retained_bundle) };
1586 let old_location = self.location;
1587 let old_archetype = &mut archetypes[old_location.archetype_id];
1588
1589 // PERF: this could be stored in an Archetype Edge
1590 let to_remove = &old_archetype
1591 .components()
1592 .filter(|c| !retained_bundle_info.contributed_components().contains(c))
1593 .collect::<Vec<_>>();
1594 let remove_bundle = self.world.bundles.init_dynamic_info(components, to_remove);
1595
1596 // SAFETY: the `BundleInfo` for the components to remove is initialized above
1597 self.location = unsafe { self.remove_bundle(remove_bundle) };
1598 self
1599 }
1600
1601 /// Removes a dynamic [`Component`] from the entity if it exists.
1602 ///
1603 /// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.
1604 ///
1605 /// # Panics
1606 ///
1607 /// Panics if the provided [`ComponentId`] does not exist in the [`World`].
1608 pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {
1609 let components = &mut self.world.components;
1610
1611 let bundle_id = self
1612 .world
1613 .bundles
1614 .init_component_info(components, component_id);
1615
1616 // SAFETY: the `BundleInfo` for this `component_id` is initialized above
1617 self.location = unsafe { self.remove_bundle(bundle_id) };
1618
1619 self
1620 }
1621
1622 /// Removes all components associated with the entity.
1623 pub fn clear(&mut self) -> &mut Self {
1624 let component_ids: Vec<ComponentId> = self.archetype().components().collect();
1625 let components = &mut self.world.components;
1626
1627 let bundle_id = self
1628 .world
1629 .bundles
1630 .init_dynamic_info(components, component_ids.as_slice());
1631
1632 // SAFETY: the `BundleInfo` for this `component_id` is initialized above
1633 self.location = unsafe { self.remove_bundle(bundle_id) };
1634
1635 self
1636 }
1637
1638 /// Despawns the current entity.
1639 ///
1640 /// See [`World::despawn`] for more details.
1641 pub fn despawn(self) {
1642 let world = self.world;
1643 let archetype = &world.archetypes[self.location.archetype_id];
1644
1645 // SAFETY: Archetype cannot be mutably aliased by DeferredWorld
1646 let (archetype, mut deferred_world) = unsafe {
1647 let archetype: *const Archetype = archetype;
1648 let world = world.as_unsafe_world_cell();
1649 (&*archetype, world.into_deferred())
1650 };
1651
1652 // SAFETY: All components in the archetype exist in world
1653 unsafe {
1654 deferred_world.trigger_on_replace(archetype, self.entity, archetype.components());
1655 if archetype.has_replace_observer() {
1656 deferred_world.trigger_observers(ON_REPLACE, self.entity, archetype.components());
1657 }
1658 deferred_world.trigger_on_remove(archetype, self.entity, archetype.components());
1659 if archetype.has_remove_observer() {
1660 deferred_world.trigger_observers(ON_REMOVE, self.entity, archetype.components());
1661 }
1662 }
1663
1664 for component_id in archetype.components() {
1665 world.removed_components.send(component_id, self.entity);
1666 }
1667
1668 // Observers and on_remove hooks may reserve new entities, which
1669 // requires a flush before Entities::free may be called.
1670 world.flush_entities();
1671
1672 let location = world
1673 .entities
1674 .free(self.entity)
1675 .expect("entity should exist at this point.");
1676 let table_row;
1677 let moved_entity;
1678
1679 {
1680 let archetype = &mut world.archetypes[self.location.archetype_id];
1681 let remove_result = archetype.swap_remove(location.archetype_row);
1682 if let Some(swapped_entity) = remove_result.swapped_entity {
1683 let swapped_location = world.entities.get(swapped_entity).unwrap();
1684 // SAFETY: swapped_entity is valid and the swapped entity's components are
1685 // moved to the new location immediately after.
1686 unsafe {
1687 world.entities.set(
1688 swapped_entity.index(),
1689 EntityLocation {
1690 archetype_id: swapped_location.archetype_id,
1691 archetype_row: location.archetype_row,
1692 table_id: swapped_location.table_id,
1693 table_row: swapped_location.table_row,
1694 },
1695 );
1696 }
1697 }
1698 table_row = remove_result.table_row;
1699
1700 for component_id in archetype.sparse_set_components() {
1701 let sparse_set = world.storages.sparse_sets.get_mut(component_id).unwrap();
1702 sparse_set.remove(self.entity);
1703 }
1704 // SAFETY: table rows stored in archetypes always exist
1705 moved_entity = unsafe {
1706 world.storages.tables[archetype.table_id()].swap_remove_unchecked(table_row)
1707 };
1708 };
1709
1710 if let Some(moved_entity) = moved_entity {
1711 let moved_location = world.entities.get(moved_entity).unwrap();
1712 // SAFETY: `moved_entity` is valid and the provided `EntityLocation` accurately reflects
1713 // the current location of the entity and its component data.
1714 unsafe {
1715 world.entities.set(
1716 moved_entity.index(),
1717 EntityLocation {
1718 archetype_id: moved_location.archetype_id,
1719 archetype_row: moved_location.archetype_row,
1720 table_id: moved_location.table_id,
1721 table_row,
1722 },
1723 );
1724 }
1725 world.archetypes[moved_location.archetype_id]
1726 .set_entity_table_row(moved_location.archetype_row, table_row);
1727 }
1728 world.flush();
1729 }
1730
1731 /// Ensures any commands triggered by the actions of Self are applied, equivalent to [`World::flush`]
1732 pub fn flush(self) -> Entity {
1733 self.world.flush();
1734 self.entity
1735 }
1736
1737 /// Gets read-only access to the world that the current entity belongs to.
1738 #[inline]
1739 pub fn world(&self) -> &World {
1740 self.world
1741 }
1742
1743 /// Returns this entity's world.
1744 ///
1745 /// See [`EntityWorldMut::world_scope`] or [`EntityWorldMut::into_world_mut`] for a safe alternative.
1746 ///
1747 /// # Safety
1748 /// Caller must not modify the world in a way that changes the current entity's location
1749 /// If the caller _does_ do something that could change the location, `self.update_location()`
1750 /// must be called before using any other methods on this [`EntityWorldMut`].
1751 #[inline]
1752 pub unsafe fn world_mut(&mut self) -> &mut World {
1753 self.world
1754 }
1755
1756 /// Returns this entity's [`World`], consuming itself.
1757 #[inline]
1758 pub fn into_world_mut(self) -> &'w mut World {
1759 self.world
1760 }
1761
1762 /// Gives mutable access to this entity's [`World`] in a temporary scope.
1763 /// This is a safe alternative to using [`EntityWorldMut::world_mut`].
1764 ///
1765 /// # Examples
1766 ///
1767 /// ```
1768 /// # use bevy_ecs::prelude::*;
1769 /// #[derive(Resource, Default, Clone, Copy)]
1770 /// struct R(u32);
1771 ///
1772 /// # let mut world = World::new();
1773 /// # world.init_resource::<R>();
1774 /// # let mut entity = world.spawn_empty();
1775 /// // This closure gives us temporary access to the world.
1776 /// let new_r = entity.world_scope(|world: &mut World| {
1777 /// // Mutate the world while we have access to it.
1778 /// let mut r = world.resource_mut::<R>();
1779 /// r.0 += 1;
1780 ///
1781 /// // Return a value from the world before giving it back to the `EntityWorldMut`.
1782 /// *r
1783 /// });
1784 /// # assert_eq!(new_r.0, 1);
1785 /// ```
1786 pub fn world_scope<U>(&mut self, f: impl FnOnce(&mut World) -> U) -> U {
1787 struct Guard<'w, 'a> {
1788 entity_mut: &'a mut EntityWorldMut<'w>,
1789 }
1790
1791 impl Drop for Guard<'_, '_> {
1792 #[inline]
1793 fn drop(&mut self) {
1794 self.entity_mut.update_location();
1795 }
1796 }
1797
1798 // When `guard` is dropped at the end of this scope,
1799 // it will update the cached `EntityLocation` for this instance.
1800 // This will run even in case the closure `f` unwinds.
1801 let guard = Guard { entity_mut: self };
1802 f(guard.entity_mut.world)
1803 }
1804
1805 /// Updates the internal entity location to match the current location in the internal
1806 /// [`World`].
1807 ///
1808 /// This is *only* required when using the unsafe function [`EntityWorldMut::world_mut`],
1809 /// which enables the location to change.
1810 pub fn update_location(&mut self) {
1811 self.location = self.world.entities().get(self.entity).unwrap();
1812 }
1813
1814 /// Gets an Entry into the world for this entity and component for in-place manipulation.
1815 ///
1816 /// The type parameter specifies which component to get.
1817 ///
1818 /// # Examples
1819 ///
1820 /// ```
1821 /// # use bevy_ecs::prelude::*;
1822 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
1823 /// struct Comp(u32);
1824 ///
1825 /// # let mut world = World::new();
1826 /// let mut entity = world.spawn_empty();
1827 /// entity.entry().or_insert_with(|| Comp(4));
1828 /// # let entity_id = entity.id();
1829 /// assert_eq!(world.query::<&Comp>().single(&world).0, 4);
1830 ///
1831 /// # let mut entity = world.get_entity_mut(entity_id).unwrap();
1832 /// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);
1833 /// assert_eq!(world.query::<&Comp>().single(&world).0, 5);
1834 /// ```
1835 pub fn entry<'a, T: Component>(&'a mut self) -> Entry<'w, 'a, T> {
1836 if self.contains::<T>() {
1837 Entry::Occupied(OccupiedEntry {
1838 entity_world: self,
1839 _marker: PhantomData,
1840 })
1841 } else {
1842 Entry::Vacant(VacantEntry {
1843 entity_world: self,
1844 _marker: PhantomData,
1845 })
1846 }
1847 }
1848
1849 /// Triggers the given `event` for this entity, which will run any observers watching for it.
1850 pub fn trigger(&mut self, event: impl Event) -> &mut Self {
1851 self.world.trigger_targets(event, self.entity);
1852 self
1853 }
1854
1855 /// Creates an [`Observer`] listening for events of type `E` targeting this entity.
1856 /// In order to trigger the callback the entity must also match the query when the event is fired.
1857 pub fn observe<E: Event, B: Bundle, M>(
1858 &mut self,
1859 observer: impl IntoObserverSystem<E, B, M>,
1860 ) -> &mut Self {
1861 self.world
1862 .spawn(Observer::new(observer).with_entity(self.entity));
1863 self
1864 }
1865}
1866
1867/// # Safety
1868/// All components in the archetype must exist in world
1869unsafe fn trigger_on_replace_and_on_remove_hooks_and_observers(
1870 deferred_world: &mut DeferredWorld,
1871 archetype: &Archetype,
1872 entity: Entity,
1873 bundle_info: &BundleInfo,
1874) {
1875 deferred_world.trigger_on_replace(archetype, entity, bundle_info.iter_explicit_components());
1876 if archetype.has_replace_observer() {
1877 deferred_world.trigger_observers(
1878 ON_REPLACE,
1879 entity,
1880 bundle_info.iter_explicit_components(),
1881 );
1882 }
1883 deferred_world.trigger_on_remove(archetype, entity, bundle_info.iter_explicit_components());
1884 if archetype.has_remove_observer() {
1885 deferred_world.trigger_observers(ON_REMOVE, entity, bundle_info.iter_explicit_components());
1886 }
1887}
1888
1889const QUERY_MISMATCH_ERROR: &str = "Query does not match the current entity";
1890
1891/// A view into a single entity and component in a world, which may either be vacant or occupied.
1892///
1893/// This `enum` can only be constructed from the [`entry`] method on [`EntityWorldMut`].
1894///
1895/// [`entry`]: EntityWorldMut::entry
1896pub enum Entry<'w, 'a, T: Component> {
1897 /// An occupied entry.
1898 Occupied(OccupiedEntry<'w, 'a, T>),
1899 /// A vacant entry.
1900 Vacant(VacantEntry<'w, 'a, T>),
1901}
1902
1903impl<'w, 'a, T: Component> Entry<'w, 'a, T> {
1904 /// Provides in-place mutable access to an occupied entry.
1905 ///
1906 /// # Examples
1907 ///
1908 /// ```
1909 /// # use bevy_ecs::prelude::*;
1910 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
1911 /// struct Comp(u32);
1912 ///
1913 /// # let mut world = World::new();
1914 /// let mut entity = world.spawn(Comp(0));
1915 ///
1916 /// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);
1917 /// assert_eq!(world.query::<&Comp>().single(&world).0, 1);
1918 /// ```
1919 #[inline]
1920 pub fn and_modify<F: FnOnce(Mut<'_, T>)>(self, f: F) -> Self {
1921 match self {
1922 Entry::Occupied(mut entry) => {
1923 f(entry.get_mut());
1924 Entry::Occupied(entry)
1925 }
1926 Entry::Vacant(entry) => Entry::Vacant(entry),
1927 }
1928 }
1929
1930 /// Replaces the component of the entry, and returns an [`OccupiedEntry`].
1931 ///
1932 /// # Examples
1933 ///
1934 /// ```
1935 /// # use bevy_ecs::prelude::*;
1936 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
1937 /// struct Comp(u32);
1938 ///
1939 /// # let mut world = World::new();
1940 /// let mut entity = world.spawn_empty();
1941 ///
1942 /// let entry = entity.entry().insert_entry(Comp(4));
1943 /// assert_eq!(entry.get(), &Comp(4));
1944 ///
1945 /// let entry = entity.entry().insert_entry(Comp(2));
1946 /// assert_eq!(entry.get(), &Comp(2));
1947 /// ```
1948 #[inline]
1949 pub fn insert_entry(self, component: T) -> OccupiedEntry<'w, 'a, T> {
1950 match self {
1951 Entry::Occupied(mut entry) => {
1952 entry.insert(component);
1953 entry
1954 }
1955 Entry::Vacant(entry) => entry.insert_entry(component),
1956 }
1957 }
1958
1959 /// Ensures the entry has this component by inserting the given default if empty, and
1960 /// returns a mutable reference to this component in the entry.
1961 ///
1962 /// # Examples
1963 ///
1964 /// ```
1965 /// # use bevy_ecs::prelude::*;
1966 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
1967 /// struct Comp(u32);
1968 ///
1969 /// # let mut world = World::new();
1970 /// let mut entity = world.spawn_empty();
1971 ///
1972 /// entity.entry().or_insert(Comp(4));
1973 /// # let entity_id = entity.id();
1974 /// assert_eq!(world.query::<&Comp>().single(&world).0, 4);
1975 ///
1976 /// # let mut entity = world.get_entity_mut(entity_id).unwrap();
1977 /// entity.entry().or_insert(Comp(15)).0 *= 2;
1978 /// assert_eq!(world.query::<&Comp>().single(&world).0, 8);
1979 /// ```
1980 #[inline]
1981 pub fn or_insert(self, default: T) -> Mut<'a, T> {
1982 match self {
1983 Entry::Occupied(entry) => entry.into_mut(),
1984 Entry::Vacant(entry) => entry.insert(default),
1985 }
1986 }
1987
1988 /// Ensures the entry has this component by inserting the result of the default function if
1989 /// empty, and returns a mutable reference to this component in the entry.
1990 ///
1991 /// # Examples
1992 ///
1993 /// ```
1994 /// # use bevy_ecs::prelude::*;
1995 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
1996 /// struct Comp(u32);
1997 ///
1998 /// # let mut world = World::new();
1999 /// let mut entity = world.spawn_empty();
2000 ///
2001 /// entity.entry().or_insert_with(|| Comp(4));
2002 /// assert_eq!(world.query::<&Comp>().single(&world).0, 4);
2003 /// ```
2004 #[inline]
2005 pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> Mut<'a, T> {
2006 match self {
2007 Entry::Occupied(entry) => entry.into_mut(),
2008 Entry::Vacant(entry) => entry.insert(default()),
2009 }
2010 }
2011}
2012
2013impl<'w, 'a, T: Component + Default> Entry<'w, 'a, T> {
2014 /// Ensures the entry has this component by inserting the default value if empty, and
2015 /// returns a mutable reference to this component in the entry.
2016 ///
2017 /// # Examples
2018 ///
2019 /// ```
2020 /// # use bevy_ecs::prelude::*;
2021 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2022 /// struct Comp(u32);
2023 ///
2024 /// # let mut world = World::new();
2025 /// let mut entity = world.spawn_empty();
2026 ///
2027 /// entity.entry::<Comp>().or_default();
2028 /// assert_eq!(world.query::<&Comp>().single(&world).0, 0);
2029 /// ```
2030 #[inline]
2031 pub fn or_default(self) -> Mut<'a, T> {
2032 match self {
2033 Entry::Occupied(entry) => entry.into_mut(),
2034 Entry::Vacant(entry) => entry.insert(Default::default()),
2035 }
2036 }
2037}
2038
2039/// A view into an occupied entry in a [`EntityWorldMut`]. It is part of the [`Entry`] enum.
2040///
2041/// The contained entity must have the component type parameter if we have this struct.
2042pub struct OccupiedEntry<'w, 'a, T: Component> {
2043 entity_world: &'a mut EntityWorldMut<'w>,
2044 _marker: PhantomData<T>,
2045}
2046
2047impl<'w, 'a, T: Component> OccupiedEntry<'w, 'a, T> {
2048 /// Gets a reference to the component in the entry.
2049 ///
2050 /// # Examples
2051 ///
2052 /// ```
2053 /// # use bevy_ecs::{prelude::*, world::Entry};
2054 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2055 /// struct Comp(u32);
2056 ///
2057 /// # let mut world = World::new();
2058 /// let mut entity = world.spawn(Comp(5));
2059 ///
2060 /// if let Entry::Occupied(o) = entity.entry::<Comp>() {
2061 /// assert_eq!(o.get().0, 5);
2062 /// }
2063 /// ```
2064 #[inline]
2065 pub fn get(&self) -> &T {
2066 // This shouldn't panic because if we have an OccupiedEntry the component must exist.
2067 self.entity_world.get::<T>().unwrap()
2068 }
2069
2070 /// Gets a mutable reference to the component in the entry.
2071 ///
2072 /// If you need a reference to the `OccupiedEntry` which may outlive the destruction of
2073 /// the `Entry` value, see [`into_mut`].
2074 ///
2075 /// [`into_mut`]: Self::into_mut
2076 ///
2077 /// # Examples
2078 ///
2079 /// ```
2080 /// # use bevy_ecs::{prelude::*, world::Entry};
2081 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2082 /// struct Comp(u32);
2083 ///
2084 /// # let mut world = World::new();
2085 /// let mut entity = world.spawn(Comp(5));
2086 ///
2087 /// if let Entry::Occupied(mut o) = entity.entry::<Comp>() {
2088 /// o.get_mut().0 += 10;
2089 /// assert_eq!(o.get().0, 15);
2090 ///
2091 /// // We can use the same Entry multiple times.
2092 /// o.get_mut().0 += 2
2093 /// }
2094 ///
2095 /// assert_eq!(world.query::<&Comp>().single(&world).0, 17);
2096 /// ```
2097 #[inline]
2098 pub fn get_mut(&mut self) -> Mut<'_, T> {
2099 // This shouldn't panic because if we have an OccupiedEntry the component must exist.
2100 self.entity_world.get_mut::<T>().unwrap()
2101 }
2102
2103 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry with
2104 /// a lifetime bound to the `EntityWorldMut`.
2105 ///
2106 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
2107 ///
2108 /// [`get_mut`]: Self::get_mut
2109 ///
2110 /// # Examples
2111 ///
2112 /// ```
2113 /// # use bevy_ecs::{prelude::*, world::Entry};
2114 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2115 /// struct Comp(u32);
2116 ///
2117 /// # let mut world = World::new();
2118 /// let mut entity = world.spawn(Comp(5));
2119 ///
2120 /// if let Entry::Occupied(o) = entity.entry::<Comp>() {
2121 /// o.into_mut().0 += 10;
2122 /// }
2123 ///
2124 /// assert_eq!(world.query::<&Comp>().single(&world).0, 15);
2125 /// ```
2126 #[inline]
2127 pub fn into_mut(self) -> Mut<'a, T> {
2128 // This shouldn't panic because if we have an OccupiedEntry the component must exist.
2129 self.entity_world.get_mut().unwrap()
2130 }
2131
2132 /// Replaces the component of the entry.
2133 ///
2134 /// # Examples
2135 ///
2136 /// ```
2137 /// # use bevy_ecs::{prelude::*, world::Entry};
2138 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2139 /// struct Comp(u32);
2140 ///
2141 /// # let mut world = World::new();
2142 /// let mut entity = world.spawn(Comp(5));
2143 ///
2144 /// if let Entry::Occupied(mut o) = entity.entry::<Comp>() {
2145 /// o.insert(Comp(10));
2146 /// }
2147 ///
2148 /// assert_eq!(world.query::<&Comp>().single(&world).0, 10);
2149 /// ```
2150 #[inline]
2151 pub fn insert(&mut self, component: T) {
2152 self.entity_world.insert(component);
2153 }
2154
2155 /// Removes the component from the entry and returns it.
2156 ///
2157 /// # Examples
2158 ///
2159 /// ```
2160 /// # use bevy_ecs::{prelude::*, world::Entry};
2161 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2162 /// struct Comp(u32);
2163 ///
2164 /// # let mut world = World::new();
2165 /// let mut entity = world.spawn(Comp(5));
2166 ///
2167 /// if let Entry::Occupied(o) = entity.entry::<Comp>() {
2168 /// assert_eq!(o.take(), Comp(5));
2169 /// }
2170 ///
2171 /// assert_eq!(world.query::<&Comp>().iter(&world).len(), 0);
2172 /// ```
2173 #[inline]
2174 pub fn take(self) -> T {
2175 // This shouldn't panic because if we have an OccupiedEntry the component must exist.
2176 self.entity_world.take().unwrap()
2177 }
2178}
2179
2180/// A view into a vacant entry in a [`EntityWorldMut`]. It is part of the [`Entry`] enum.
2181pub struct VacantEntry<'w, 'a, T: Component> {
2182 entity_world: &'a mut EntityWorldMut<'w>,
2183 _marker: PhantomData<T>,
2184}
2185
2186impl<'w, 'a, T: Component> VacantEntry<'w, 'a, T> {
2187 /// Inserts the component into the `VacantEntry` and returns a mutable reference to it.
2188 ///
2189 /// # Examples
2190 ///
2191 /// ```
2192 /// # use bevy_ecs::{prelude::*, world::Entry};
2193 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2194 /// struct Comp(u32);
2195 ///
2196 /// # let mut world = World::new();
2197 /// let mut entity = world.spawn_empty();
2198 ///
2199 /// if let Entry::Vacant(v) = entity.entry::<Comp>() {
2200 /// v.insert(Comp(10));
2201 /// }
2202 ///
2203 /// assert_eq!(world.query::<&Comp>().single(&world).0, 10);
2204 /// ```
2205 #[inline]
2206 pub fn insert(self, component: T) -> Mut<'a, T> {
2207 self.entity_world.insert(component);
2208 // This shouldn't panic because we just added this component
2209 self.entity_world.get_mut::<T>().unwrap()
2210 }
2211
2212 /// Inserts the component into the `VacantEntry` and returns an `OccupiedEntry`.
2213 ///
2214 /// # Examples
2215 ///
2216 /// ```
2217 /// # use bevy_ecs::{prelude::*, world::Entry};
2218 /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
2219 /// struct Comp(u32);
2220 ///
2221 /// # let mut world = World::new();
2222 /// let mut entity = world.spawn_empty();
2223 ///
2224 /// if let Entry::Vacant(v) = entity.entry::<Comp>() {
2225 /// v.insert_entry(Comp(10));
2226 /// }
2227 ///
2228 /// assert_eq!(world.query::<&Comp>().single(&world).0, 10);
2229 /// ```
2230 #[inline]
2231 pub fn insert_entry(self, component: T) -> OccupiedEntry<'w, 'a, T> {
2232 self.entity_world.insert(component);
2233 OccupiedEntry {
2234 entity_world: self.entity_world,
2235 _marker: PhantomData,
2236 }
2237 }
2238}
2239
2240/// Provides read-only access to a single entity and some of its components defined by the contained [`Access`].
2241///
2242/// To define the access when used as a [`QueryData`](crate::query::QueryData),
2243/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).
2244/// The `FilteredEntityRef` must be the entire `QueryData`, and not nested inside a tuple with other data.
2245///
2246/// ```
2247/// # use bevy_ecs::{prelude::*, world::FilteredEntityRef};
2248/// #
2249/// # #[derive(Component)]
2250/// # struct A;
2251/// #
2252/// # let mut world = World::new();
2253/// # world.spawn(A);
2254/// #
2255/// // This gives the `FilteredEntityRef` access to `&A`.
2256/// let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
2257/// .data::<&A>()
2258/// .build();
2259///
2260/// let filtered_entity: FilteredEntityRef = query.single(&mut world);
2261/// let component: &A = filtered_entity.get().unwrap();
2262///
2263/// // Here `FilteredEntityRef` is nested in a tuple, so it does not have access to `&A`.
2264/// let mut query = QueryBuilder::<(Entity, FilteredEntityRef)>::new(&mut world)
2265/// .data::<&A>()
2266/// .build();
2267///
2268/// let (_, filtered_entity) = query.single(&mut world);
2269/// assert!(filtered_entity.get::<A>().is_none());
2270/// ```
2271#[derive(Clone)]
2272pub struct FilteredEntityRef<'w> {
2273 entity: UnsafeEntityCell<'w>,
2274 access: Access<ComponentId>,
2275}
2276
2277impl<'w> FilteredEntityRef<'w> {
2278 /// # Safety
2279 /// - No `&mut World` can exist from the underlying `UnsafeWorldCell`
2280 /// - If `access` takes read access to a component no mutable reference to that
2281 /// component can exist at the same time as the returned [`FilteredEntityMut`]
2282 /// - If `access` takes any access for a component `entity` must have that component.
2283 #[inline]
2284 pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: Access<ComponentId>) -> Self {
2285 Self { entity, access }
2286 }
2287
2288 /// Returns the [ID](Entity) of the current entity.
2289 #[inline]
2290 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
2291 pub fn id(&self) -> Entity {
2292 self.entity.id()
2293 }
2294
2295 /// Gets metadata indicating the location where the current entity is stored.
2296 #[inline]
2297 pub fn location(&self) -> EntityLocation {
2298 self.entity.location()
2299 }
2300
2301 /// Returns the archetype that the current entity belongs to.
2302 #[inline]
2303 pub fn archetype(&self) -> &Archetype {
2304 self.entity.archetype()
2305 }
2306
2307 /// Returns a reference to the underlying [`Access`].
2308 #[inline]
2309 pub fn access(&self) -> &Access<ComponentId> {
2310 &self.access
2311 }
2312
2313 /// Returns `true` if the current entity has a component of type `T`.
2314 /// Otherwise, this returns `false`.
2315 ///
2316 /// ## Notes
2317 ///
2318 /// If you do not know the concrete type of a component, consider using
2319 /// [`Self::contains_id`] or [`Self::contains_type_id`].
2320 #[inline]
2321 pub fn contains<T: Component>(&self) -> bool {
2322 self.contains_type_id(TypeId::of::<T>())
2323 }
2324
2325 /// Returns `true` if the current entity has a component identified by `component_id`.
2326 /// Otherwise, this returns false.
2327 ///
2328 /// ## Notes
2329 ///
2330 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
2331 /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
2332 /// [`Self::contains_type_id`].
2333 #[inline]
2334 pub fn contains_id(&self, component_id: ComponentId) -> bool {
2335 self.entity.contains_id(component_id)
2336 }
2337
2338 /// Returns `true` if the current entity has a component with the type identified by `type_id`.
2339 /// Otherwise, this returns false.
2340 ///
2341 /// ## Notes
2342 ///
2343 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
2344 /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
2345 #[inline]
2346 pub fn contains_type_id(&self, type_id: TypeId) -> bool {
2347 self.entity.contains_type_id(type_id)
2348 }
2349
2350 /// Gets access to the component of type `T` for the current entity.
2351 /// Returns `None` if the entity does not have a component of type `T`.
2352 #[inline]
2353 pub fn get<T: Component>(&self) -> Option<&'w T> {
2354 let id = self.entity.world().components().get_id(TypeId::of::<T>())?;
2355 self.access
2356 .has_component_read(id)
2357 // SAFETY: We have read access
2358 .then(|| unsafe { self.entity.get() })
2359 .flatten()
2360 }
2361
2362 /// Gets access to the component of type `T` for the current entity,
2363 /// including change detection information as a [`Ref`].
2364 ///
2365 /// Returns `None` if the entity does not have a component of type `T`.
2366 #[inline]
2367 pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {
2368 let id = self.entity.world().components().get_id(TypeId::of::<T>())?;
2369 self.access
2370 .has_component_read(id)
2371 // SAFETY: We have read access
2372 .then(|| unsafe { self.entity.get_ref() })
2373 .flatten()
2374 }
2375
2376 /// Retrieves the change ticks for the given component. This can be useful for implementing change
2377 /// detection in custom runtimes.
2378 #[inline]
2379 pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
2380 let id = self.entity.world().components().get_id(TypeId::of::<T>())?;
2381 self.access
2382 .has_component_read(id)
2383 // SAFETY: We have read access
2384 .then(|| unsafe { self.entity.get_change_ticks::<T>() })
2385 .flatten()
2386 }
2387
2388 /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
2389 /// detection in custom runtimes.
2390 ///
2391 /// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only
2392 /// use this in cases where the actual component types are not known at
2393 /// compile time.**
2394 #[inline]
2395 pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
2396 self.access
2397 .has_component_read(component_id)
2398 // SAFETY: We have read access
2399 .then(|| unsafe { self.entity.get_change_ticks_by_id(component_id) })
2400 .flatten()
2401 }
2402
2403 /// Gets the component of the given [`ComponentId`] from the entity.
2404 ///
2405 /// **You should prefer to use the typed API [`Self::get`] where possible and only
2406 /// use this in cases where the actual component types are not known at
2407 /// compile time.**
2408 ///
2409 /// Unlike [`FilteredEntityRef::get`], this returns a raw pointer to the component,
2410 /// which is only valid while the [`FilteredEntityRef`] is alive.
2411 #[inline]
2412 pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {
2413 self.access
2414 .has_component_read(component_id)
2415 // SAFETY: We have read access
2416 .then(|| unsafe { self.entity.get_by_id(component_id) })
2417 .flatten()
2418 }
2419}
2420
2421impl<'w> From<FilteredEntityMut<'w>> for FilteredEntityRef<'w> {
2422 #[inline]
2423 fn from(entity_mut: FilteredEntityMut<'w>) -> Self {
2424 // SAFETY:
2425 // - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
2426 unsafe { FilteredEntityRef::new(entity_mut.entity, entity_mut.access) }
2427 }
2428}
2429
2430impl<'a> From<&'a FilteredEntityMut<'_>> for FilteredEntityRef<'a> {
2431 #[inline]
2432 fn from(entity_mut: &'a FilteredEntityMut<'_>) -> Self {
2433 // SAFETY:
2434 // - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
2435 unsafe { FilteredEntityRef::new(entity_mut.entity, entity_mut.access.clone()) }
2436 }
2437}
2438
2439impl<'a> From<EntityRef<'a>> for FilteredEntityRef<'a> {
2440 fn from(entity: EntityRef<'a>) -> Self {
2441 // SAFETY:
2442 // - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.
2443 unsafe {
2444 let mut access = Access::default();
2445 access.read_all();
2446 FilteredEntityRef::new(entity.0, access)
2447 }
2448 }
2449}
2450
2451impl<'a> From<&'a EntityRef<'_>> for FilteredEntityRef<'a> {
2452 fn from(entity: &'a EntityRef<'_>) -> Self {
2453 // SAFETY:
2454 // - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.
2455 unsafe {
2456 let mut access = Access::default();
2457 access.read_all();
2458 FilteredEntityRef::new(entity.0, access)
2459 }
2460 }
2461}
2462
2463impl<'a> From<EntityMut<'a>> for FilteredEntityRef<'a> {
2464 fn from(entity: EntityMut<'a>) -> Self {
2465 // SAFETY:
2466 // - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
2467 unsafe {
2468 let mut access = Access::default();
2469 access.read_all();
2470 FilteredEntityRef::new(entity.0, access)
2471 }
2472 }
2473}
2474
2475impl<'a> From<&'a EntityMut<'_>> for FilteredEntityRef<'a> {
2476 fn from(entity: &'a EntityMut<'_>) -> Self {
2477 // SAFETY:
2478 // - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.
2479 unsafe {
2480 let mut access = Access::default();
2481 access.read_all();
2482 FilteredEntityRef::new(entity.0, access)
2483 }
2484 }
2485}
2486
2487impl<'a> From<EntityWorldMut<'a>> for FilteredEntityRef<'a> {
2488 fn from(entity: EntityWorldMut<'a>) -> Self {
2489 // SAFETY:
2490 // - `EntityWorldMut` guarantees exclusive access to the entire world.
2491 unsafe {
2492 let mut access = Access::default();
2493 access.read_all();
2494 FilteredEntityRef::new(entity.into_unsafe_entity_cell(), access)
2495 }
2496 }
2497}
2498
2499impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a> {
2500 fn from(entity: &'a EntityWorldMut<'_>) -> Self {
2501 // SAFETY:
2502 // - `EntityWorldMut` guarantees exclusive access to the entire world.
2503 unsafe {
2504 let mut access = Access::default();
2505 access.read_all();
2506 FilteredEntityRef::new(entity.as_unsafe_entity_cell_readonly(), access)
2507 }
2508 }
2509}
2510
2511/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
2512///
2513/// To define the access when used as a [`QueryData`](crate::query::QueryData),
2514/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).
2515/// The `FilteredEntityMut` must be the entire `QueryData`, and not nested inside a tuple with other data.
2516///
2517/// ```
2518/// # use bevy_ecs::{prelude::*, world::FilteredEntityMut};
2519/// #
2520/// # #[derive(Component)]
2521/// # struct A;
2522/// #
2523/// # let mut world = World::new();
2524/// # world.spawn(A);
2525/// #
2526/// // This gives the `FilteredEntityMut` access to `&mut A`.
2527/// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)
2528/// .data::<&mut A>()
2529/// .build();
2530///
2531/// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world);
2532/// let component: Mut<A> = filtered_entity.get_mut().unwrap();
2533///
2534/// // Here `FilteredEntityMut` is nested in a tuple, so it does not have access to `&mut A`.
2535/// let mut query = QueryBuilder::<(Entity, FilteredEntityMut)>::new(&mut world)
2536/// .data::<&mut A>()
2537/// .build();
2538///
2539/// let (_, mut filtered_entity) = query.single_mut(&mut world);
2540/// assert!(filtered_entity.get_mut::<A>().is_none());
2541/// ```
2542pub struct FilteredEntityMut<'w> {
2543 entity: UnsafeEntityCell<'w>,
2544 access: Access<ComponentId>,
2545}
2546
2547impl<'w> FilteredEntityMut<'w> {
2548 /// # Safety
2549 /// - No `&mut World` can exist from the underlying `UnsafeWorldCell`
2550 /// - If `access` takes read access to a component no mutable reference to that
2551 /// component can exist at the same time as the returned [`FilteredEntityMut`]
2552 /// - If `access` takes write access to a component, no reference to that component
2553 /// may exist at the same time as the returned [`FilteredEntityMut`]
2554 /// - If `access` takes any access for a component `entity` must have that component.
2555 #[inline]
2556 pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: Access<ComponentId>) -> Self {
2557 Self { entity, access }
2558 }
2559
2560 /// Returns a new instance with a shorter lifetime.
2561 /// This is useful if you have `&mut FilteredEntityMut`, but you need `FilteredEntityMut`.
2562 pub fn reborrow(&mut self) -> FilteredEntityMut<'_> {
2563 // SAFETY: We have exclusive access to the entire entity and its components.
2564 unsafe { Self::new(self.entity, self.access.clone()) }
2565 }
2566
2567 /// Gets read-only access to all of the entity's components.
2568 #[inline]
2569 pub fn as_readonly(&self) -> FilteredEntityRef<'_> {
2570 FilteredEntityRef::from(self)
2571 }
2572
2573 /// Returns the [ID](Entity) of the current entity.
2574 #[inline]
2575 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
2576 pub fn id(&self) -> Entity {
2577 self.entity.id()
2578 }
2579
2580 /// Gets metadata indicating the location where the current entity is stored.
2581 #[inline]
2582 pub fn location(&self) -> EntityLocation {
2583 self.entity.location()
2584 }
2585
2586 /// Returns the archetype that the current entity belongs to.
2587 #[inline]
2588 pub fn archetype(&self) -> &Archetype {
2589 self.entity.archetype()
2590 }
2591
2592 /// Returns a reference to the underlying [`Access`].
2593 #[inline]
2594 pub fn access(&self) -> &Access<ComponentId> {
2595 &self.access
2596 }
2597
2598 /// Returns `true` if the current entity has a component of type `T`.
2599 /// Otherwise, this returns `false`.
2600 ///
2601 /// ## Notes
2602 ///
2603 /// If you do not know the concrete type of a component, consider using
2604 /// [`Self::contains_id`] or [`Self::contains_type_id`].
2605 #[inline]
2606 pub fn contains<T: Component>(&self) -> bool {
2607 self.contains_type_id(TypeId::of::<T>())
2608 }
2609
2610 /// Returns `true` if the current entity has a component identified by `component_id`.
2611 /// Otherwise, this returns false.
2612 ///
2613 /// ## Notes
2614 ///
2615 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
2616 /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
2617 /// [`Self::contains_type_id`].
2618 #[inline]
2619 pub fn contains_id(&self, component_id: ComponentId) -> bool {
2620 self.entity.contains_id(component_id)
2621 }
2622
2623 /// Returns `true` if the current entity has a component with the type identified by `type_id`.
2624 /// Otherwise, this returns false.
2625 ///
2626 /// ## Notes
2627 ///
2628 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
2629 /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
2630 #[inline]
2631 pub fn contains_type_id(&self, type_id: TypeId) -> bool {
2632 self.entity.contains_type_id(type_id)
2633 }
2634
2635 /// Gets access to the component of type `T` for the current entity.
2636 /// Returns `None` if the entity does not have a component of type `T`.
2637 #[inline]
2638 pub fn get<T: Component>(&self) -> Option<&'_ T> {
2639 self.as_readonly().get()
2640 }
2641
2642 /// Gets access to the component of type `T` for the current entity,
2643 /// including change detection information as a [`Ref`].
2644 ///
2645 /// Returns `None` if the entity does not have a component of type `T`.
2646 #[inline]
2647 pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
2648 self.as_readonly().get_ref()
2649 }
2650
2651 /// Gets mutable access to the component of type `T` for the current entity.
2652 /// Returns `None` if the entity does not have a component of type `T`.
2653 #[inline]
2654 pub fn get_mut<T: Component>(&mut self) -> Option<Mut<'_, T>> {
2655 let id = self.entity.world().components().get_id(TypeId::of::<T>())?;
2656 self.access
2657 .has_component_write(id)
2658 // SAFETY: We have write access
2659 .then(|| unsafe { self.entity.get_mut() })
2660 .flatten()
2661 }
2662
2663 /// Consumes self and gets mutable access to the component of type `T`
2664 /// with the world `'w` lifetime for the current entity.
2665 /// Returns `None` if the entity does not have a component of type `T`.
2666 #[inline]
2667 pub fn into_mut<T: Component>(self) -> Option<Mut<'w, T>> {
2668 let id = self.entity.world().components().get_id(TypeId::of::<T>())?;
2669 self.access
2670 .has_component_write(id)
2671 // SAFETY: We have write access
2672 .then(|| unsafe { self.entity.get_mut() })
2673 .flatten()
2674 }
2675
2676 /// Retrieves the change ticks for the given component. This can be useful for implementing change
2677 /// detection in custom runtimes.
2678 #[inline]
2679 pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
2680 self.as_readonly().get_change_ticks::<T>()
2681 }
2682
2683 /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
2684 /// detection in custom runtimes.
2685 ///
2686 /// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only
2687 /// use this in cases where the actual component types are not known at
2688 /// compile time.**
2689 #[inline]
2690 pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
2691 self.as_readonly().get_change_ticks_by_id(component_id)
2692 }
2693
2694 /// Gets the component of the given [`ComponentId`] from the entity.
2695 ///
2696 /// **You should prefer to use the typed API [`Self::get`] where possible and only
2697 /// use this in cases where the actual component types are not known at
2698 /// compile time.**
2699 ///
2700 /// Unlike [`FilteredEntityMut::get`], this returns a raw pointer to the component,
2701 /// which is only valid while the [`FilteredEntityMut`] is alive.
2702 #[inline]
2703 pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
2704 self.as_readonly().get_by_id(component_id)
2705 }
2706
2707 /// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
2708 ///
2709 /// **You should prefer to use the typed API [`Self::get_mut`] where possible and only
2710 /// use this in cases where the actual component types are not known at
2711 /// compile time.**
2712 ///
2713 /// Unlike [`FilteredEntityMut::get_mut`], this returns a raw pointer to the component,
2714 /// which is only valid while the [`FilteredEntityMut`] is alive.
2715 #[inline]
2716 pub fn get_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
2717 self.access
2718 .has_component_write(component_id)
2719 // SAFETY: We have write access
2720 .then(|| unsafe { self.entity.get_mut_by_id(component_id) })
2721 .flatten()
2722 }
2723}
2724
2725impl<'a> From<EntityMut<'a>> for FilteredEntityMut<'a> {
2726 fn from(entity: EntityMut<'a>) -> Self {
2727 // SAFETY:
2728 // - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.
2729 unsafe {
2730 let mut access = Access::default();
2731 access.read_all();
2732 access.write_all();
2733 FilteredEntityMut::new(entity.0, access)
2734 }
2735 }
2736}
2737
2738impl<'a> From<&'a mut EntityMut<'_>> for FilteredEntityMut<'a> {
2739 fn from(entity: &'a mut EntityMut<'_>) -> Self {
2740 // SAFETY:
2741 // - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.
2742 unsafe {
2743 let mut access = Access::default();
2744 access.read_all();
2745 access.write_all();
2746 FilteredEntityMut::new(entity.0, access)
2747 }
2748 }
2749}
2750
2751impl<'a> From<EntityWorldMut<'a>> for FilteredEntityMut<'a> {
2752 fn from(entity: EntityWorldMut<'a>) -> Self {
2753 // SAFETY:
2754 // - `EntityWorldMut` guarantees exclusive access to the entire world.
2755 unsafe {
2756 let mut access = Access::default();
2757 access.read_all();
2758 access.write_all();
2759 FilteredEntityMut::new(entity.into_unsafe_entity_cell(), access)
2760 }
2761 }
2762}
2763
2764impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a> {
2765 fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {
2766 // SAFETY:
2767 // - `EntityWorldMut` guarantees exclusive access to the entire world.
2768 unsafe {
2769 let mut access = Access::default();
2770 access.read_all();
2771 access.write_all();
2772 FilteredEntityMut::new(entity.as_unsafe_entity_cell(), access)
2773 }
2774 }
2775}
2776
2777/// Error type returned by [`TryFrom`] conversions from filtered entity types
2778/// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types
2779/// ([`EntityRef`]/[`EntityMut`]).
2780#[derive(Error, Display, Debug)]
2781pub enum TryFromFilteredError {
2782 /// Error indicating that the filtered entity does not have read access to
2783 /// all components.
2784 #[display(
2785 "Conversion failed, filtered entity ref does not have read access to all components"
2786 )]
2787 MissingReadAllAccess,
2788 /// Error indicating that the filtered entity does not have write access to
2789 /// all components.
2790 #[display(
2791 "Conversion failed, filtered entity ref does not have write access to all components"
2792 )]
2793 MissingWriteAllAccess,
2794}
2795
2796/// Provides read-only access to a single entity and all its components, save
2797/// for an explicitly-enumerated set.
2798#[derive(Clone)]
2799pub struct EntityRefExcept<'w, B>
2800where
2801 B: Bundle,
2802{
2803 entity: UnsafeEntityCell<'w>,
2804 phantom: PhantomData<B>,
2805}
2806
2807impl<'w, B> EntityRefExcept<'w, B>
2808where
2809 B: Bundle,
2810{
2811 /// # Safety
2812 /// Other users of `UnsafeEntityCell` must only have mutable access to the components in `B`.
2813 pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>) -> Self {
2814 Self {
2815 entity,
2816 phantom: PhantomData,
2817 }
2818 }
2819
2820 /// Returns the [ID](Entity) of the current entity.
2821 #[inline]
2822 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
2823 pub fn id(&self) -> Entity {
2824 self.entity.id()
2825 }
2826
2827 /// Gets access to the component of type `C` for the current entity. Returns
2828 /// `None` if the component doesn't have a component of that type or if the
2829 /// type is one of the excluded components.
2830 #[inline]
2831 pub fn get<C>(&self) -> Option<&'w C>
2832 where
2833 C: Component,
2834 {
2835 let components = self.entity.world().components();
2836 let id = components.component_id::<C>()?;
2837 if bundle_contains_component::<B>(components, id) {
2838 None
2839 } else {
2840 // SAFETY: We have read access for all components that weren't
2841 // covered by the `contains` check above.
2842 unsafe { self.entity.get() }
2843 }
2844 }
2845
2846 /// Gets access to the component of type `C` for the current entity,
2847 /// including change detection information. Returns `None` if the component
2848 /// doesn't have a component of that type or if the type is one of the
2849 /// excluded components.
2850 #[inline]
2851 pub fn get_ref<C>(&self) -> Option<Ref<'w, C>>
2852 where
2853 C: Component,
2854 {
2855 let components = self.entity.world().components();
2856 let id = components.component_id::<C>()?;
2857 if bundle_contains_component::<B>(components, id) {
2858 None
2859 } else {
2860 // SAFETY: We have read access for all components that weren't
2861 // covered by the `contains` check above.
2862 unsafe { self.entity.get_ref() }
2863 }
2864 }
2865}
2866
2867impl<'a, B> From<&'a EntityMutExcept<'_, B>> for EntityRefExcept<'a, B>
2868where
2869 B: Bundle,
2870{
2871 fn from(entity_mut: &'a EntityMutExcept<'_, B>) -> Self {
2872 // SAFETY: All accesses that `EntityRefExcept` provides are also
2873 // accesses that `EntityMutExcept` provides.
2874 unsafe { EntityRefExcept::new(entity_mut.entity) }
2875 }
2876}
2877
2878/// Provides mutable access to all components of an entity, with the exception
2879/// of an explicit set.
2880///
2881/// This is a rather niche type that should only be used if you need access to
2882/// *all* components of an entity, while still allowing you to consult other
2883/// queries that might match entities that this query also matches. If you don't
2884/// need access to all components, prefer a standard query with a
2885/// [`crate::query::Without`] filter.
2886#[derive(Clone)]
2887pub struct EntityMutExcept<'w, B>
2888where
2889 B: Bundle,
2890{
2891 entity: UnsafeEntityCell<'w>,
2892 phantom: PhantomData<B>,
2893}
2894
2895impl<'w, B> EntityMutExcept<'w, B>
2896where
2897 B: Bundle,
2898{
2899 /// # Safety
2900 /// Other users of `UnsafeEntityCell` must not have access to any components not in `B`.
2901 pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>) -> Self {
2902 Self {
2903 entity,
2904 phantom: PhantomData,
2905 }
2906 }
2907
2908 /// Returns the [ID](Entity) of the current entity.
2909 #[inline]
2910 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
2911 pub fn id(&self) -> Entity {
2912 self.entity.id()
2913 }
2914
2915 /// Returns a new instance with a shorter lifetime.
2916 ///
2917 /// This is useful if you have `&mut EntityMutExcept`, but you need
2918 /// `EntityMutExcept`.
2919 pub fn reborrow(&mut self) -> EntityMutExcept<'_, B> {
2920 // SAFETY: We have exclusive access to the entire entity and the
2921 // applicable components.
2922 unsafe { Self::new(self.entity) }
2923 }
2924
2925 /// Gets read-only access to all of the entity's components, except for the
2926 /// ones in `CL`.
2927 #[inline]
2928 pub fn as_readonly(&self) -> EntityRefExcept<'_, B> {
2929 EntityRefExcept::from(self)
2930 }
2931
2932 /// Gets access to the component of type `C` for the current entity. Returns
2933 /// `None` if the component doesn't have a component of that type or if the
2934 /// type is one of the excluded components.
2935 #[inline]
2936 pub fn get<C>(&self) -> Option<&'_ C>
2937 where
2938 C: Component,
2939 {
2940 self.as_readonly().get()
2941 }
2942
2943 /// Gets access to the component of type `C` for the current entity,
2944 /// including change detection information. Returns `None` if the component
2945 /// doesn't have a component of that type or if the type is one of the
2946 /// excluded components.
2947 #[inline]
2948 pub fn get_ref<C>(&self) -> Option<Ref<'_, C>>
2949 where
2950 C: Component,
2951 {
2952 self.as_readonly().get_ref()
2953 }
2954
2955 /// Gets mutable access to the component of type `C` for the current entity.
2956 /// Returns `None` if the component doesn't have a component of that type or
2957 /// if the type is one of the excluded components.
2958 #[inline]
2959 pub fn get_mut<C>(&mut self) -> Option<Mut<'_, C>>
2960 where
2961 C: Component,
2962 {
2963 let components = self.entity.world().components();
2964 let id = components.component_id::<C>()?;
2965 if bundle_contains_component::<B>(components, id) {
2966 None
2967 } else {
2968 // SAFETY: We have write access for all components that weren't
2969 // covered by the `contains` check above.
2970 unsafe { self.entity.get_mut() }
2971 }
2972 }
2973}
2974
2975fn bundle_contains_component<B>(components: &Components, query_id: ComponentId) -> bool
2976where
2977 B: Bundle,
2978{
2979 let mut found = false;
2980 B::get_component_ids(components, &mut |maybe_id| {
2981 if let Some(id) = maybe_id {
2982 found = found || id == query_id;
2983 }
2984 });
2985 found
2986}
2987
2988/// Inserts a dynamic [`Bundle`] into the entity.
2989///
2990/// # Safety
2991///
2992/// - [`OwningPtr`] and [`StorageType`] iterators must correspond to the
2993/// [`BundleInfo`] used to construct [`BundleInserter`]
2994/// - [`Entity`] must correspond to [`EntityLocation`]
2995#[track_caller]
2996unsafe fn insert_dynamic_bundle<
2997 'a,
2998 I: Iterator<Item = OwningPtr<'a>>,
2999 S: Iterator<Item = StorageType>,
3000>(
3001 mut bundle_inserter: BundleInserter<'_>,
3002 entity: Entity,
3003 location: EntityLocation,
3004 components: I,
3005 storage_types: S,
3006) -> EntityLocation {
3007 struct DynamicInsertBundle<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> {
3008 components: I,
3009 }
3010
3011 impl<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> DynamicBundle
3012 for DynamicInsertBundle<'a, I>
3013 {
3014 fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) {
3015 self.components.for_each(|(t, ptr)| func(t, ptr));
3016 }
3017 }
3018
3019 let bundle = DynamicInsertBundle {
3020 components: storage_types.zip(components),
3021 };
3022
3023 // SAFETY: location matches current entity.
3024 unsafe {
3025 bundle_inserter.insert(
3026 entity,
3027 location,
3028 bundle,
3029 InsertMode::Replace,
3030 #[cfg(feature = "track_change_detection")]
3031 core::panic::Location::caller(),
3032 )
3033 }
3034}
3035
3036/// Removes a bundle from the given archetype and returns the resulting archetype (or None if the
3037/// removal was invalid). in the event that adding the given bundle does not result in an Archetype
3038/// change. Results are cached in the Archetype Graph to avoid redundant work.
3039/// if `intersection` is false, attempting to remove a bundle with components _not_ contained in the
3040/// current archetype will fail, returning None. if `intersection` is true, components in the bundle
3041/// but not in the current archetype will be ignored
3042///
3043/// # Safety
3044/// `archetype_id` must exist and components in `bundle_info` must exist
3045unsafe fn remove_bundle_from_archetype(
3046 archetypes: &mut Archetypes,
3047 storages: &mut Storages,
3048 components: &Components,
3049 observers: &Observers,
3050 archetype_id: ArchetypeId,
3051 bundle_info: &BundleInfo,
3052 intersection: bool,
3053) -> Option<ArchetypeId> {
3054 // check the archetype graph to see if the Bundle has been removed from this archetype in the
3055 // past
3056 let remove_bundle_result = {
3057 let edges = archetypes[archetype_id].edges();
3058 if intersection {
3059 edges.get_remove_bundle(bundle_info.id())
3060 } else {
3061 edges.get_take_bundle(bundle_info.id())
3062 }
3063 };
3064 let result = if let Some(result) = remove_bundle_result {
3065 // this Bundle removal result is cached. just return that!
3066 result
3067 } else {
3068 let mut next_table_components;
3069 let mut next_sparse_set_components;
3070 let next_table_id;
3071 {
3072 let current_archetype = &mut archetypes[archetype_id];
3073 let mut removed_table_components = Vec::new();
3074 let mut removed_sparse_set_components = Vec::new();
3075 for component_id in bundle_info.iter_explicit_components() {
3076 if current_archetype.contains(component_id) {
3077 // SAFETY: bundle components were already initialized by bundles.get_info
3078 let component_info = unsafe { components.get_info_unchecked(component_id) };
3079 match component_info.storage_type() {
3080 StorageType::Table => removed_table_components.push(component_id),
3081 StorageType::SparseSet => removed_sparse_set_components.push(component_id),
3082 }
3083 } else if !intersection {
3084 // a component in the bundle was not present in the entity's archetype, so this
3085 // removal is invalid cache the result in the archetype
3086 // graph
3087 current_archetype
3088 .edges_mut()
3089 .insert_take_bundle(bundle_info.id(), None);
3090 return None;
3091 }
3092 }
3093
3094 // sort removed components so we can do an efficient "sorted remove". archetype
3095 // components are already sorted
3096 removed_table_components.sort_unstable();
3097 removed_sparse_set_components.sort_unstable();
3098 next_table_components = current_archetype.table_components().collect();
3099 next_sparse_set_components = current_archetype.sparse_set_components().collect();
3100 sorted_remove(&mut next_table_components, &removed_table_components);
3101 sorted_remove(
3102 &mut next_sparse_set_components,
3103 &removed_sparse_set_components,
3104 );
3105
3106 next_table_id = if removed_table_components.is_empty() {
3107 current_archetype.table_id()
3108 } else {
3109 // SAFETY: all components in next_table_components exist
3110 unsafe {
3111 storages
3112 .tables
3113 .get_id_or_insert(&next_table_components, components)
3114 }
3115 };
3116 }
3117
3118 let new_archetype_id = archetypes.get_id_or_insert(
3119 components,
3120 observers,
3121 next_table_id,
3122 next_table_components,
3123 next_sparse_set_components,
3124 );
3125 Some(new_archetype_id)
3126 };
3127 let current_archetype = &mut archetypes[archetype_id];
3128 // cache the result in an edge
3129 if intersection {
3130 current_archetype
3131 .edges_mut()
3132 .insert_remove_bundle(bundle_info.id(), result);
3133 } else {
3134 current_archetype
3135 .edges_mut()
3136 .insert_take_bundle(bundle_info.id(), result);
3137 }
3138 result
3139}
3140
3141fn sorted_remove<T: Eq + Ord + Copy>(source: &mut Vec<T>, remove: &[T]) {
3142 let mut remove_index = 0;
3143 source.retain(|value| {
3144 while remove_index < remove.len() && *value > remove[remove_index] {
3145 remove_index += 1;
3146 }
3147
3148 if remove_index < remove.len() {
3149 *value != remove[remove_index]
3150 } else {
3151 true
3152 }
3153 });
3154}
3155
3156/// Moves component data out of storage.
3157///
3158/// This function leaves the underlying memory unchanged, but the component behind
3159/// returned pointer is semantically owned by the caller and will not be dropped in its original location.
3160/// Caller is responsible to drop component data behind returned pointer.
3161///
3162/// # Safety
3163/// - `location.table_row` must be in bounds of column of component id `component_id`
3164/// - `component_id` must be valid
3165/// - `components` must come from the same world as `self`
3166/// - The relevant table row **must be removed** by the caller once all components are taken, without dropping the value
3167#[inline]
3168pub(crate) unsafe fn take_component<'a>(
3169 storages: &'a mut Storages,
3170 components: &Components,
3171 removed_components: &mut RemovedComponentEvents,
3172 component_id: ComponentId,
3173 entity: Entity,
3174 location: EntityLocation,
3175) -> OwningPtr<'a> {
3176 // SAFETY: caller promises component_id to be valid
3177 let component_info = unsafe { components.get_info_unchecked(component_id) };
3178 removed_components.send(component_id, entity);
3179 match component_info.storage_type() {
3180 StorageType::Table => {
3181 let table = &mut storages.tables[location.table_id];
3182 // SAFETY:
3183 // - archetypes only store valid table_rows
3184 // - index is in bounds as promised by caller
3185 // - promote is safe because the caller promises to remove the table row without dropping it immediately afterwards
3186 unsafe { table.take_component(component_id, location.table_row) }
3187 }
3188 StorageType::SparseSet => storages
3189 .sparse_sets
3190 .get_mut(component_id)
3191 .unwrap()
3192 .remove_and_forget(entity)
3193 .unwrap(),
3194 }
3195}
3196
3197/// Types that can be used to fetch components from an entity dynamically by
3198/// [`ComponentId`]s.
3199///
3200/// Provided implementations are:
3201/// - [`ComponentId`]: Returns a single untyped reference.
3202/// - `[ComponentId; N]` and `&[ComponentId; N]`: Returns a same-sized array of untyped references.
3203/// - `&[ComponentId]`: Returns a [`Vec`] of untyped references.
3204/// - [`&HashSet<ComponentId>`](HashSet): Returns a [`HashMap`] of IDs to untyped references.
3205///
3206/// # Performance
3207///
3208/// - The slice and array implementations perform an aliased mutability check in
3209/// [`DynamicComponentFetch::fetch_mut`] that is `O(N^2)`.
3210/// - The [`HashSet`] implementation performs no such check as the type itself
3211/// guarantees unique IDs.
3212/// - The single [`ComponentId`] implementation performs no such check as only
3213/// one reference is returned.
3214///
3215/// # Safety
3216///
3217/// Implementor must ensure that:
3218/// - No aliased mutability is caused by the returned references.
3219/// - [`DynamicComponentFetch::fetch_ref`] returns only read-only references.
3220pub unsafe trait DynamicComponentFetch {
3221 /// The read-only reference type returned by [`DynamicComponentFetch::fetch_ref`].
3222 type Ref<'w>;
3223
3224 /// The mutable reference type returned by [`DynamicComponentFetch::fetch_mut`].
3225 type Mut<'w>;
3226
3227 /// Returns untyped read-only reference(s) to the component(s) with the
3228 /// given [`ComponentId`]s, as determined by `self`.
3229 ///
3230 /// # Safety
3231 ///
3232 /// It is the caller's responsibility to ensure that:
3233 /// - The given [`UnsafeEntityCell`] has read-only access to the fetched components.
3234 /// - No other mutable references to the fetched components exist at the same time.
3235 ///
3236 /// # Errors
3237 ///
3238 /// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.
3239 unsafe fn fetch_ref(
3240 self,
3241 cell: UnsafeEntityCell<'_>,
3242 ) -> Result<Self::Ref<'_>, EntityComponentError>;
3243
3244 /// Returns untyped mutable reference(s) to the component(s) with the
3245 /// given [`ComponentId`]s, as determined by `self`.
3246 ///
3247 /// # Safety
3248 ///
3249 /// It is the caller's responsibility to ensure that:
3250 /// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.
3251 /// - No other references to the fetched components exist at the same time.
3252 ///
3253 /// # Errors
3254 ///
3255 /// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.
3256 /// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.
3257 unsafe fn fetch_mut(
3258 self,
3259 cell: UnsafeEntityCell<'_>,
3260 ) -> Result<Self::Mut<'_>, EntityComponentError>;
3261}
3262
3263// SAFETY:
3264// - No aliased mutability is caused because a single reference is returned.
3265// - No mutable references are returned by `fetch_ref`.
3266unsafe impl DynamicComponentFetch for ComponentId {
3267 type Ref<'w> = Ptr<'w>;
3268 type Mut<'w> = MutUntyped<'w>;
3269
3270 unsafe fn fetch_ref(
3271 self,
3272 cell: UnsafeEntityCell<'_>,
3273 ) -> Result<Self::Ref<'_>, EntityComponentError> {
3274 // SAFETY: caller ensures that the cell has read access to the component.
3275 unsafe { cell.get_by_id(self) }.ok_or(EntityComponentError::MissingComponent(self))
3276 }
3277
3278 unsafe fn fetch_mut(
3279 self,
3280 cell: UnsafeEntityCell<'_>,
3281 ) -> Result<Self::Mut<'_>, EntityComponentError> {
3282 // SAFETY: caller ensures that the cell has mutable access to the component.
3283 unsafe { cell.get_mut_by_id(self) }.ok_or(EntityComponentError::MissingComponent(self))
3284 }
3285}
3286
3287// SAFETY:
3288// - No aliased mutability is caused because the array is checked for duplicates.
3289// - No mutable references are returned by `fetch_ref`.
3290unsafe impl<const N: usize> DynamicComponentFetch for [ComponentId; N] {
3291 type Ref<'w> = [Ptr<'w>; N];
3292 type Mut<'w> = [MutUntyped<'w>; N];
3293
3294 unsafe fn fetch_ref(
3295 self,
3296 cell: UnsafeEntityCell<'_>,
3297 ) -> Result<Self::Ref<'_>, EntityComponentError> {
3298 <&Self>::fetch_ref(&self, cell)
3299 }
3300
3301 unsafe fn fetch_mut(
3302 self,
3303 cell: UnsafeEntityCell<'_>,
3304 ) -> Result<Self::Mut<'_>, EntityComponentError> {
3305 <&Self>::fetch_mut(&self, cell)
3306 }
3307}
3308
3309// SAFETY:
3310// - No aliased mutability is caused because the array is checked for duplicates.
3311// - No mutable references are returned by `fetch_ref`.
3312unsafe impl<const N: usize> DynamicComponentFetch for &'_ [ComponentId; N] {
3313 type Ref<'w> = [Ptr<'w>; N];
3314 type Mut<'w> = [MutUntyped<'w>; N];
3315
3316 unsafe fn fetch_ref(
3317 self,
3318 cell: UnsafeEntityCell<'_>,
3319 ) -> Result<Self::Ref<'_>, EntityComponentError> {
3320 let mut ptrs = [const { MaybeUninit::uninit() }; N];
3321 for (ptr, &id) in core::iter::zip(&mut ptrs, self) {
3322 *ptr = MaybeUninit::new(
3323 // SAFETY: caller ensures that the cell has read access to the component.
3324 unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,
3325 );
3326 }
3327
3328 // SAFETY: Each ptr was initialized in the loop above.
3329 let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });
3330
3331 Ok(ptrs)
3332 }
3333
3334 unsafe fn fetch_mut(
3335 self,
3336 cell: UnsafeEntityCell<'_>,
3337 ) -> Result<Self::Mut<'_>, EntityComponentError> {
3338 // Check for duplicate component IDs.
3339 for i in 0..self.len() {
3340 for j in 0..i {
3341 if self[i] == self[j] {
3342 return Err(EntityComponentError::AliasedMutability(self[i]));
3343 }
3344 }
3345 }
3346
3347 let mut ptrs = [const { MaybeUninit::uninit() }; N];
3348 for (ptr, &id) in core::iter::zip(&mut ptrs, self) {
3349 *ptr = MaybeUninit::new(
3350 // SAFETY: caller ensures that the cell has mutable access to the component.
3351 unsafe { cell.get_mut_by_id(id) }
3352 .ok_or(EntityComponentError::MissingComponent(id))?,
3353 );
3354 }
3355
3356 // SAFETY: Each ptr was initialized in the loop above.
3357 let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });
3358
3359 Ok(ptrs)
3360 }
3361}
3362
3363// SAFETY:
3364// - No aliased mutability is caused because the slice is checked for duplicates.
3365// - No mutable references are returned by `fetch_ref`.
3366unsafe impl DynamicComponentFetch for &'_ [ComponentId] {
3367 type Ref<'w> = Vec<Ptr<'w>>;
3368 type Mut<'w> = Vec<MutUntyped<'w>>;
3369
3370 unsafe fn fetch_ref(
3371 self,
3372 cell: UnsafeEntityCell<'_>,
3373 ) -> Result<Self::Ref<'_>, EntityComponentError> {
3374 let mut ptrs = Vec::with_capacity(self.len());
3375 for &id in self {
3376 ptrs.push(
3377 // SAFETY: caller ensures that the cell has read access to the component.
3378 unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,
3379 );
3380 }
3381 Ok(ptrs)
3382 }
3383
3384 unsafe fn fetch_mut(
3385 self,
3386 cell: UnsafeEntityCell<'_>,
3387 ) -> Result<Self::Mut<'_>, EntityComponentError> {
3388 // Check for duplicate component IDs.
3389 for i in 0..self.len() {
3390 for j in 0..i {
3391 if self[i] == self[j] {
3392 return Err(EntityComponentError::AliasedMutability(self[i]));
3393 }
3394 }
3395 }
3396
3397 let mut ptrs = Vec::with_capacity(self.len());
3398 for &id in self {
3399 ptrs.push(
3400 // SAFETY: caller ensures that the cell has mutable access to the component.
3401 unsafe { cell.get_mut_by_id(id) }
3402 .ok_or(EntityComponentError::MissingComponent(id))?,
3403 );
3404 }
3405 Ok(ptrs)
3406 }
3407}
3408
3409// SAFETY:
3410// - No aliased mutability is caused because `HashSet` guarantees unique elements.
3411// - No mutable references are returned by `fetch_ref`.
3412unsafe impl DynamicComponentFetch for &'_ HashSet<ComponentId> {
3413 type Ref<'w> = HashMap<ComponentId, Ptr<'w>>;
3414 type Mut<'w> = HashMap<ComponentId, MutUntyped<'w>>;
3415
3416 unsafe fn fetch_ref(
3417 self,
3418 cell: UnsafeEntityCell<'_>,
3419 ) -> Result<Self::Ref<'_>, EntityComponentError> {
3420 let mut ptrs = HashMap::with_capacity(self.len());
3421 for &id in self {
3422 ptrs.insert(
3423 id,
3424 // SAFETY: caller ensures that the cell has read access to the component.
3425 unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,
3426 );
3427 }
3428 Ok(ptrs)
3429 }
3430
3431 unsafe fn fetch_mut(
3432 self,
3433 cell: UnsafeEntityCell<'_>,
3434 ) -> Result<Self::Mut<'_>, EntityComponentError> {
3435 let mut ptrs = HashMap::with_capacity(self.len());
3436 for &id in self {
3437 ptrs.insert(
3438 id,
3439 // SAFETY: caller ensures that the cell has mutable access to the component.
3440 unsafe { cell.get_mut_by_id(id) }
3441 .ok_or(EntityComponentError::MissingComponent(id))?,
3442 );
3443 }
3444 Ok(ptrs)
3445 }
3446}
3447
3448#[cfg(test)]
3449mod tests {
3450 use bevy_ptr::{OwningPtr, Ptr};
3451 use core::panic::AssertUnwindSafe;
3452
3453 use crate::{
3454 self as bevy_ecs,
3455 change_detection::MutUntyped,
3456 component::ComponentId,
3457 prelude::*,
3458 system::{assert_is_system, RunSystemOnce as _},
3459 world::{error::EntityComponentError, FilteredEntityMut, FilteredEntityRef},
3460 };
3461
3462 use super::{EntityMutExcept, EntityRefExcept};
3463
3464 #[test]
3465 fn sorted_remove() {
3466 let mut a = vec![1, 2, 3, 4, 5, 6, 7];
3467 let b = vec![1, 2, 3, 5, 7];
3468 super::sorted_remove(&mut a, &b);
3469
3470 assert_eq!(a, vec![4, 6]);
3471
3472 let mut a = vec![1];
3473 let b = vec![1];
3474 super::sorted_remove(&mut a, &b);
3475
3476 assert_eq!(a, vec![]);
3477
3478 let mut a = vec![1];
3479 let b = vec![2];
3480 super::sorted_remove(&mut a, &b);
3481
3482 assert_eq!(a, vec![1]);
3483 }
3484
3485 #[derive(Component, Clone, Copy, Debug, PartialEq)]
3486 struct TestComponent(u32);
3487
3488 #[derive(Component, Clone, Copy, Debug, PartialEq)]
3489 #[component(storage = "SparseSet")]
3490 struct TestComponent2(u32);
3491
3492 #[test]
3493 fn entity_ref_get_by_id() {
3494 let mut world = World::new();
3495 let entity = world.spawn(TestComponent(42)).id();
3496 let component_id = world
3497 .components()
3498 .get_id(core::any::TypeId::of::<TestComponent>())
3499 .unwrap();
3500
3501 let entity = world.entity(entity);
3502 let test_component = entity.get_by_id(component_id).unwrap();
3503 // SAFETY: points to a valid `TestComponent`
3504 let test_component = unsafe { test_component.deref::<TestComponent>() };
3505
3506 assert_eq!(test_component.0, 42);
3507 }
3508
3509 #[test]
3510 fn entity_mut_get_by_id() {
3511 let mut world = World::new();
3512 let entity = world.spawn(TestComponent(42)).id();
3513 let component_id = world
3514 .components()
3515 .get_id(core::any::TypeId::of::<TestComponent>())
3516 .unwrap();
3517
3518 let mut entity_mut = world.entity_mut(entity);
3519 let mut test_component = entity_mut.get_mut_by_id(component_id).unwrap();
3520 {
3521 test_component.set_changed();
3522 let test_component =
3523 // SAFETY: `test_component` has unique access of the `EntityWorldMut` and is not used afterwards
3524 unsafe { test_component.into_inner().deref_mut::<TestComponent>() };
3525 test_component.0 = 43;
3526 }
3527
3528 let entity = world.entity(entity);
3529 let test_component = entity.get_by_id(component_id).unwrap();
3530 // SAFETY: `TestComponent` is the correct component type
3531 let test_component = unsafe { test_component.deref::<TestComponent>() };
3532
3533 assert_eq!(test_component.0, 43);
3534 }
3535
3536 #[test]
3537 fn entity_ref_get_by_id_invalid_component_id() {
3538 let invalid_component_id = ComponentId::new(usize::MAX);
3539
3540 let mut world = World::new();
3541 let entity = world.spawn_empty().id();
3542 let entity = world.entity(entity);
3543 assert!(entity.get_by_id(invalid_component_id).is_err());
3544 }
3545
3546 #[test]
3547 fn entity_mut_get_by_id_invalid_component_id() {
3548 let invalid_component_id = ComponentId::new(usize::MAX);
3549
3550 let mut world = World::new();
3551 let mut entity = world.spawn_empty();
3552 assert!(entity.get_by_id(invalid_component_id).is_err());
3553 assert!(entity.get_mut_by_id(invalid_component_id).is_err());
3554 }
3555
3556 // regression test for https://github.com/bevyengine/bevy/pull/7387
3557 #[test]
3558 fn entity_mut_world_scope_panic() {
3559 let mut world = World::new();
3560
3561 let mut entity = world.spawn_empty();
3562 let old_location = entity.location();
3563 let id = entity.id();
3564 let res = std::panic::catch_unwind(AssertUnwindSafe(|| {
3565 entity.world_scope(|w| {
3566 // Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.
3567 // This will get updated at the end of the scope.
3568 w.entity_mut(id).insert(TestComponent(0));
3569
3570 // Ensure that the entity location still gets updated even in case of a panic.
3571 panic!("this should get caught by the outer scope")
3572 });
3573 }));
3574 assert!(res.is_err());
3575
3576 // Ensure that the location has been properly updated.
3577 assert_ne!(entity.location(), old_location);
3578 }
3579
3580 // regression test for https://github.com/bevyengine/bevy/pull/7805
3581 #[test]
3582 fn removing_sparse_updates_archetype_row() {
3583 #[derive(Component, PartialEq, Debug)]
3584 struct Dense(u8);
3585
3586 #[derive(Component)]
3587 #[component(storage = "SparseSet")]
3588 struct Sparse;
3589
3590 let mut world = World::new();
3591 let e1 = world.spawn((Dense(0), Sparse)).id();
3592 let e2 = world.spawn((Dense(1), Sparse)).id();
3593
3594 world.entity_mut(e1).remove::<Sparse>();
3595 assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
3596 }
3597
3598 // regression test for https://github.com/bevyengine/bevy/pull/7805
3599 #[test]
3600 fn removing_dense_updates_table_row() {
3601 #[derive(Component, PartialEq, Debug)]
3602 struct Dense(u8);
3603
3604 #[derive(Component)]
3605 #[component(storage = "SparseSet")]
3606 struct Sparse;
3607
3608 let mut world = World::new();
3609 let e1 = world.spawn((Dense(0), Sparse)).id();
3610 let e2 = world.spawn((Dense(1), Sparse)).id();
3611
3612 world.entity_mut(e1).remove::<Dense>();
3613 assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
3614 }
3615
3616 // Test that calling retain with `()` removes all components.
3617 #[test]
3618 fn retain_nothing() {
3619 #[derive(Component)]
3620 struct Marker<const N: usize>;
3621
3622 let mut world = World::new();
3623 let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();
3624
3625 world.entity_mut(ent).retain::<()>();
3626 assert_eq!(world.entity(ent).archetype().components().next(), None);
3627 }
3628
3629 // Test removing some components with `retain`, including components not on the entity.
3630 #[test]
3631 fn retain_some_components() {
3632 #[derive(Component)]
3633 struct Marker<const N: usize>;
3634
3635 let mut world = World::new();
3636 let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();
3637
3638 world.entity_mut(ent).retain::<(Marker<2>, Marker<4>)>();
3639 // Check that marker 2 was retained.
3640 assert!(world.entity(ent).get::<Marker<2>>().is_some());
3641 // Check that only marker 2 was retained.
3642 assert_eq!(
3643 world
3644 .entity(ent)
3645 .archetype()
3646 .components()
3647 .collect::<Vec<_>>()
3648 .len(),
3649 1
3650 );
3651 }
3652
3653 // regression test for https://github.com/bevyengine/bevy/pull/7805
3654 #[test]
3655 fn inserting_sparse_updates_archetype_row() {
3656 #[derive(Component, PartialEq, Debug)]
3657 struct Dense(u8);
3658
3659 #[derive(Component)]
3660 #[component(storage = "SparseSet")]
3661 struct Sparse;
3662
3663 let mut world = World::new();
3664 let e1 = world.spawn(Dense(0)).id();
3665 let e2 = world.spawn(Dense(1)).id();
3666
3667 world.entity_mut(e1).insert(Sparse);
3668 assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
3669 }
3670
3671 // regression test for https://github.com/bevyengine/bevy/pull/7805
3672 #[test]
3673 fn inserting_dense_updates_archetype_row() {
3674 #[derive(Component, PartialEq, Debug)]
3675 struct Dense(u8);
3676
3677 #[derive(Component)]
3678 struct Dense2;
3679
3680 #[derive(Component)]
3681 #[component(storage = "SparseSet")]
3682 struct Sparse;
3683
3684 let mut world = World::new();
3685 let e1 = world.spawn(Dense(0)).id();
3686 let e2 = world.spawn(Dense(1)).id();
3687
3688 world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
3689
3690 // archetype with [e2, e1]
3691 // table with [e1, e2]
3692
3693 world.entity_mut(e2).insert(Dense2);
3694
3695 assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));
3696 }
3697
3698 #[test]
3699 fn inserting_dense_updates_table_row() {
3700 #[derive(Component, PartialEq, Debug)]
3701 struct Dense(u8);
3702
3703 #[derive(Component)]
3704 struct Dense2;
3705
3706 #[derive(Component)]
3707 #[component(storage = "SparseSet")]
3708 struct Sparse;
3709
3710 let mut world = World::new();
3711 let e1 = world.spawn(Dense(0)).id();
3712 let e2 = world.spawn(Dense(1)).id();
3713
3714 world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
3715
3716 // archetype with [e2, e1]
3717 // table with [e1, e2]
3718
3719 world.entity_mut(e1).insert(Dense2);
3720
3721 assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
3722 }
3723
3724 // regression test for https://github.com/bevyengine/bevy/pull/7805
3725 #[test]
3726 fn despawning_entity_updates_archetype_row() {
3727 #[derive(Component, PartialEq, Debug)]
3728 struct Dense(u8);
3729
3730 #[derive(Component)]
3731 #[component(storage = "SparseSet")]
3732 struct Sparse;
3733
3734 let mut world = World::new();
3735 let e1 = world.spawn(Dense(0)).id();
3736 let e2 = world.spawn(Dense(1)).id();
3737
3738 world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
3739
3740 // archetype with [e2, e1]
3741 // table with [e1, e2]
3742
3743 world.entity_mut(e2).despawn();
3744
3745 assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));
3746 }
3747
3748 // regression test for https://github.com/bevyengine/bevy/pull/7805
3749 #[test]
3750 fn despawning_entity_updates_table_row() {
3751 #[derive(Component, PartialEq, Debug)]
3752 struct Dense(u8);
3753
3754 #[derive(Component)]
3755 #[component(storage = "SparseSet")]
3756 struct Sparse;
3757
3758 let mut world = World::new();
3759 let e1 = world.spawn(Dense(0)).id();
3760 let e2 = world.spawn(Dense(1)).id();
3761
3762 world.entity_mut(e1).insert(Sparse).remove::<Sparse>();
3763
3764 // archetype with [e2, e1]
3765 // table with [e1, e2]
3766
3767 world.entity_mut(e1).despawn();
3768
3769 assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));
3770 }
3771
3772 #[test]
3773 fn entity_mut_insert_by_id() {
3774 let mut world = World::new();
3775 let test_component_id = world.register_component::<TestComponent>();
3776
3777 let mut entity = world.spawn_empty();
3778 OwningPtr::make(TestComponent(42), |ptr| {
3779 // SAFETY: `ptr` matches the component id
3780 unsafe { entity.insert_by_id(test_component_id, ptr) };
3781 });
3782
3783 let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();
3784
3785 assert_eq!(components, vec![&TestComponent(42)]);
3786
3787 // Compare with `insert_bundle_by_id`
3788
3789 let mut entity = world.spawn_empty();
3790 OwningPtr::make(TestComponent(84), |ptr| {
3791 // SAFETY: `ptr` matches the component id
3792 unsafe { entity.insert_by_ids(&[test_component_id], vec![ptr].into_iter()) };
3793 });
3794
3795 let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();
3796
3797 assert_eq!(components, vec![&TestComponent(42), &TestComponent(84)]);
3798 }
3799
3800 #[test]
3801 fn entity_mut_insert_bundle_by_id() {
3802 let mut world = World::new();
3803 let test_component_id = world.register_component::<TestComponent>();
3804 let test_component_2_id = world.register_component::<TestComponent2>();
3805
3806 let component_ids = [test_component_id, test_component_2_id];
3807 let test_component_value = TestComponent(42);
3808 let test_component_2_value = TestComponent2(84);
3809
3810 let mut entity = world.spawn_empty();
3811 OwningPtr::make(test_component_value, |ptr1| {
3812 OwningPtr::make(test_component_2_value, |ptr2| {
3813 // SAFETY: `ptr1` and `ptr2` match the component ids
3814 unsafe { entity.insert_by_ids(&component_ids, vec![ptr1, ptr2].into_iter()) };
3815 });
3816 });
3817
3818 let dynamic_components: Vec<_> = world
3819 .query::<(&TestComponent, &TestComponent2)>()
3820 .iter(&world)
3821 .collect();
3822
3823 assert_eq!(
3824 dynamic_components,
3825 vec![(&TestComponent(42), &TestComponent2(84))]
3826 );
3827
3828 // Compare with `World` generated using static type equivalents
3829 let mut static_world = World::new();
3830
3831 static_world.spawn((test_component_value, test_component_2_value));
3832 let static_components: Vec<_> = static_world
3833 .query::<(&TestComponent, &TestComponent2)>()
3834 .iter(&static_world)
3835 .collect();
3836
3837 assert_eq!(dynamic_components, static_components);
3838 }
3839
3840 #[test]
3841 fn entity_mut_remove_by_id() {
3842 let mut world = World::new();
3843 let test_component_id = world.register_component::<TestComponent>();
3844
3845 let mut entity = world.spawn(TestComponent(42));
3846 entity.remove_by_id(test_component_id);
3847
3848 let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();
3849
3850 assert_eq!(components, vec![] as Vec<&TestComponent>);
3851
3852 // remove non-existent component does not panic
3853 world.spawn_empty().remove_by_id(test_component_id);
3854 }
3855
3856 /// Tests that components can be accessed through an `EntityRefExcept`.
3857 #[test]
3858 fn entity_ref_except() {
3859 let mut world = World::new();
3860 world.register_component::<TestComponent>();
3861 world.register_component::<TestComponent2>();
3862
3863 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3864
3865 let mut query = world.query::<EntityRefExcept<TestComponent>>();
3866
3867 let mut found = false;
3868 for entity_ref in query.iter_mut(&mut world) {
3869 found = true;
3870 assert!(entity_ref.get::<TestComponent>().is_none());
3871 assert!(entity_ref.get_ref::<TestComponent>().is_none());
3872 assert!(matches!(
3873 entity_ref.get::<TestComponent2>(),
3874 Some(TestComponent2(0))
3875 ));
3876 }
3877
3878 assert!(found);
3879 }
3880
3881 // Test that a single query can't both contain a mutable reference to a
3882 // component C and an `EntityRefExcept` that doesn't include C among its
3883 // exclusions.
3884 #[test]
3885 #[should_panic]
3886 fn entity_ref_except_conflicts_with_self() {
3887 let mut world = World::new();
3888 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3889
3890 // This should panic, because we have a mutable borrow on
3891 // `TestComponent` but have a simultaneous indirect immutable borrow on
3892 // that component via `EntityRefExcept`.
3893 world.run_system_once(system).unwrap();
3894
3895 fn system(_: Query<(&mut TestComponent, EntityRefExcept<TestComponent2>)>) {}
3896 }
3897
3898 // Test that an `EntityRefExcept` that doesn't include a component C among
3899 // its exclusions can't coexist with a mutable query for that component.
3900 #[test]
3901 #[should_panic]
3902 fn entity_ref_except_conflicts_with_other() {
3903 let mut world = World::new();
3904 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3905
3906 // This should panic, because we have a mutable borrow on
3907 // `TestComponent` but have a simultaneous indirect immutable borrow on
3908 // that component via `EntityRefExcept`.
3909 world.run_system_once(system).unwrap();
3910
3911 fn system(_: Query<&mut TestComponent>, _: Query<EntityRefExcept<TestComponent2>>) {}
3912 }
3913
3914 // Test that an `EntityRefExcept` with an exception for some component C can
3915 // coexist with a query for that component C.
3916 #[test]
3917 fn entity_ref_except_doesnt_conflict() {
3918 let mut world = World::new();
3919 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3920
3921 world.run_system_once(system).unwrap();
3922
3923 fn system(_: Query<&mut TestComponent>, query: Query<EntityRefExcept<TestComponent>>) {
3924 for entity_ref in query.iter() {
3925 assert!(matches!(
3926 entity_ref.get::<TestComponent2>(),
3927 Some(TestComponent2(0))
3928 ));
3929 }
3930 }
3931 }
3932
3933 /// Tests that components can be mutably accessed through an
3934 /// `EntityMutExcept`.
3935 #[test]
3936 fn entity_mut_except() {
3937 let mut world = World::new();
3938 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3939
3940 let mut query = world.query::<EntityMutExcept<TestComponent>>();
3941
3942 let mut found = false;
3943 for mut entity_mut in query.iter_mut(&mut world) {
3944 found = true;
3945 assert!(entity_mut.get::<TestComponent>().is_none());
3946 assert!(entity_mut.get_ref::<TestComponent>().is_none());
3947 assert!(entity_mut.get_mut::<TestComponent>().is_none());
3948 assert!(matches!(
3949 entity_mut.get::<TestComponent2>(),
3950 Some(TestComponent2(0))
3951 ));
3952 }
3953
3954 assert!(found);
3955 }
3956
3957 // Test that a single query can't both contain a mutable reference to a
3958 // component C and an `EntityMutExcept` that doesn't include C among its
3959 // exclusions.
3960 #[test]
3961 #[should_panic]
3962 fn entity_mut_except_conflicts_with_self() {
3963 let mut world = World::new();
3964 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3965
3966 // This should panic, because we have a mutable borrow on
3967 // `TestComponent` but have a simultaneous indirect immutable borrow on
3968 // that component via `EntityRefExcept`.
3969 world.run_system_once(system).unwrap();
3970
3971 fn system(_: Query<(&mut TestComponent, EntityMutExcept<TestComponent2>)>) {}
3972 }
3973
3974 // Test that an `EntityMutExcept` that doesn't include a component C among
3975 // its exclusions can't coexist with a query for that component.
3976 #[test]
3977 #[should_panic]
3978 fn entity_mut_except_conflicts_with_other() {
3979 let mut world = World::new();
3980 world.spawn(TestComponent(0)).insert(TestComponent2(0));
3981
3982 // This should panic, because we have a mutable borrow on
3983 // `TestComponent` but have a simultaneous indirect immutable borrow on
3984 // that component via `EntityRefExcept`.
3985 world.run_system_once(system).unwrap();
3986
3987 fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent2>>) {
3988 for mut entity_mut in query.iter_mut() {
3989 assert!(entity_mut
3990 .get_mut::<TestComponent2>()
3991 .is_some_and(|component| component.0 == 0));
3992 }
3993 }
3994 }
3995
3996 // Test that an `EntityMutExcept` with an exception for some component C can
3997 // coexist with a query for that component C.
3998 #[test]
3999 fn entity_mut_except_doesnt_conflict() {
4000 let mut world = World::new();
4001 world.spawn(TestComponent(0)).insert(TestComponent2(0));
4002
4003 world.run_system_once(system).unwrap();
4004
4005 fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent>>) {
4006 for mut entity_mut in query.iter_mut() {
4007 assert!(entity_mut
4008 .get_mut::<TestComponent2>()
4009 .is_some_and(|component| component.0 == 0));
4010 }
4011 }
4012 }
4013
4014 #[derive(Component)]
4015 struct A;
4016
4017 #[derive(Resource)]
4018 struct R;
4019
4020 #[test]
4021 fn disjoint_access() {
4022 fn disjoint_readonly(_: Query<EntityMut, With<A>>, _: Query<EntityRef, Without<A>>) {}
4023
4024 fn disjoint_mutable(_: Query<EntityMut, With<A>>, _: Query<EntityMut, Without<A>>) {}
4025
4026 assert_is_system(disjoint_readonly);
4027 assert_is_system(disjoint_mutable);
4028 }
4029
4030 #[test]
4031 fn ref_compatible() {
4032 fn borrow_system(_: Query<(EntityRef, &A)>, _: Query<&A>) {}
4033
4034 assert_is_system(borrow_system);
4035 }
4036
4037 #[test]
4038 fn ref_compatible_with_resource() {
4039 fn borrow_system(_: Query<EntityRef>, _: Res<R>) {}
4040
4041 assert_is_system(borrow_system);
4042 }
4043
4044 #[test]
4045 #[ignore] // This should pass, but it currently fails due to limitations in our access model.
4046 fn ref_compatible_with_resource_mut() {
4047 fn borrow_system(_: Query<EntityRef>, _: ResMut<R>) {}
4048
4049 assert_is_system(borrow_system);
4050 }
4051
4052 #[test]
4053 #[should_panic]
4054 fn ref_incompatible_with_mutable_component() {
4055 fn incompatible_system(_: Query<(EntityRef, &mut A)>) {}
4056
4057 assert_is_system(incompatible_system);
4058 }
4059
4060 #[test]
4061 #[should_panic]
4062 fn ref_incompatible_with_mutable_query() {
4063 fn incompatible_system(_: Query<EntityRef>, _: Query<&mut A>) {}
4064
4065 assert_is_system(incompatible_system);
4066 }
4067
4068 #[test]
4069 fn mut_compatible_with_entity() {
4070 fn borrow_mut_system(_: Query<(Entity, EntityMut)>) {}
4071
4072 assert_is_system(borrow_mut_system);
4073 }
4074
4075 #[test]
4076 #[ignore] // This should pass, but it currently fails due to limitations in our access model.
4077 fn mut_compatible_with_resource() {
4078 fn borrow_mut_system(_: Res<R>, _: Query<EntityMut>) {}
4079
4080 assert_is_system(borrow_mut_system);
4081 }
4082
4083 #[test]
4084 #[ignore] // This should pass, but it currently fails due to limitations in our access model.
4085 fn mut_compatible_with_resource_mut() {
4086 fn borrow_mut_system(_: ResMut<R>, _: Query<EntityMut>) {}
4087
4088 assert_is_system(borrow_mut_system);
4089 }
4090
4091 #[test]
4092 #[should_panic]
4093 fn mut_incompatible_with_read_only_component() {
4094 fn incompatible_system(_: Query<(EntityMut, &A)>) {}
4095
4096 assert_is_system(incompatible_system);
4097 }
4098
4099 #[test]
4100 #[should_panic]
4101 fn mut_incompatible_with_mutable_component() {
4102 fn incompatible_system(_: Query<(EntityMut, &mut A)>) {}
4103
4104 assert_is_system(incompatible_system);
4105 }
4106
4107 #[test]
4108 #[should_panic]
4109 fn mut_incompatible_with_read_only_query() {
4110 fn incompatible_system(_: Query<EntityMut>, _: Query<&A>) {}
4111
4112 assert_is_system(incompatible_system);
4113 }
4114
4115 #[test]
4116 #[should_panic]
4117 fn mut_incompatible_with_mutable_query() {
4118 fn incompatible_system(_: Query<EntityMut>, _: Query<&mut A>) {}
4119
4120 assert_is_system(incompatible_system);
4121 }
4122
4123 #[test]
4124 fn filtered_entity_ref_normal() {
4125 let mut world = World::new();
4126 let a_id = world.register_component::<A>();
4127
4128 let e: FilteredEntityRef = world.spawn(A).into();
4129
4130 assert!(e.get::<A>().is_some());
4131 assert!(e.get_ref::<A>().is_some());
4132 assert!(e.get_change_ticks::<A>().is_some());
4133 assert!(e.get_by_id(a_id).is_some());
4134 assert!(e.get_change_ticks_by_id(a_id).is_some());
4135 }
4136
4137 #[test]
4138 fn filtered_entity_ref_missing() {
4139 let mut world = World::new();
4140 let a_id = world.register_component::<A>();
4141
4142 let e: FilteredEntityRef = world.spawn(()).into();
4143
4144 assert!(e.get::<A>().is_none());
4145 assert!(e.get_ref::<A>().is_none());
4146 assert!(e.get_change_ticks::<A>().is_none());
4147 assert!(e.get_by_id(a_id).is_none());
4148 assert!(e.get_change_ticks_by_id(a_id).is_none());
4149 }
4150
4151 #[test]
4152 fn filtered_entity_mut_normal() {
4153 let mut world = World::new();
4154 let a_id = world.register_component::<A>();
4155
4156 let mut e: FilteredEntityMut = world.spawn(A).into();
4157
4158 assert!(e.get::<A>().is_some());
4159 assert!(e.get_ref::<A>().is_some());
4160 assert!(e.get_mut::<A>().is_some());
4161 assert!(e.get_change_ticks::<A>().is_some());
4162 assert!(e.get_by_id(a_id).is_some());
4163 assert!(e.get_mut_by_id(a_id).is_some());
4164 assert!(e.get_change_ticks_by_id(a_id).is_some());
4165 }
4166
4167 #[test]
4168 fn filtered_entity_mut_missing() {
4169 let mut world = World::new();
4170 let a_id = world.register_component::<A>();
4171
4172 let mut e: FilteredEntityMut = world.spawn(()).into();
4173
4174 assert!(e.get::<A>().is_none());
4175 assert!(e.get_ref::<A>().is_none());
4176 assert!(e.get_mut::<A>().is_none());
4177 assert!(e.get_change_ticks::<A>().is_none());
4178 assert!(e.get_by_id(a_id).is_none());
4179 assert!(e.get_mut_by_id(a_id).is_none());
4180 assert!(e.get_change_ticks_by_id(a_id).is_none());
4181 }
4182
4183 #[derive(Component, PartialEq, Eq, Debug)]
4184 struct X(usize);
4185
4186 #[derive(Component, PartialEq, Eq, Debug)]
4187 struct Y(usize);
4188
4189 #[test]
4190 fn get_components() {
4191 let mut world = World::default();
4192 let e1 = world.spawn((X(7), Y(10))).id();
4193 let e2 = world.spawn(X(8)).id();
4194 let e3 = world.spawn_empty().id();
4195
4196 assert_eq!(
4197 Some((&X(7), &Y(10))),
4198 world.entity(e1).get_components::<(&X, &Y)>()
4199 );
4200 assert_eq!(None, world.entity(e2).get_components::<(&X, &Y)>());
4201 assert_eq!(None, world.entity(e3).get_components::<(&X, &Y)>());
4202 }
4203
4204 #[test]
4205 fn get_by_id_array() {
4206 let mut world = World::default();
4207 let e1 = world.spawn((X(7), Y(10))).id();
4208 let e2 = world.spawn(X(8)).id();
4209 let e3 = world.spawn_empty().id();
4210
4211 let x_id = world.register_component::<X>();
4212 let y_id = world.register_component::<Y>();
4213
4214 assert_eq!(
4215 Ok((&X(7), &Y(10))),
4216 world
4217 .entity(e1)
4218 .get_by_id([x_id, y_id])
4219 .map(|[x_ptr, y_ptr]| {
4220 // SAFETY: components match the id they were fetched with
4221 (unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
4222 })
4223 );
4224 assert_eq!(
4225 Err(EntityComponentError::MissingComponent(y_id)),
4226 world
4227 .entity(e2)
4228 .get_by_id([x_id, y_id])
4229 .map(|[x_ptr, y_ptr]| {
4230 // SAFETY: components match the id they were fetched with
4231 (unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
4232 })
4233 );
4234 assert_eq!(
4235 Err(EntityComponentError::MissingComponent(x_id)),
4236 world
4237 .entity(e3)
4238 .get_by_id([x_id, y_id])
4239 .map(|[x_ptr, y_ptr]| {
4240 // SAFETY: components match the id they were fetched with
4241 (unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
4242 })
4243 );
4244 }
4245
4246 #[test]
4247 fn get_by_id_vec() {
4248 let mut world = World::default();
4249 let e1 = world.spawn((X(7), Y(10))).id();
4250 let e2 = world.spawn(X(8)).id();
4251 let e3 = world.spawn_empty().id();
4252
4253 let x_id = world.register_component::<X>();
4254 let y_id = world.register_component::<Y>();
4255
4256 assert_eq!(
4257 Ok((&X(7), &Y(10))),
4258 world
4259 .entity(e1)
4260 .get_by_id(&[x_id, y_id] as &[ComponentId])
4261 .map(|ptrs| {
4262 let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {
4263 panic!("get_by_id(slice) didn't return 2 elements")
4264 };
4265
4266 // SAFETY: components match the id they were fetched with
4267 (unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
4268 })
4269 );
4270 assert_eq!(
4271 Err(EntityComponentError::MissingComponent(y_id)),
4272 world
4273 .entity(e2)
4274 .get_by_id(&[x_id, y_id] as &[ComponentId])
4275 .map(|ptrs| {
4276 let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {
4277 panic!("get_by_id(slice) didn't return 2 elements")
4278 };
4279
4280 // SAFETY: components match the id they were fetched with
4281 (unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
4282 })
4283 );
4284 assert_eq!(
4285 Err(EntityComponentError::MissingComponent(x_id)),
4286 world
4287 .entity(e3)
4288 .get_by_id(&[x_id, y_id] as &[ComponentId])
4289 .map(|ptrs| {
4290 let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {
4291 panic!("get_by_id(slice) didn't return 2 elements")
4292 };
4293
4294 // SAFETY: components match the id they were fetched with
4295 (unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })
4296 })
4297 );
4298 }
4299
4300 #[test]
4301 fn get_mut_by_id_array() {
4302 let mut world = World::default();
4303 let e1 = world.spawn((X(7), Y(10))).id();
4304 let e2 = world.spawn(X(8)).id();
4305 let e3 = world.spawn_empty().id();
4306
4307 let x_id = world.register_component::<X>();
4308 let y_id = world.register_component::<Y>();
4309
4310 assert_eq!(
4311 Ok((&mut X(7), &mut Y(10))),
4312 world
4313 .entity_mut(e1)
4314 .get_mut_by_id([x_id, y_id])
4315 .map(|[x_ptr, y_ptr]| {
4316 // SAFETY: components match the id they were fetched with
4317 (unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
4318 y_ptr.into_inner().deref_mut::<Y>()
4319 })
4320 })
4321 );
4322 assert_eq!(
4323 Err(EntityComponentError::MissingComponent(y_id)),
4324 world
4325 .entity_mut(e2)
4326 .get_mut_by_id([x_id, y_id])
4327 .map(|[x_ptr, y_ptr]| {
4328 // SAFETY: components match the id they were fetched with
4329 (unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
4330 y_ptr.into_inner().deref_mut::<Y>()
4331 })
4332 })
4333 );
4334 assert_eq!(
4335 Err(EntityComponentError::MissingComponent(x_id)),
4336 world
4337 .entity_mut(e3)
4338 .get_mut_by_id([x_id, y_id])
4339 .map(|[x_ptr, y_ptr]| {
4340 // SAFETY: components match the id they were fetched with
4341 (unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
4342 y_ptr.into_inner().deref_mut::<Y>()
4343 })
4344 })
4345 );
4346
4347 assert_eq!(
4348 Err(EntityComponentError::AliasedMutability(x_id)),
4349 world
4350 .entity_mut(e1)
4351 .get_mut_by_id([x_id, x_id])
4352 .map(|_| { unreachable!() })
4353 );
4354 assert_eq!(
4355 Err(EntityComponentError::AliasedMutability(x_id)),
4356 world
4357 .entity_mut(e3)
4358 .get_mut_by_id([x_id, x_id])
4359 .map(|_| { unreachable!() })
4360 );
4361 }
4362
4363 #[test]
4364 fn get_mut_by_id_vec() {
4365 let mut world = World::default();
4366 let e1 = world.spawn((X(7), Y(10))).id();
4367 let e2 = world.spawn(X(8)).id();
4368 let e3 = world.spawn_empty().id();
4369
4370 let x_id = world.register_component::<X>();
4371 let y_id = world.register_component::<Y>();
4372
4373 assert_eq!(
4374 Ok((&mut X(7), &mut Y(10))),
4375 world
4376 .entity_mut(e1)
4377 .get_mut_by_id(&[x_id, y_id] as &[ComponentId])
4378 .map(|ptrs| {
4379 let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {
4380 panic!("get_mut_by_id(slice) didn't return 2 elements")
4381 };
4382
4383 // SAFETY: components match the id they were fetched with
4384 (unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
4385 y_ptr.into_inner().deref_mut::<Y>()
4386 })
4387 })
4388 );
4389 assert_eq!(
4390 Err(EntityComponentError::MissingComponent(y_id)),
4391 world
4392 .entity_mut(e2)
4393 .get_mut_by_id(&[x_id, y_id] as &[ComponentId])
4394 .map(|ptrs| {
4395 let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {
4396 panic!("get_mut_by_id(slice) didn't return 2 elements")
4397 };
4398
4399 // SAFETY: components match the id they were fetched with
4400 (unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
4401 y_ptr.into_inner().deref_mut::<Y>()
4402 })
4403 })
4404 );
4405 assert_eq!(
4406 Err(EntityComponentError::MissingComponent(x_id)),
4407 world
4408 .entity_mut(e3)
4409 .get_mut_by_id(&[x_id, y_id] as &[ComponentId])
4410 .map(|ptrs| {
4411 let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {
4412 panic!("get_mut_by_id(slice) didn't return 2 elements")
4413 };
4414
4415 // SAFETY: components match the id they were fetched with
4416 (unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {
4417 y_ptr.into_inner().deref_mut::<Y>()
4418 })
4419 })
4420 );
4421
4422 assert_eq!(
4423 Err(EntityComponentError::AliasedMutability(x_id)),
4424 world
4425 .entity_mut(e1)
4426 .get_mut_by_id(&[x_id, x_id])
4427 .map(|_| { unreachable!() })
4428 );
4429 assert_eq!(
4430 Err(EntityComponentError::AliasedMutability(x_id)),
4431 world
4432 .entity_mut(e3)
4433 .get_mut_by_id(&[x_id, x_id])
4434 .map(|_| { unreachable!() })
4435 );
4436 }
4437}