From 4918e10c35410618752c0babd954752cf18a909c Mon Sep 17 00:00:00 2001 From: james7132 Date: Tue, 7 Jun 2022 02:10:05 -0700 Subject: [PATCH] Shrink Resources --- crates/bevy_ecs/src/storage/resource.rs | 46 +++++++++++++++++-------- crates/bevy_ecs/src/world/mod.rs | 31 +++++++++-------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/crates/bevy_ecs/src/storage/resource.rs b/crates/bevy_ecs/src/storage/resource.rs index ebf98aef63497..4a1603b1e01f3 100644 --- a/crates/bevy_ecs/src/storage/resource.rs +++ b/crates/bevy_ecs/src/storage/resource.rs @@ -5,14 +5,18 @@ use crate::storage::{Column, SparseSet}; use bevy_ptr::{OwningPtr, Ptr, PtrMut, UnsafeCellDeref}; use std::cell::UnsafeCell; +pub(crate) struct ResourceInfo { + pub data: Column, + pub component_info: ArchetypeComponentInfo, +} + /// The backing store for all [`Resource`]s stored in the [`World`]. /// /// [`Resource`]: crate::system::Resource /// [`World`]: crate::world::World #[derive(Default)] pub struct Resources { - pub(crate) resources: SparseSet, - pub(crate) components: SparseSet, + pub(crate) resources: SparseSet, } impl Resources { @@ -22,9 +26,9 @@ impl Resources { &self, component_id: ComponentId, ) -> Option { - self.components + self.resources .get(component_id) - .map(|info| info.archetype_component_id) + .map(|info| info.component_info.archetype_component_id) } /// The total number of resoruces stored in the [`World`] @@ -44,35 +48,39 @@ impl Resources { self.resources.is_empty() } + /// Gets a read-only [`Ptr`] to a resource, if available. #[inline] pub fn get(&self, component_id: ComponentId) -> Option> { - let column = self.resources.get(component_id)?; + let column = &self.resources.get(component_id)?.data; // SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the // ptr value / drop is called when R is dropped (!column.is_empty()).then(|| unsafe { column.get_data_unchecked(0) }) } + /// Gets a read-only [`Ptr`] to a resource, if available. #[inline] pub fn get_mut(&mut self, component_id: ComponentId) -> Option> { - let column = self.resources.get_mut(component_id)?; + let column = &mut self.resources.get_mut(component_id)?.data; // SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the // ptr value / drop is called when R is dropped (!column.is_empty()).then(|| unsafe { column.get_data_unchecked_mut(0) }) } + /// Gets the [`ComponentTicks`] to a resource, if available. #[inline] pub fn get_ticks(&self, component_id: ComponentId) -> Option<&ComponentTicks> { - let column = self.resources.get(component_id)?; + let column = &self.resources.get(component_id)?.data; // SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the // ptr value / drop is called when R is dropped (!column.is_empty()).then(|| unsafe { column.get_ticks_unchecked(0).deref() }) } + /// Checks if the a resource is currently stored with a given ID. #[inline] pub fn contains(&self, component_id: ComponentId) -> bool { self.resources .get(component_id) - .map(|column| !column.is_empty()) + .map(|info| !info.data.is_empty()) .unwrap_or(false) } @@ -81,15 +89,18 @@ impl Resources { &self, component_id: ComponentId, ) -> Option<(Ptr<'_>, &UnsafeCell)> { - let column = self.resources.get(component_id)?; + let column = &self.resources.get(component_id)?.data; // SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the // ptr value / drop is called when R is dropped (!column.is_empty()) .then(|| unsafe { (column.get_data_unchecked(0), column.get_ticks_unchecked(0)) }) } + /// Inserts a resource into the world. + /// /// # Safety - /// - ptr must point to valid data of this column's component type + /// ptr must point to valid data of this column's component type which + /// must correspond to the provided ID. #[inline] pub unsafe fn insert( &mut self, @@ -97,16 +108,21 @@ impl Resources { data: OwningPtr<'_>, ticks: ComponentTicks, ) -> Option<()> { - let column = self.resources.get_mut(component_id)?; + let column = &mut self.resources.get_mut(component_id)?.data; debug_assert!(column.is_empty()); column.push(data, ticks); Some(()) } + /// Removes a resource from the world. + /// + /// # Safety + /// ptr must point to valid data of this column's component type which + /// must correspond to the provided ID. #[inline] #[must_use = "The returned pointer to the removed component should be used or dropped"] pub fn remove(&mut self, component_id: ComponentId) -> Option<(OwningPtr<'_>, ComponentTicks)> { - let column = self.resources.get_mut(component_id)?; + let column = &mut self.resources.get_mut(component_id)?.data; if column.is_empty() { return None; } @@ -117,7 +133,7 @@ impl Resources { #[inline] pub(crate) fn remove_and_drop(&mut self, component_id: ComponentId) -> Option<()> { - let column = self.resources.get_mut(component_id)?; + let column = &mut self.resources.get_mut(component_id)?.data; if column.is_empty() { return None; } @@ -130,8 +146,8 @@ impl Resources { } pub fn check_change_ticks(&mut self, change_tick: u32) { - for column in self.resources.values_mut() { - column.check_change_ticks(change_tick); + for info in self.resources.values_mut() { + info.data.check_change_ticks(change_tick); } } } diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index fdbf8211a1253..1f1c3541e1add 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -16,7 +16,7 @@ use crate::{ }, entity::{AllocAtWithoutReplacement, Entities, Entity}, query::{QueryState, WorldQuery}, - storage::{Column, SparseSet, Storages}, + storage::{Column, ResourceInfo, SparseSet, Storages}, system::Resource, }; use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref}; @@ -1195,22 +1195,25 @@ impl World { unsafe fn initialize_resource_internal(&mut self, component_id: ComponentId) -> &mut Column { // SAFE: resource archetype always exists let resources = &mut self.storages.resources; - let resource_components = &mut resources.components; let resources = &mut resources.resources; let archetype_component_count = &mut self.archetypes.archetype_component_count; let components = &self.components; - resources.get_or_insert_with(component_id, || { - resource_components.insert( - component_id, - ArchetypeComponentInfo { - archetype_component_id: ArchetypeComponentId::new(*archetype_component_count), - storage_type: StorageType::Table, - }, - ); - *archetype_component_count += 1; - let component_info = components.get_info_unchecked(component_id); - Column::with_capacity(component_info, 1) - }) + &mut resources + .get_or_insert_with(component_id, || { + let component_info = components.get_info_unchecked(component_id); + let info = ResourceInfo { + data: Column::with_capacity(component_info, 1), + component_info: ArchetypeComponentInfo { + archetype_component_id: ArchetypeComponentId::new( + *archetype_component_count, + ), + storage_type: StorageType::Table, + }, + }; + *archetype_component_count += 1; + info + }) + .data } pub(crate) fn initialize_resource(&mut self) -> ComponentId {