bevy_ecs/world/entity_access/
entity_ref.rs

1use crate::{
2    archetype::Archetype,
3    change_detection::{ComponentTicks, MaybeLocation, Tick},
4    component::{Component, ComponentId},
5    entity::{ContainsEntity, Entity, EntityEquivalent, EntityLocation},
6    query::{Access, QueryAccessError, ReadOnlyQueryData, ReleaseStateQueryData},
7    world::{
8        error::EntityComponentError, unsafe_world_cell::UnsafeEntityCell, DynamicComponentFetch,
9        FilteredEntityRef, Ref,
10    },
11};
12
13use core::{
14    any::TypeId,
15    cmp::Ordering,
16    hash::{Hash, Hasher},
17};
18
19/// A read-only reference to a particular [`Entity`] and all of its components.
20///
21/// # Examples
22///
23/// Read-only access disjoint with mutable access.
24///
25/// ```
26/// # use bevy_ecs::prelude::*;
27/// # #[derive(Component)] pub struct A;
28/// # #[derive(Component)] pub struct B;
29/// fn disjoint_system(
30///     query1: Query<&mut A>,
31///     query2: Query<EntityRef, Without<A>>,
32/// ) {
33///     // ...
34/// }
35/// # bevy_ecs::system::assert_is_system(disjoint_system);
36/// ```
37#[derive(Copy, Clone)]
38pub struct EntityRef<'w> {
39    cell: UnsafeEntityCell<'w>,
40}
41
42impl<'w> EntityRef<'w> {
43    /// # Safety
44    /// - `cell` must have permission to read every component of the entity.
45    /// - No mutable accesses to any of the entity's components may exist
46    ///   at the same time as the returned [`EntityRef`].
47    #[inline]
48    pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {
49        Self { cell }
50    }
51
52    /// Returns the [ID](Entity) of the current entity.
53    #[inline]
54    #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
55    pub fn id(&self) -> Entity {
56        self.cell.id()
57    }
58
59    /// Gets metadata indicating the location where the current entity is stored.
60    #[inline]
61    pub fn location(&self) -> EntityLocation {
62        self.cell.location()
63    }
64
65    /// Returns the archetype that the current entity belongs to.
66    #[inline]
67    pub fn archetype(&self) -> &Archetype {
68        self.cell.archetype()
69    }
70
71    /// Returns `true` if the current entity has a component of type `T`.
72    /// Otherwise, this returns `false`.
73    ///
74    /// ## Notes
75    ///
76    /// If you do not know the concrete type of a component, consider using
77    /// [`Self::contains_id`] or [`Self::contains_type_id`].
78    #[inline]
79    pub fn contains<T: Component>(&self) -> bool {
80        self.contains_type_id(TypeId::of::<T>())
81    }
82
83    /// Returns `true` if the current entity has a component identified by `component_id`.
84    /// Otherwise, this returns false.
85    ///
86    /// ## Notes
87    ///
88    /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
89    /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
90    ///   [`Self::contains_type_id`].
91    #[inline]
92    pub fn contains_id(&self, component_id: ComponentId) -> bool {
93        self.cell.contains_id(component_id)
94    }
95
96    /// Returns `true` if the current entity has a component with the type identified by `type_id`.
97    /// Otherwise, this returns false.
98    ///
99    /// ## Notes
100    ///
101    /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
102    /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
103    #[inline]
104    pub fn contains_type_id(&self, type_id: TypeId) -> bool {
105        self.cell.contains_type_id(type_id)
106    }
107
108    /// Gets access to the component of type `T` for the current entity.
109    /// Returns `None` if the entity does not have a component of type `T`.
110    #[inline]
111    pub fn get<T: Component>(&self) -> Option<&'w T> {
112        // SAFETY: We have read-only access to all components of this entity.
113        unsafe { self.cell.get::<T>() }
114    }
115
116    /// Gets access to the component of type `T` for the current entity,
117    /// including change detection information as a [`Ref`].
118    ///
119    /// Returns `None` if the entity does not have a component of type `T`.
120    #[inline]
121    pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {
122        // SAFETY: We have read-only access to all components of this entity.
123        unsafe { self.cell.get_ref::<T>() }
124    }
125
126    /// Retrieves the change ticks for the given component. This can be useful for implementing change
127    /// detection in custom runtimes.
128    #[inline]
129    pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
130        // SAFETY: We have read-only access to all components of this entity.
131        unsafe { self.cell.get_change_ticks::<T>() }
132    }
133
134    /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
135    /// detection in custom runtimes.
136    ///
137    /// **You should prefer to use the typed API [`EntityRef::get_change_ticks`] where possible and only
138    /// use this in cases where the actual component types are not known at
139    /// compile time.**
140    #[inline]
141    pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
142        // SAFETY: We have read-only access to all components of this entity.
143        unsafe { self.cell.get_change_ticks_by_id(component_id) }
144    }
145
146    /// Returns untyped read-only reference(s) to component(s) for the
147    /// current entity, based on the given [`ComponentId`]s.
148    ///
149    /// **You should prefer to use the typed API [`EntityRef::get`] where
150    /// possible and only use this in cases where the actual component types
151    /// are not known at compile time.**
152    ///
153    /// Unlike [`EntityRef::get`], this returns untyped reference(s) to
154    /// component(s), and it's the job of the caller to ensure the correct
155    /// type(s) are dereferenced (if necessary).
156    ///
157    /// # Errors
158    ///
159    /// Returns [`EntityComponentError::MissingComponent`] if the entity does
160    /// not have a component.
161    ///
162    /// # Examples
163    ///
164    /// ## Single [`ComponentId`]
165    ///
166    /// ```
167    /// # use bevy_ecs::prelude::*;
168    /// #
169    /// # #[derive(Component, PartialEq, Debug)]
170    /// # pub struct Foo(i32);
171    /// # let mut world = World::new();
172    /// let entity = world.spawn(Foo(42)).id();
173    ///
174    /// // Grab the component ID for `Foo` in whatever way you like.
175    /// let component_id = world.register_component::<Foo>();
176    ///
177    /// // Then, get the component by ID.
178    /// let ptr = world.entity(entity).get_by_id(component_id);
179    /// # assert_eq!(unsafe { ptr.unwrap().deref::<Foo>() }, &Foo(42));
180    /// ```
181    ///
182    /// ## Array of [`ComponentId`]s
183    ///
184    /// ```
185    /// # use bevy_ecs::prelude::*;
186    /// #
187    /// # #[derive(Component, PartialEq, Debug)]
188    /// # pub struct X(i32);
189    /// # #[derive(Component, PartialEq, Debug)]
190    /// # pub struct Y(i32);
191    /// # let mut world = World::new();
192    /// let entity = world.spawn((X(42), Y(10))).id();
193    ///
194    /// // Grab the component IDs for `X` and `Y` in whatever way you like.
195    /// let x_id = world.register_component::<X>();
196    /// let y_id = world.register_component::<Y>();
197    ///
198    /// // Then, get the components by ID. You'll receive a same-sized array.
199    /// let Ok([x_ptr, y_ptr]) = world.entity(entity).get_by_id([x_id, y_id]) else {
200    ///     // Up to you to handle if a component is missing from the entity.
201    /// #   unreachable!();
202    /// };
203    /// # assert_eq!((unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() }), (&X(42), &Y(10)));
204    /// ```
205    ///
206    /// ## Slice of [`ComponentId`]s
207    ///
208    /// ```
209    /// # use bevy_ecs::{prelude::*, component::ComponentId};
210    /// #
211    /// # #[derive(Component, PartialEq, Debug)]
212    /// # pub struct X(i32);
213    /// # #[derive(Component, PartialEq, Debug)]
214    /// # pub struct Y(i32);
215    /// # let mut world = World::new();
216    /// let entity = world.spawn((X(42), Y(10))).id();
217    ///
218    /// // Grab the component IDs for `X` and `Y` in whatever way you like.
219    /// let x_id = world.register_component::<X>();
220    /// let y_id = world.register_component::<Y>();
221    ///
222    /// // Then, get the components by ID. You'll receive a vec of ptrs.
223    /// let ptrs = world.entity(entity).get_by_id(&[x_id, y_id] as &[ComponentId]);
224    /// # let ptrs = ptrs.unwrap();
225    /// # assert_eq!((unsafe { ptrs[0].deref::<X>() }, unsafe { ptrs[1].deref::<Y>() }), (&X(42), &Y(10)));
226    /// ```
227    ///
228    /// ## `HashSet` of [`ComponentId`]s
229    ///
230    /// ```
231    /// # use bevy_platform::collections::HashSet;
232    /// # use bevy_ecs::{prelude::*, component::ComponentId};
233    /// #
234    /// # #[derive(Component, PartialEq, Debug)]
235    /// # pub struct X(i32);
236    /// # #[derive(Component, PartialEq, Debug)]
237    /// # pub struct Y(i32);
238    /// # let mut world = World::new();
239    /// let entity = world.spawn((X(42), Y(10))).id();
240    ///
241    /// // Grab the component IDs for `X` and `Y` in whatever way you like.
242    /// let x_id = world.register_component::<X>();
243    /// let y_id = world.register_component::<Y>();
244    ///
245    /// // Then, get the components by ID. You'll receive a vec of ptrs.
246    /// let ptrs = world.entity(entity).get_by_id(&HashSet::from_iter([x_id, y_id]));
247    /// # let ptrs = ptrs.unwrap();
248    /// # assert_eq!((unsafe { ptrs[&x_id].deref::<X>() }, unsafe { ptrs[&y_id].deref::<Y>() }), (&X(42), &Y(10)));
249    /// ```
250    #[inline]
251    pub fn get_by_id<F: DynamicComponentFetch>(
252        &self,
253        component_ids: F,
254    ) -> Result<F::Ref<'w>, EntityComponentError> {
255        // SAFETY: We have read-only access to all components of this entity.
256        unsafe { component_ids.fetch_ref(self.cell) }
257    }
258
259    /// Returns read-only components for the current entity that match the query `Q`.
260    ///
261    /// # Panics
262    ///
263    /// If the entity does not have the components required by the query `Q`.
264    pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'w, 'static> {
265        self.get_components::<Q>()
266            .expect("Query does not match the current entity")
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 + ReleaseStateQueryData>(
272        &self,
273    ) -> Result<Q::Item<'w, 'static>, QueryAccessError> {
274        // SAFETY:
275        // - We have read-only access to all components of this entity.
276        // - The query is read-only, and read-only references cannot have conflicts.
277        unsafe { self.cell.get_components::<Q>() }
278    }
279
280    /// Returns the source code location from which this entity has been spawned.
281    pub fn spawned_by(&self) -> MaybeLocation {
282        self.cell.spawned_by()
283    }
284
285    /// Returns the [`Tick`] at which this entity has been spawned.
286    pub fn spawn_tick(&self) -> Tick {
287        self.cell.spawn_tick()
288    }
289}
290
291impl<'a> From<EntityRef<'a>> for FilteredEntityRef<'a, 'static> {
292    fn from(entity: EntityRef<'a>) -> Self {
293        // SAFETY:
294        // - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.
295        unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }
296    }
297}
298
299impl<'a> From<&'a EntityRef<'_>> for FilteredEntityRef<'a, 'static> {
300    fn from(entity: &'a EntityRef<'_>) -> Self {
301        // SAFETY:
302        // - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.
303        unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }
304    }
305}
306
307impl PartialEq for EntityRef<'_> {
308    fn eq(&self, other: &Self) -> bool {
309        self.entity() == other.entity()
310    }
311}
312
313impl Eq for EntityRef<'_> {}
314
315impl PartialOrd for EntityRef<'_> {
316    /// [`EntityRef`]'s comparison trait implementations match the underlying [`Entity`],
317    /// and cannot discern between different worlds.
318    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
319        Some(self.cmp(other))
320    }
321}
322
323impl Ord for EntityRef<'_> {
324    fn cmp(&self, other: &Self) -> Ordering {
325        self.entity().cmp(&other.entity())
326    }
327}
328
329impl Hash for EntityRef<'_> {
330    fn hash<H: Hasher>(&self, state: &mut H) {
331        self.entity().hash(state);
332    }
333}
334
335impl ContainsEntity for EntityRef<'_> {
336    fn entity(&self) -> Entity {
337        self.id()
338    }
339}
340
341// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
342unsafe impl EntityEquivalent for EntityRef<'_> {}