termite/storage/
storage.rs1use std::cell::UnsafeCell;
2
3use crate::{
4 ChangeTicks, ComponentDescriptor, ComponentId, ComponentInfo, Entity, EntityIdSet, SparseArray,
5 SparseStorage,
6};
7
8pub struct StorageSets<T> {
9 storage_sets: SparseArray<T>,
10}
11
12impl<T> Default for StorageSets<T> {
13 #[inline]
14 fn default() -> Self {
15 Self {
16 storage_sets: SparseArray::new(),
17 }
18 }
19}
20
21impl<T> StorageSets<T>
22where
23 T: StorageSet,
24{
25 #[inline]
26 pub fn get(&self, id: ComponentId) -> Option<&T> {
27 self.storage_sets.get(id.index())
28 }
29
30 #[inline]
31 pub fn get_mut(&mut self, id: ComponentId) -> Option<&mut T> {
32 self.storage_sets.get_mut(id.index())
33 }
34
35 #[inline]
36 pub unsafe fn get_unchecked(&self, id: ComponentId) -> &T {
37 unsafe { self.storage_sets.get_unchecked(id.index()) }
38 }
39
40 #[inline]
41 pub unsafe fn get_unchecked_mut(&mut self, id: ComponentId) -> &mut T {
42 unsafe { self.storage_sets.get_unchecked_mut(id.index()) }
43 }
44
45 #[inline]
46 pub fn initialize(&mut self, info: &ComponentInfo) {
47 if !self.storage_sets.contains(info.id().index()) {
48 let set = StorageSet::new(*info.descriptor(), info.id().index());
49 self.storage_sets.insert(info.id().index(), set);
50 }
51 }
52
53 #[inline]
54 pub fn remove_and_drop(&mut self, entity: Entity, id: ComponentId) {
55 if let Some(storage) = self.get_mut(id) {
56 storage.remove_and_drop(entity);
57 }
58 }
59
60 #[inline]
61 pub fn remove(&mut self, entity: Entity) {
62 for (_, storage) in self.storage_sets.iter_mut() {
63 storage.remove_and_drop(entity);
64 }
65 }
66}
67
68#[derive(Default)]
69pub struct ComponentStorage {
70 sparse: StorageSets<SparseStorage>,
71}
72
73impl ComponentStorage {
74 #[inline]
75 pub fn sparse(&self) -> &StorageSets<SparseStorage> {
76 &self.sparse
77 }
78
79 #[inline]
80 pub fn sparse_mut(&mut self) -> &mut StorageSets<SparseStorage> {
81 &mut self.sparse
82 }
83
84 #[inline]
85 pub fn remove(&mut self, entity: Entity) {
86 self.sparse.remove(entity);
87 }
88
89 #[inline]
90 pub fn contains(&self, id: ComponentId, entity: Entity) -> bool {
91 if let Some(storage) = self.sparse.get(id) {
92 return storage.contains(entity);
93 }
94
95 false
96 }
97
98 #[inline]
99 pub fn entity_ids(&self, id: ComponentId) -> EntityIdSet {
100 if let Some(sparse) = self.sparse.get(id) {
101 return sparse.entity_ids();
102 }
103
104 EntityIdSet::default()
105 }
106
107 #[inline]
108 pub fn check_change_ticks(&mut self, tick: u32) {
109 for (_, storage) in self.sparse.storage_sets.iter_mut() {
110 storage.check_change_ticks(tick);
111 }
112 }
113}
114
115pub trait StorageSet: Send + Sync + 'static {
116 fn new(desc: ComponentDescriptor, capacity: usize) -> Self;
118
119 fn contains(&self, entity: Entity) -> bool;
121
122 fn entity_ids(&self) -> EntityIdSet;
123
124 unsafe fn insert(&mut self, entity: Entity, component: *mut u8, change_ticks: u32);
129
130 unsafe fn remove_unchecked(&mut self, entity: Entity, component: *mut u8);
136
137 fn remove_and_drop(&mut self, entity: Entity);
139
140 unsafe fn get_unchecked(&self, entity: Entity) -> *mut u8;
145
146 #[inline]
148 fn get(&self, entity: Entity) -> Option<*mut u8> {
149 if self.contains(entity) {
150 unsafe { Some(self.get_unchecked(entity)) }
151 } else {
152 None
153 }
154 }
155
156 unsafe fn get_ticks_unchecked(&self, entity: Entity) -> &UnsafeCell<ChangeTicks>;
161
162 unsafe fn get_with_ticks_unchecked(
167 &self,
168 entity: Entity,
169 ) -> (*mut u8, &UnsafeCell<ChangeTicks>);
170}