Skip to content

Commit

Permalink
Add grab method for EntityMut and EntityWorldMut that consume self.
Browse files Browse the repository at this point in the history
The grab methods returns access with the world lifetime instead of
&'_ self lifetime.

Methods implemented:
- EntityMut::grab
- EntityMut::grab_ref
- EntityMut::grab_mut
- EntityMut::grab_by_id
- EntityMut::grab_mut_by_id
- EntityWorldMut::grab
- EntityWorldMut::grab_ref
- EntityWorldMut::grab_mut
- EntityWorldMut::grab_by_id
- EntityWorldMut::grab_mut_by_id
  • Loading branch information
jkb0o committed Mar 11, 2024
1 parent 6399386 commit 6064efe
Showing 1 changed file with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,16 @@ impl<'w> EntityMut<'w> {
self.as_readonly().get()
}

/// Consumes `self` and gets access to the component of type `T` with the
/// world `'w` lifetime for the current entity.
///
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
pub fn grab<T: Component>(self) -> Option<&'w T> {
// SAFETY: consuming `self` implies exclusive access
unsafe { self.0.get() }
}

/// Gets access to the component of type `T` for the current entity,
/// including change detection information as a [`Ref`].
///
Expand All @@ -357,6 +367,17 @@ impl<'w> EntityMut<'w> {
self.as_readonly().get_ref()
}

/// Consumes `self` and gets access to the component of type `T` with world
/// `'w` lifetime for the current entity, including change detection information
/// as a [`Ref<'w>`].
///
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
pub fn grab_ref<T: Component>(self) -> Option<Ref<'w, T>> {
// SAFETY: consuming `self` implies exclusive access
unsafe { self.0.get_ref() }
}

/// Gets mutable access to the component of type `T` for the current entity.
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
Expand All @@ -365,6 +386,15 @@ impl<'w> EntityMut<'w> {
unsafe { self.0.get_mut() }
}

/// Consumes self and gets mutable access to the component of type `T`
/// with the world `'w` lifetime for the current entity.
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
pub fn grab_mut<T: Component>(self) -> Option<Mut<'w, T>> {
// SAFETY: consuming `self` implies exclusive access
unsafe { self.0.get_mut() }
}

/// Retrieves the change ticks for the given component. This can be useful for implementing change
/// detection in custom runtimes.
#[inline]
Expand Down Expand Up @@ -396,6 +426,19 @@ impl<'w> EntityMut<'w> {
self.as_readonly().get_by_id(component_id)
}

/// Consumes `self` and gets the component of the given [`ComponentId`] with
/// world `'w` lifetime from the entity.
///
/// **You should prefer to use the typed API [`EntityWorldMut::grab`] where possible and only
/// use this in cases where the actual component types are not known at
/// compile time.**
#[inline]
pub fn grab_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
// SAFETY:
// consuming `self` ensures that no references exist to this entity's components.
unsafe { self.0.get_by_id(component_id) }
}

/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
///
/// **You should prefer to use the typed API [`EntityMut::get_mut`] where possible and only
Expand All @@ -411,6 +454,19 @@ impl<'w> EntityMut<'w> {
// - `as_unsafe_world_cell` gives mutable permission for all components on this entity
unsafe { self.0.get_mut_by_id(component_id) }
}

/// Consumes `self` and gets a [`MutUntyped<'w>`] of the component of the given [`ComponentId`]
/// with world lifetime from the entity.
///
/// **You should prefer to use the typed API [`EntityMut::grab_mut`] where possible and only
/// use this in cases where the actual component types are not known at
/// compile time.**
#[inline]
pub fn grab_mut_by_id(self, component_id: ComponentId) -> Option<MutUntyped<'w>> {
// SAFETY:
// consuming `self` ensures that no references exist to this entity's components.
unsafe { self.0.get_mut_by_id(component_id) }
}
}

impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {
Expand Down Expand Up @@ -583,6 +639,15 @@ impl<'w> EntityWorldMut<'w> {
EntityRef::from(self).get()
}

/// Consumes `self` and gets access to the component of type `T` with
/// the world `'w` lifetime for the current entity.
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
pub fn grab<T: Component>(self) -> Option<&'w T> {
// SAFETY: consuming `self` implies exclusive access
unsafe { self.into_unsafe_entity_cell().get() }
}

/// Gets access to the component of type `T` for the current entity,
/// including change detection information as a [`Ref`].
///
Expand All @@ -592,6 +657,16 @@ impl<'w> EntityWorldMut<'w> {
EntityRef::from(self).get_ref()
}

/// Consumes `self` and gets access to the component of type `T`
/// with the world `'w` lifetime for the current entity,
/// including change detection information as a [`Ref`].
///
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
pub fn grab_ref<T: Component>(self) -> Option<Ref<'w, T>> {
EntityRef::from(self).get_ref()
}

/// Gets mutable access to the component of type `T` for the current entity.
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
Expand All @@ -600,6 +675,15 @@ impl<'w> EntityWorldMut<'w> {
unsafe { self.as_unsafe_entity_cell().get_mut() }
}

/// Consumes `self` and gets mutable access to the component of type `T`
/// with the world `'w` lifetime for the current entity.
/// Returns `None` if the entity does not have a component of type `T`.
#[inline]
pub fn grab_mut<T: Component>(self) -> Option<Mut<'w, T>> {
// SAFETY: consuming `self` implies exclusive access
unsafe { self.into_unsafe_entity_cell().get_mut() }
}

/// Retrieves the change ticks for the given component. This can be useful for implementing change
/// detection in custom runtimes.
#[inline]
Expand Down Expand Up @@ -631,6 +715,18 @@ impl<'w> EntityWorldMut<'w> {
EntityRef::from(self).get_by_id(component_id)
}

/// Consumes `self` and gets the component of the given [`ComponentId`] with
/// with world `'w` lifetime from the entity.
///
/// **You should prefer to use the typed API [`EntityWorldMut::grab`] where possible and only
/// use this in cases where the actual component types are not known at
/// compile time.**
#[inline]
pub fn grab_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
// SAFETY: consuming `self` implies exclusive access
unsafe { self.into_unsafe_entity_cell().get_by_id(component_id) }
}

/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
///
/// **You should prefer to use the typed API [`EntityWorldMut::get_mut`] where possible and only
Expand All @@ -647,6 +743,19 @@ impl<'w> EntityWorldMut<'w> {
unsafe { self.as_unsafe_entity_cell().get_mut_by_id(component_id) }
}

/// Consumes `self` and gets a [`MutUntyped<'w>`] of the component with the world `'w` lifetime
/// of the given [`ComponentId`] from the entity.
///
/// **You should prefer to use the typed API [`EntityWorldMut::grab_mut`] where possible and only
/// use this in cases where the actual component types are not known at
/// compile time.**
#[inline]
pub fn grab_mut_by_id(self, component_id: ComponentId) -> Option<MutUntyped<'w>> {
// SAFETY:
// consuming `self` ensures that no references exist to this entity's components.
unsafe { self.into_unsafe_entity_cell().get_mut_by_id(component_id) }
}

/// Adds a [`Bundle`] of components to the entity.
///
/// This will overwrite any previous value(s) of the same component type.
Expand Down

0 comments on commit 6064efe

Please sign in to comment.