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