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<'_> {}