Skip to content

Commit 5b90e52

Browse files
add EntityRef::get_unchecked_mut_by_id
1 parent f62f291 commit 5b90e52

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

132157
impl<'w> From<EntityMut<'w>> for EntityRef<'w> {
@@ -578,7 +603,7 @@ impl<'w> EntityMut<'w> {
578603
#[inline]
579604
pub fn get_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
580605
self.world.components().get_info(component_id)?;
581-
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
606+
// SAFETY: entity_location is valid, component_id is valid as checked by the line above, world access is unique
582607
unsafe { get_mut_by_id(self.world, self.entity, self.location, component_id) }
583608
}
584609
}
@@ -912,15 +937,17 @@ pub(crate) unsafe fn get_mut<T: Component>(
912937
)
913938
}
914939

915-
// SAFETY: EntityLocation must be valid, component_id must be valid
940+
// SAFETY:
941+
// - EntityLocation must be valid, component_id must be valid
942+
// - world access to the component must be valid, either because the caller has a `&mut` world or it synchronizes access like systems do
916943
#[inline]
917944
pub(crate) unsafe fn get_mut_by_id(
918-
world: &mut World,
945+
world: &World,
919946
entity: Entity,
920947
location: EntityLocation,
921948
component_id: ComponentId,
922949
) -> Option<MutUntyped> {
923-
// SAFETY: world access is unique, entity location and component_id required to be valid
950+
// SAFETY: world access promised by the caller, entity location and component_id required to be valid
924951
get_component_and_ticks(world, component_id, entity, location).map(|(value, ticks)| {
925952
MutUntyped {
926953
value: value.assert_unique(),

0 commit comments

Comments
 (0)