@@ -9,247 +9,10 @@ pub use resource::*;
9
9
pub use sparse_set:: * ;
10
10
pub use table:: * ;
11
11
12
- use crate :: {
13
- archetype:: { Archetype , Archetypes } ,
14
- component:: { ComponentId , ComponentTicks , Components , StorageType , TickCells } ,
15
- entity:: { Entity , EntityLocation } ,
16
- } ;
17
- use bevy_ptr:: { OwningPtr , Ptr } ;
18
- use std:: any:: TypeId ;
19
-
20
12
/// The raw data stores of a [World](crate::world::World)
21
13
#[ derive( Default ) ]
22
14
pub struct Storages {
23
15
pub sparse_sets : SparseSets ,
24
16
pub tables : Tables ,
25
17
pub resources : Resources ,
26
18
}
27
-
28
- impl Storages {
29
- /// Get a raw pointer to a particular [`Component`](crate::component::Component) and its [`ComponentTicks`] identified by their [`TypeId`]
30
- ///
31
- /// # Safety
32
- /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
33
- /// - `location` must refer to an archetype that contains `entity`
34
- /// - `Archetypes` and `Components` must come from the world this of this `Storages`
35
- /// - the caller must ensure that no aliasing rules are violated
36
- #[ inline]
37
- pub ( crate ) unsafe fn get_component_and_ticks_with_type (
38
- & self ,
39
- archetypes : & Archetypes ,
40
- components : & Components ,
41
- type_id : TypeId ,
42
- storage_type : StorageType ,
43
- entity : Entity ,
44
- location : EntityLocation ,
45
- ) -> Option < ( Ptr < ' _ > , TickCells < ' _ > ) > {
46
- let component_id = components. get_id ( type_id) ?;
47
- // SAFETY: component_id is valid, the rest is deferred to caller
48
- self . get_component_and_ticks ( archetypes, component_id, storage_type, entity, location)
49
- }
50
-
51
- /// Get a raw pointer to a particular [`Component`](crate::component::Component) and its [`ComponentTicks`]
52
- ///
53
- /// # Safety
54
- /// - `location` must refer to an archetype that contains `entity`
55
- /// - `component_id` must be valid
56
- /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
57
- /// - `Archetypes` and `Components` must come from the world this of this `Storages`
58
- /// - the caller must ensure that no aliasing rules are violated
59
- #[ inline]
60
- pub ( crate ) unsafe fn get_component_and_ticks (
61
- & self ,
62
- archetypes : & Archetypes ,
63
- component_id : ComponentId ,
64
- storage_type : StorageType ,
65
- entity : Entity ,
66
- location : EntityLocation ,
67
- ) -> Option < ( Ptr < ' _ > , TickCells < ' _ > ) > {
68
- match storage_type {
69
- StorageType :: Table => {
70
- let ( components, table_row) =
71
- fetch_table ( archetypes, self , location, component_id) ?;
72
-
73
- // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
74
- Some ( (
75
- components. get_data_unchecked ( table_row) ,
76
- TickCells {
77
- added : components. get_added_ticks_unchecked ( table_row) ,
78
- changed : components. get_changed_ticks_unchecked ( table_row) ,
79
- } ,
80
- ) )
81
- }
82
- StorageType :: SparseSet => fetch_sparse_set ( self , component_id) ?. get_with_ticks ( entity) ,
83
- }
84
- }
85
-
86
- /// Get a raw pointer to a particular [`Component`](crate::component::Component) on a particular [`Entity`], identified by the component's type
87
- ///
88
- /// # Safety
89
- /// - `location` must refer to an archetype that contains `entity`
90
- /// the archetype
91
- /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
92
- /// - `Archetypes` and `Components` must come from the world this of this `Storages`
93
- /// - the caller must ensure that no aliasing rules are violated
94
- #[ inline]
95
- pub ( crate ) unsafe fn get_component_with_type (
96
- & self ,
97
- archetypes : & Archetypes ,
98
- components : & Components ,
99
- type_id : TypeId ,
100
- storage_type : StorageType ,
101
- entity : Entity ,
102
- location : EntityLocation ,
103
- ) -> Option < Ptr < ' _ > > {
104
- let component_id = components. get_id ( type_id) ?;
105
- // SAFETY: component_id is valid, the rest is deferred to caller
106
- self . get_component ( archetypes, component_id, storage_type, entity, location)
107
- }
108
-
109
- /// Get a raw pointer to a particular [`Component`](crate::component::Component) on a particular [`Entity`] in the provided [`World`](crate::world::World).
110
- ///
111
- /// # Safety
112
- /// - `location` must refer to an archetype that contains `entity`
113
- /// the archetype
114
- /// - `component_id`
115
- /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
116
- /// - `Archetypes` and `Components` must come from the world this of this `Storages`
117
- /// - the caller must ensure that no aliasing rules are violated
118
- #[ inline]
119
- pub ( crate ) unsafe fn get_component (
120
- & self ,
121
- archetypes : & Archetypes ,
122
- component_id : ComponentId ,
123
- storage_type : StorageType ,
124
- entity : Entity ,
125
- location : EntityLocation ,
126
- ) -> Option < Ptr < ' _ > > {
127
- // SAFETY: component_id exists and is therefore valid
128
- match storage_type {
129
- StorageType :: Table => {
130
- let ( components, table_row) =
131
- fetch_table ( archetypes, self , location, component_id) ?;
132
- // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
133
- Some ( components. get_data_unchecked ( table_row) )
134
- }
135
- StorageType :: SparseSet => fetch_sparse_set ( self , component_id) ?. get ( entity) ,
136
- }
137
- }
138
-
139
- /// Get a raw pointer to the [`ComponentTicks`] on a particular [`Entity`], identified by the component's [`TypeId`]
140
- ///
141
- /// # Safety
142
- /// - `location` must refer to an archetype that contains `entity`
143
- /// the archetype
144
- /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
145
- /// - `Archetypes` and `Components` must come from the world this of this `Storages`
146
- /// - the caller must ensure that no aliasing rules are violated
147
- #[ inline]
148
- pub ( crate ) unsafe fn get_ticks_with_type (
149
- & self ,
150
- archetypes : & Archetypes ,
151
- components : & Components ,
152
- type_id : TypeId ,
153
- storage_type : StorageType ,
154
- entity : Entity ,
155
- location : EntityLocation ,
156
- ) -> Option < ComponentTicks > {
157
- let component_id = components. get_id ( type_id) ?;
158
- // SAFETY: component_id is valid, the rest is deferred to caller
159
- self . get_ticks ( archetypes, component_id, storage_type, entity, location)
160
- }
161
-
162
- /// Get a raw pointer to the [`ComponentTicks`] on a particular [`Entity`]
163
- ///
164
- /// # Safety
165
- /// - `location` must refer to an archetype that contains `entity`
166
- /// the archetype
167
- /// - `component_id` must be valid
168
- /// - `storage_type` must accurately reflect where the components for `component_id` are stored.
169
- /// - `Archetypes` and `Components` must come from the world this of this `Storages`
170
- /// - the caller must ensure that no aliasing rules are violated
171
- #[ inline]
172
- pub ( crate ) unsafe fn get_ticks (
173
- & self ,
174
- archetypes : & Archetypes ,
175
- component_id : ComponentId ,
176
- storage_type : StorageType ,
177
- entity : Entity ,
178
- location : EntityLocation ,
179
- ) -> Option < ComponentTicks > {
180
- match storage_type {
181
- StorageType :: Table => {
182
- let ( components, table_row) =
183
- fetch_table ( archetypes, self , location, component_id) ?;
184
- // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
185
- Some ( components. get_ticks_unchecked ( table_row) )
186
- }
187
- StorageType :: SparseSet => fetch_sparse_set ( self , component_id) ?. get_ticks ( entity) ,
188
- }
189
- }
190
- }
191
-
192
- impl Storages {
193
- /// Moves component data out of storage.
194
- ///
195
- /// This function leaves the underlying memory unchanged, but the component behind
196
- /// returned pointer is semantically owned by the caller and will not be dropped in its original location.
197
- /// Caller is responsible to drop component data behind returned pointer.
198
- ///
199
- /// # Safety
200
- /// - `entity_location` must be within bounds of the given archetype and `entity` must exist inside the `archetype`
201
- /// - `component_id` must be valid
202
- /// - `components` must come from the same world as `self`
203
- /// - The relevant table row **must be removed** by the caller once all components are taken
204
- #[ inline]
205
- pub ( crate ) unsafe fn take_component < ' a > (
206
- & ' a mut self ,
207
- components : & Components ,
208
- archetype : & Archetype ,
209
- removed_components : & mut SparseSet < ComponentId , Vec < Entity > > ,
210
- component_id : ComponentId ,
211
- entity : Entity ,
212
- location : EntityLocation ,
213
- ) -> OwningPtr < ' a > {
214
- // SAFETY: component id is valid as per the functions safety requirements
215
- let component_info = components. get_info_unchecked ( component_id) ;
216
- let removed_components = removed_components. get_or_insert_with ( component_id, Vec :: new) ;
217
- removed_components. push ( entity) ;
218
- match component_info. storage_type ( ) {
219
- StorageType :: Table => {
220
- let table = & mut self . tables [ archetype. table_id ( ) ] ;
221
- // SAFETY: archetypes will always point to valid columns
222
- let components = table. get_column_mut ( component_id) . unwrap ( ) ;
223
- // SAFETY: archetypes only store valid table_rows
224
- let table_row = archetype. entity_table_row ( location. archetype_row ) ;
225
- // SAFETY: promote is safe because the caller promises to remove the table row without dropping it immediately afterwards
226
- components. get_data_unchecked_mut ( table_row) . promote ( )
227
- }
228
- StorageType :: SparseSet => self
229
- . sparse_sets
230
- . get_mut ( component_id)
231
- . unwrap ( )
232
- . remove_and_forget ( entity)
233
- . unwrap ( ) ,
234
- }
235
- }
236
- }
237
-
238
- #[ inline]
239
- unsafe fn fetch_table < ' s > (
240
- archetypes : & Archetypes ,
241
- storages : & ' s Storages ,
242
- location : EntityLocation ,
243
- component_id : ComponentId ,
244
- ) -> Option < ( & ' s Column , TableRow ) > {
245
- let archetype = & archetypes[ location. archetype_id ] ;
246
- let table = & storages. tables [ archetype. table_id ( ) ] ;
247
- let components = table. get_column ( component_id) ?;
248
- let table_row = archetype. entity_table_row ( location. archetype_row ) ;
249
- Some ( ( components, table_row) )
250
- }
251
-
252
- #[ inline]
253
- fn fetch_sparse_set ( storages : & Storages , component_id : ComponentId ) -> Option < & ComponentSparseSet > {
254
- storages. sparse_sets . get ( component_id)
255
- }
0 commit comments