1
1
use crate :: {
2
2
component:: { ComponentId , ComponentInfo , ComponentTicks } ,
3
3
entity:: Entity ,
4
- storage:: BlobVec ,
4
+ storage:: Column ,
5
5
} ;
6
6
use bevy_ptr:: { OwningPtr , Ptr } ;
7
7
use std:: { cell:: UnsafeCell , hash:: Hash , marker:: PhantomData } ;
@@ -96,8 +96,7 @@ impl<I: SparseSetIndex, V> SparseArray<I, V> {
96
96
/// Designed for relatively fast insertions and deletions.
97
97
#[ derive( Debug ) ]
98
98
pub struct ComponentSparseSet {
99
- dense : BlobVec ,
100
- ticks : Vec < UnsafeCell < ComponentTicks > > ,
99
+ dense : Column ,
101
100
// Internally this only relies on the Entity ID to keep track of where the component data is
102
101
// stored for entities that are alive. The generation is not required, but is stored
103
102
// in debug builds to validate that access is correct.
@@ -111,19 +110,14 @@ pub struct ComponentSparseSet {
111
110
impl ComponentSparseSet {
112
111
pub fn new ( component_info : & ComponentInfo , capacity : usize ) -> Self {
113
112
Self {
114
- // SAFE: component_info.drop() is compatible with the items that will be inserted.
115
- dense : unsafe {
116
- BlobVec :: new ( component_info. layout ( ) , component_info. drop ( ) , capacity)
117
- } ,
118
- ticks : Vec :: with_capacity ( capacity) ,
113
+ dense : Column :: with_capacity ( component_info, capacity) ,
119
114
entities : Vec :: with_capacity ( capacity) ,
120
115
sparse : Default :: default ( ) ,
121
116
}
122
117
}
123
118
124
119
pub fn clear ( & mut self ) {
125
120
self . dense . clear ( ) ;
126
- self . ticks . clear ( ) ;
127
121
self . entities . clear ( ) ;
128
122
self . sparse . clear ( ) ;
129
123
}
@@ -148,20 +142,13 @@ impl ComponentSparseSet {
148
142
if let Some ( & dense_index) = self . sparse . get ( entity. id ( ) ) {
149
143
#[ cfg( debug_assertions) ]
150
144
assert_eq ! ( entity, self . entities[ dense_index as usize ] ) ;
151
- let _entity = self . dense . replace_unchecked ( dense_index as usize , value) ;
152
- * self . ticks . get_unchecked_mut ( dense_index as usize ) =
153
- UnsafeCell :: new ( ComponentTicks :: new ( change_tick) ) ;
145
+ self . dense . replace ( dense_index as usize , value, change_tick) ;
154
146
} else {
155
147
let dense_index = self . dense . len ( ) ;
156
- self . dense . push ( value) ;
148
+ self . dense . push ( value, ComponentTicks :: new ( change_tick ) ) ;
157
149
self . sparse . insert ( entity. id ( ) , dense_index as u32 ) ;
158
150
#[ cfg( debug_assertions) ]
159
- {
160
- assert_eq ! ( self . ticks. len( ) , dense_index) ;
161
- assert_eq ! ( self . entities. len( ) , dense_index) ;
162
- }
163
- self . ticks
164
- . push ( UnsafeCell :: new ( ComponentTicks :: new ( change_tick) ) ) ;
151
+ assert_eq ! ( self . entities. len( ) , dense_index) ;
165
152
#[ cfg( not( debug_assertions) ) ]
166
153
self . entities . push ( entity. id ( ) ) ;
167
154
#[ cfg( debug_assertions) ]
@@ -192,7 +179,7 @@ impl ComponentSparseSet {
192
179
#[ cfg( debug_assertions) ]
193
180
assert_eq ! ( entity, self . entities[ dense_index] ) ;
194
181
// SAFE: if the sparse index points to something in the dense vec, it exists
195
- unsafe { self . dense . get_unchecked ( dense_index) }
182
+ unsafe { self . dense . get_data_unchecked ( dense_index) }
196
183
} )
197
184
}
198
185
@@ -204,8 +191,8 @@ impl ComponentSparseSet {
204
191
// SAFE: if the sparse index points to something in the dense vec, it exists
205
192
unsafe {
206
193
Some ( (
207
- self . dense . get_unchecked ( dense_index) ,
208
- self . ticks . get_unchecked ( dense_index) ,
194
+ self . dense . get_data_unchecked ( dense_index) ,
195
+ self . dense . get_ticks_unchecked ( dense_index) ,
209
196
) )
210
197
}
211
198
}
@@ -216,7 +203,7 @@ impl ComponentSparseSet {
216
203
#[ cfg( debug_assertions) ]
217
204
assert_eq ! ( entity, self . entities[ dense_index] ) ;
218
205
// SAFE: if the sparse index points to something in the dense vec, it exists
219
- unsafe { Some ( self . ticks . get_unchecked ( dense_index) ) }
206
+ unsafe { Some ( self . dense . get_ticks_unchecked ( dense_index) ) }
220
207
}
221
208
222
209
/// Removes the `entity` from this sparse set and returns a pointer to the associated value (if
@@ -227,11 +214,10 @@ impl ComponentSparseSet {
227
214
let dense_index = dense_index as usize ;
228
215
#[ cfg( debug_assertions) ]
229
216
assert_eq ! ( entity, self . entities[ dense_index] ) ;
230
- self . ticks . swap_remove ( dense_index) ;
231
217
self . entities . swap_remove ( dense_index) ;
232
218
let is_last = dense_index == self . dense . len ( ) - 1 ;
233
219
// SAFE: dense_index was just removed from `sparse`, which ensures that it is valid
234
- let value = unsafe { self . dense . swap_remove_and_forget_unchecked ( dense_index) } ;
220
+ let ( value, _ ) = unsafe { self . dense . swap_remove_and_forget_unchecked ( dense_index) } ;
235
221
if !is_last {
236
222
let swapped_entity = self . entities [ dense_index] ;
237
223
#[ cfg( not( debug_assertions) ) ]
@@ -249,11 +235,10 @@ impl ComponentSparseSet {
249
235
let dense_index = dense_index as usize ;
250
236
#[ cfg( debug_assertions) ]
251
237
assert_eq ! ( entity, self . entities[ dense_index] ) ;
252
- self . ticks . swap_remove ( dense_index) ;
253
238
self . entities . swap_remove ( dense_index) ;
254
239
let is_last = dense_index == self . dense . len ( ) - 1 ;
255
240
// SAFE: if the sparse index points to something in the dense vec, it exists
256
- unsafe { self . dense . swap_remove_and_drop_unchecked ( dense_index) }
241
+ unsafe { self . dense . swap_remove_unchecked ( dense_index) }
257
242
if !is_last {
258
243
let swapped_entity = self . entities [ dense_index] ;
259
244
#[ cfg( not( debug_assertions) ) ]
@@ -269,9 +254,7 @@ impl ComponentSparseSet {
269
254
}
270
255
271
256
pub ( crate ) fn check_change_ticks ( & mut self , change_tick : u32 ) {
272
- for component_ticks in & mut self . ticks {
273
- component_ticks. get_mut ( ) . check_ticks ( change_tick) ;
274
- }
257
+ self . dense . check_change_ticks ( change_tick) ;
275
258
}
276
259
}
277
260
0 commit comments