From 8b5fee97691c5f48e85581290193da67ccd6eb04 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Wed, 22 Mar 2023 23:41:27 -0400 Subject: [PATCH 1/5] give access to world storages --- crates/bevy_ecs/src/world/unsafe_world_cell.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index 99231fe3f32ef..a708a92fa0248 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -10,7 +10,7 @@ use crate::{ }, entity::{Entities, Entity, EntityLocation}, prelude::Component, - storage::{Column, ComponentSparseSet}, + storage::{Column, ComponentSparseSet, Storages}, system::Resource, }; use bevy_ptr::Ptr; @@ -183,6 +183,17 @@ impl<'w> UnsafeWorldCell<'w> { &unsafe { self.world_metadata() }.bundles } + /// Provides access to the underlying data storages of the world. + /// + /// # Safety + /// The caller must only access world data that this [`UnsafeWorldCell`] + /// was given access to on construction. + pub unsafe fn storages(self) -> &'w Storages { + // SAFETY: Caller ensures they will only access world + // data that this instance is allowed to access. + unsafe { self.unsafe_world() }.storages() + } + /// Reads the current change tick of this world. #[inline] pub fn read_change_tick(self) -> Tick { From bc02c09044e8104a480ff9cdbabab15d66fc34e0 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Wed, 22 Mar 2023 23:47:47 -0400 Subject: [PATCH 2/5] use `UnsafeWorldCell::storages` internally --- .../bevy_ecs/src/world/unsafe_world_cell.rs | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index a708a92fa0248..c17f60bb2f149 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -291,8 +291,7 @@ impl<'w> UnsafeWorldCell<'w> { pub unsafe fn get_resource_by_id(self, component_id: ComponentId) -> Option> { // SAFETY: caller ensures that `self` has permission to access `R` // caller ensures that no mutable reference exists to `R` - unsafe { self.unsafe_world() } - .storages + unsafe { self.storages() } .resources .get(component_id)? .get_data() @@ -334,8 +333,7 @@ impl<'w> UnsafeWorldCell<'w> { pub unsafe fn get_non_send_resource_by_id(self, component_id: ComponentId) -> Option> { // SAFETY: we only access data on world that the caller has ensured is unaliased and we have // permission to access. - unsafe { self.unsafe_world() } - .storages + unsafe { self.storages() } .non_send_resources .get(component_id)? .get_data() @@ -378,8 +376,7 @@ impl<'w> UnsafeWorldCell<'w> { ) -> Option> { // SAFETY: we only access data that the caller has ensured is unaliased and `self` // has permission to access. - let (ptr, ticks) = unsafe { self.unsafe_world() } - .storages + let (ptr, ticks) = unsafe { self.storages() } .resources .get(component_id)? .get_with_ticks()?; @@ -439,8 +436,7 @@ impl<'w> UnsafeWorldCell<'w> { let change_tick = self.read_change_tick(); // SAFETY: we only access data that the caller has ensured is unaliased and `self` // has permission to access. - let (ptr, ticks) = unsafe { self.unsafe_world() } - .storages + let (ptr, ticks) = unsafe { self.storages() } .non_send_resources .get(component_id)? .get_with_ticks()?; @@ -473,8 +469,7 @@ impl<'w> UnsafeWorldCell<'w> { // - caller ensures there is no `&mut World` // - caller ensures there are no mutable borrows of this resource // - caller ensures that we have permission to access this resource - unsafe { self.unsafe_world() } - .storages + unsafe { self.storages() } .resources .get(component_id)? .get_with_ticks() @@ -498,8 +493,7 @@ impl<'w> UnsafeWorldCell<'w> { // - caller ensures there is no `&mut World` // - caller ensures there are no mutable borrows of this resource // - caller ensures that we have permission to access this resource - unsafe { self.unsafe_world() } - .storages + unsafe { self.storages() } .non_send_resources .get(component_id)? .get_with_ticks() @@ -769,7 +763,7 @@ impl<'w> UnsafeWorldCell<'w> { ) -> Option<&'w Column> { // SAFETY: caller ensures returned data is not misused and we have not created any borrows // of component/resource data - unsafe { self.unsafe_world() }.storages.tables[location.table_id].get_column(component_id) + unsafe { self.storages() }.tables[location.table_id].get_column(component_id) } #[inline] @@ -780,10 +774,7 @@ impl<'w> UnsafeWorldCell<'w> { unsafe fn fetch_sparse_set(self, component_id: ComponentId) -> Option<&'w ComponentSparseSet> { // SAFETY: caller ensures returned data is not misused and we have not created any borrows // of component/resource data - unsafe { self.unsafe_world() } - .storages - .sparse_sets - .get(component_id) + unsafe { self.storages() }.sparse_sets.get(component_id) } } From f286a82a2b9052d6cf305f4d570b9f24c08d9472 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Wed, 22 Mar 2023 23:50:34 -0400 Subject: [PATCH 3/5] tweak formatting for a safety comment --- crates/bevy_ecs/src/world/unsafe_world_cell.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index c17f60bb2f149..a15214e79e02c 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -189,8 +189,9 @@ impl<'w> UnsafeWorldCell<'w> { /// The caller must only access world data that this [`UnsafeWorldCell`] /// was given access to on construction. pub unsafe fn storages(self) -> &'w Storages { - // SAFETY: Caller ensures they will only access world - // data that this instance is allowed to access. + // SAFETY: + // - Caller ensures they will only access world + // data that this instance is allowed to access. unsafe { self.unsafe_world() }.storages() } From 13f4e7359519c8fcd636535b52417d84c74e7ef1 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Wed, 22 Mar 2023 23:52:46 -0400 Subject: [PATCH 4/5] simplify another function while we're here --- crates/bevy_ecs/src/world/unsafe_world_cell.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index a15214e79e02c..1d1ab8775c694 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -200,10 +200,7 @@ impl<'w> UnsafeWorldCell<'w> { pub fn read_change_tick(self) -> Tick { // SAFETY: // - we only access world metadata - let tick = unsafe { self.world_metadata() } - .change_tick - .load(Ordering::Acquire); - Tick::new(tick) + unsafe { self.world_metadata() }.read_change_tick() } #[inline] From 0ca5c432afdd362f5ae83fd2daa813affb011c5e Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Thu, 23 Mar 2023 00:07:03 -0400 Subject: [PATCH 5/5] tweak a safety invariant --- crates/bevy_ecs/src/world/unsafe_world_cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index 1d1ab8775c694..f30b6873ada15 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -187,7 +187,7 @@ impl<'w> UnsafeWorldCell<'w> { /// /// # Safety /// The caller must only access world data that this [`UnsafeWorldCell`] - /// was given access to on construction. + /// has been given access to. pub unsafe fn storages(self) -> &'w Storages { // SAFETY: // - Caller ensures they will only access world