diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 7448dddd8b..d92029154f 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -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 into_borrow(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`]. /// @@ -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 into_ref(self) -> Option> { + // 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] @@ -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 into_mut(self) -> Option> { + // 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] @@ -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::into_borrow`] where possible and only + /// use this in cases where the actual component types are not known at + /// compile time.** + #[inline] + pub fn into_borrow_by_id(self, component_id: ComponentId) -> Option> { + // 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 @@ -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 `'w` lifetime from the entity. + /// + /// **You should prefer to use the typed API [`EntityMut::into_mut`] where possible and only + /// use this in cases where the actual component types are not known at + /// compile time.** + #[inline] + pub fn into_mut_by_id(self, component_id: ComponentId) -> Option> { + // 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> for EntityMut<'w> { @@ -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 into_borrow(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`]. /// @@ -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 into_ref(self) -> Option> { + 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] @@ -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 into_mut(self) -> Option> { + // 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] @@ -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::into_borrow`] where + /// possible and only use this in cases where the actual component types are not + /// known at compile time.** + #[inline] + pub fn into_borrow_by_id(self, component_id: ComponentId) -> Option> { + // 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 @@ -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::into_mut`] where possible and only + /// use this in cases where the actual component types are not known at + /// compile time.** + #[inline] + pub fn into_mut_by_id(self, component_id: ComponentId) -> Option> { + // 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.