Skip to content

Commit 74db01f

Browse files
add EntityRef::get_unchecked_mut_by_id
1 parent de54033 commit 74db01f

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

crates/bevy_ecs/src/world/entity_ref.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,31 @@ impl<'w> EntityRef<'w> {
128128
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
129129
unsafe { get_component(self.world, component_id, self.entity, self.location) }
130130
}
131+
132+
/// Gets the component of the given [`ComponentId`] from the entity.
133+
///
134+
/// **You should prefer to use the typed API where possible and only
135+
/// use this in cases where the actual component types are not known at
136+
/// compile time.**
137+
///
138+
/// Unlike [`EntityRef::get`], this returns a raw pointer to the component,
139+
/// which is only valid while the `'w` borrow of the lifetime is active.
140+
///
141+
/// # Safety
142+
///
143+
/// - The returned reference must never alias a mutable borrow of this component.
144+
/// - The returned reference must not be used after this component is moved which
145+
/// may happen from **any** `insert_component`, `remove_component` or `despawn`
146+
/// operation on this world (non-exhaustive list).
147+
#[inline]
148+
pub unsafe fn get_unchecked_mut_by_id(
149+
&self,
150+
component_id: ComponentId,
151+
) -> Option<MutUntyped<'w>> {
152+
self.world.components().get_info(component_id)?;
153+
// SAFETY: entity_location is valid, component_id is valid as checked by the line above, world access is promised by the caller
154+
get_mut_by_id(self.world, self.entity, self.location, component_id)
155+
}
131156
}
132157

133158
impl<'w> From<EntityMut<'w>> for EntityRef<'w> {
@@ -586,7 +611,7 @@ impl<'w> EntityMut<'w> {
586611
#[inline]
587612
pub fn get_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
588613
self.world.components().get_info(component_id)?;
589-
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
614+
// SAFETY: entity_location is valid, component_id is valid as checked by the line above, world access is unique
590615
unsafe { get_mut_by_id(self.world, self.entity, self.location, component_id) }
591616
}
592617
}
@@ -920,15 +945,17 @@ pub(crate) unsafe fn get_mut<T: Component>(
920945
)
921946
}
922947

923-
// SAFETY: EntityLocation must be valid, component_id must be valid
948+
// SAFETY:
949+
// - EntityLocation must be valid, component_id must be valid
950+
// - world access to the component must be valid, either because the caller has a `&mut` world or it synchronizes access like systems do
924951
#[inline]
925952
pub(crate) unsafe fn get_mut_by_id(
926-
world: &mut World,
953+
world: &World,
927954
entity: Entity,
928955
location: EntityLocation,
929956
component_id: ComponentId,
930957
) -> Option<MutUntyped> {
931-
// SAFETY: world access is unique, entity location and component_id required to be valid
958+
// SAFETY: world access promised by the caller, entity location and component_id required to be valid
932959
get_component_and_ticks(world, component_id, entity, location).map(|(value, ticks)| {
933960
MutUntyped {
934961
value: value.assert_unique(),

0 commit comments

Comments
 (0)