Skip to content

Commit d8758f8

Browse files
committed
Shrink Resources
1 parent 56aa9d5 commit d8758f8

File tree

2 files changed

+48
-29
lines changed

2 files changed

+48
-29
lines changed

crates/bevy_ecs/src/storage/resource.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ use crate::storage::{Column, SparseSet};
55
use bevy_ptr::{OwningPtr, Ptr, PtrMut, UnsafeCellDeref};
66
use std::cell::UnsafeCell;
77

8+
pub(crate) struct ResourceInfo {
9+
pub data: Column,
10+
pub component_info: ArchetypeComponentInfo,
11+
}
12+
813
/// The backing store for all [`Resource`]s stored in the [`World`].
914
///
1015
/// [`Resource`]: crate::system::Resource
1116
/// [`World`]: crate::world::World
1217
#[derive(Default)]
1318
pub struct Resources {
14-
pub(crate) resources: SparseSet<ComponentId, Column>,
15-
pub(crate) components: SparseSet<ComponentId, ArchetypeComponentInfo>,
19+
pub(crate) resources: SparseSet<ComponentId, ResourceInfo>,
1620
}
1721

1822
impl Resources {
@@ -22,9 +26,9 @@ impl Resources {
2226
&self,
2327
component_id: ComponentId,
2428
) -> Option<ArchetypeComponentId> {
25-
self.components
29+
self.resources
2630
.get(component_id)
27-
.map(|info| info.archetype_component_id)
31+
.map(|info| info.component_info.archetype_component_id)
2832
}
2933

3034
/// The total number of resoruces stored in the [`World`]
@@ -44,35 +48,39 @@ impl Resources {
4448
self.resources.is_empty()
4549
}
4650

51+
/// Gets a read-only [`Ptr`] to a resource, if available.
4752
#[inline]
4853
pub fn get(&self, component_id: ComponentId) -> Option<Ptr<'_>> {
49-
let column = self.resources.get(component_id)?;
54+
let column = &self.resources.get(component_id)?.data;
5055
// SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the
5156
// ptr value / drop is called when R is dropped
5257
(!column.is_empty()).then(|| unsafe { column.get_data_unchecked(0) })
5358
}
5459

60+
/// Gets a read-only [`Ptr`] to a resource, if available.
5561
#[inline]
5662
pub fn get_mut(&mut self, component_id: ComponentId) -> Option<PtrMut<'_>> {
57-
let column = self.resources.get_mut(component_id)?;
63+
let column = &mut self.resources.get_mut(component_id)?.data;
5864
// SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the
5965
// ptr value / drop is called when R is dropped
6066
(!column.is_empty()).then(|| unsafe { column.get_data_unchecked_mut(0) })
6167
}
6268

69+
/// Gets the [`ComponentTicks`] to a resource, if available.
6370
#[inline]
6471
pub fn get_ticks(&self, component_id: ComponentId) -> Option<&ComponentTicks> {
65-
let column = self.resources.get(component_id)?;
72+
let column = &self.resources.get(component_id)?.data;
6673
// SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the
6774
// ptr value / drop is called when R is dropped
6875
(!column.is_empty()).then(|| unsafe { column.get_ticks_unchecked(0).deref() })
6976
}
7077

78+
/// Checks if the a resource is currently stored with a given ID.
7179
#[inline]
7280
pub fn contains(&self, component_id: ComponentId) -> bool {
7381
self.resources
7482
.get(component_id)
75-
.map(|column| !column.is_empty())
83+
.map(|info| !info.data.is_empty())
7684
.unwrap_or(false)
7785
}
7886

@@ -81,32 +89,40 @@ impl Resources {
8189
&self,
8290
component_id: ComponentId,
8391
) -> Option<(Ptr<'_>, &UnsafeCell<ComponentTicks>)> {
84-
let column = self.resources.get(component_id)?;
92+
let column = &self.resources.get(component_id)?.data;
8593
// SAFE: if a resource column exists, row 0 exists as well. caller takes ownership of the
8694
// ptr value / drop is called when R is dropped
8795
(!column.is_empty())
8896
.then(|| unsafe { (column.get_data_unchecked(0), column.get_ticks_unchecked(0)) })
8997
}
9098

99+
/// Inserts a resource into the world.
100+
///
91101
/// # Safety
92-
/// - ptr must point to valid data of this column's component type
102+
/// ptr must point to valid data of this column's component type which
103+
/// must correspond to the provided ID.
93104
#[inline]
94105
pub unsafe fn insert(
95106
&mut self,
96107
component_id: ComponentId,
97108
data: OwningPtr<'_>,
98109
ticks: ComponentTicks,
99110
) -> Option<()> {
100-
let column = self.resources.get_mut(component_id)?;
111+
let column = &mut self.resources.get_mut(component_id)?.data;
101112
debug_assert!(column.is_empty());
102113
column.push(data, ticks);
103114
Some(())
104115
}
105116

117+
/// Removes a resource from the world.
118+
///
119+
/// # Safety
120+
/// ptr must point to valid data of this column's component type which
121+
/// must correspond to the provided ID.
106122
#[inline]
107123
#[must_use = "The returned pointer to the removed component should be used or dropped"]
108124
pub fn remove(&mut self, component_id: ComponentId) -> Option<(OwningPtr<'_>, ComponentTicks)> {
109-
let column = self.resources.get_mut(component_id)?;
125+
let column = &mut self.resources.get_mut(component_id)?.data;
110126
if column.is_empty() {
111127
return None;
112128
}
@@ -117,7 +133,7 @@ impl Resources {
117133

118134
#[inline]
119135
pub(crate) fn remove_and_drop(&mut self, component_id: ComponentId) -> Option<()> {
120-
let column = self.resources.get_mut(component_id)?;
136+
let column = &mut self.resources.get_mut(component_id)?.data;
121137
if column.is_empty() {
122138
return None;
123139
}
@@ -130,8 +146,8 @@ impl Resources {
130146
}
131147

132148
pub fn check_change_ticks(&mut self, change_tick: u32) {
133-
for column in self.resources.values_mut() {
134-
column.check_change_ticks(change_tick);
149+
for info in self.resources.values_mut() {
150+
info.data.check_change_ticks(change_tick);
135151
}
136152
}
137153
}

crates/bevy_ecs/src/world/mod.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
},
1717
entity::{AllocAtWithoutReplacement, Entities, Entity},
1818
query::{QueryState, WorldQuery},
19-
storage::{Column, SparseSet, Storages},
19+
storage::{Column, ResourceInfo, SparseSet, Storages},
2020
system::Resource,
2121
};
2222
use bevy_ptr::{OwningPtr, Ptr, UnsafeCellDeref};
@@ -1195,22 +1195,25 @@ impl World {
11951195
unsafe fn initialize_resource_internal(&mut self, component_id: ComponentId) -> &mut Column {
11961196
// SAFE: resource archetype always exists
11971197
let resources = &mut self.storages.resources;
1198-
let resource_components = &mut resources.components;
11991198
let resources = &mut resources.resources;
12001199
let archetype_component_count = &mut self.archetypes.archetype_component_count;
12011200
let components = &self.components;
1202-
resources.get_or_insert_with(component_id, || {
1203-
resource_components.insert(
1204-
component_id,
1205-
ArchetypeComponentInfo {
1206-
archetype_component_id: ArchetypeComponentId::new(*archetype_component_count),
1207-
storage_type: StorageType::Table,
1208-
},
1209-
);
1210-
*archetype_component_count += 1;
1211-
let component_info = components.get_info_unchecked(component_id);
1212-
Column::with_capacity(component_info, 1)
1213-
})
1201+
&mut resources
1202+
.get_or_insert_with(component_id, || {
1203+
let component_info = components.get_info_unchecked(component_id);
1204+
let info = ResourceInfo {
1205+
data: Column::with_capacity(component_info, 1),
1206+
component_info: ArchetypeComponentInfo {
1207+
archetype_component_id: ArchetypeComponentId::new(
1208+
*archetype_component_count,
1209+
),
1210+
storage_type: StorageType::Table,
1211+
},
1212+
};
1213+
*archetype_component_count += 1;
1214+
info
1215+
})
1216+
.data
12141217
}
12151218

12161219
pub(crate) fn initialize_resource<R: Resource>(&mut self) -> ComponentId {

0 commit comments

Comments
 (0)