Skip to content

Commit f5bdeb9

Browse files
add get_resource_unchecked_mut_by_id
1 parent b027d40 commit f5bdeb9

File tree

1 file changed

+26
-7
lines changed
  • crates/bevy_ecs/src/world

1 file changed

+26
-7
lines changed

crates/bevy_ecs/src/world/mod.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,23 +1499,42 @@ impl World {
14991499
/// use this in cases where the actual types are not known at compile time.**
15001500
#[inline]
15011501
pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
1502+
// SAFETY: unique world access
1503+
unsafe { self.get_resource_unchecked_mut_by_id(component_id) }
1504+
}
1505+
1506+
/// Gets a resource to the resource with the id [`ComponentId`] if it exists.
1507+
/// The returned pointer may be used to modify the resource, as long as the mutable borrow
1508+
/// of the [`World`] is still valid.
1509+
///
1510+
/// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
1511+
/// use this in cases where the actual types are not known at compile time.**
1512+
///
1513+
/// # Safety
1514+
/// This will allow aliased mutable access to the given resource type. The caller must ensure
1515+
/// that there is either only one mutable access or multiple immutable accesses at a time.
1516+
#[inline]
1517+
pub unsafe fn get_resource_unchecked_mut_by_id(
1518+
&self,
1519+
component_id: ComponentId,
1520+
) -> Option<MutUntyped<'_>> {
15021521
let info = self.components.get_info(component_id)?;
15031522
if !info.is_send_and_sync() {
15041523
self.validate_non_send_access_untyped(info.name());
15051524
}
15061525

1507-
let change_tick = self.change_tick();
1508-
15091526
let (ptr, ticks) = self.get_resource_with_ticks(component_id)?;
15101527

1511-
// SAFETY: This function has exclusive access to the world so nothing aliases `ticks`.
1528+
// SAFETY:
15121529
// - index is in-bounds because the column is initialized and non-empty
1513-
// - no other reference to the ticks of the same row can exist at the same time
1514-
let ticks = unsafe { Ticks::from_tick_cells(ticks, self.last_change_tick(), change_tick) };
1530+
// - no other reference to the ticks, because the caller promises it
1531+
let ticks = unsafe {
1532+
Ticks::from_tick_cells(ticks, self.last_change_tick(), self.read_change_tick())
1533+
};
15151534

15161535
Some(MutUntyped {
15171536
// SAFETY: This function has exclusive access to the world so nothing aliases `ptr`.
1518-
value: unsafe { ptr.assert_unique() },
1537+
value: ptr.assert_unique(),
15191538
ticks,
15201539
})
15211540
}
@@ -1574,7 +1593,7 @@ impl World {
15741593
component_id: ComponentId,
15751594
) -> Option<MutUntyped<'_>> {
15761595
self.components().get_info(component_id)?;
1577-
// SAFETY: entity_location is valid, component_id is valid as checked by the line above
1596+
// SAFETY: entity_location is valid, component_id is valid as checked by the line above, world access is unique
15781597
unsafe {
15791598
get_mut_by_id(
15801599
self,

0 commit comments

Comments
 (0)