1
1
use crate :: {
2
- archetype:: ArchetypeId ,
3
2
component:: { ComponentId , ComponentInfo , ComponentTicks , Components } ,
4
3
entity:: Entity ,
5
4
storage:: { BlobVec , SparseSet } ,
@@ -48,12 +47,24 @@ impl Column {
48
47
}
49
48
}
50
49
50
+ #[ inline]
51
+ fn ticks_mut ( & mut self ) -> & mut Vec < ComponentTicks > {
52
+ self . ticks . get_mut ( )
53
+ }
54
+
55
+ /// # Safety
56
+ /// Assumes data has already been allocated for the given row.
57
+ #[ inline]
58
+ pub unsafe fn set_unchecked ( & mut self , row : usize , data : * mut u8 , ticks : ComponentTicks ) {
59
+ self . set_data_unchecked ( row, data) ;
60
+ * self . ticks_mut ( ) . get_unchecked_mut ( row) = ticks;
61
+ }
62
+
51
63
/// # Safety
52
- /// Assumes data has already been allocated for the given row/column.
53
- /// Allows aliased mutable accesses to the data at the given `row`. Caller must ensure that this
54
- /// does not happen.
64
+ /// Assumes data has already been allocated for the given row.
55
65
#[ inline]
56
- pub unsafe fn set_unchecked ( & self , row : usize , data : * mut u8 ) {
66
+ pub unsafe fn set_data_unchecked ( & mut self , row : usize , data : * mut u8 ) {
67
+ debug_assert ! ( row < self . len( ) ) ;
57
68
self . data . set_unchecked ( row, data) ;
58
69
}
59
70
@@ -68,20 +79,19 @@ impl Column {
68
79
}
69
80
70
81
/// # Safety
71
- /// Assumes data has already been allocated for the given row/column.
72
- /// Allows aliased mutable accesses to the row's [ComponentTicks].
73
- /// Caller must ensure that this does not happen.
82
+ /// Assumes data has already been allocated for the given row.
74
83
#[ inline]
75
- #[ allow( clippy:: mut_from_ref) ]
76
- pub unsafe fn get_ticks_unchecked_mut ( & self , row : usize ) -> & mut ComponentTicks {
84
+ pub unsafe fn get_ticks_unchecked_mut ( & mut self , row : usize ) -> & mut ComponentTicks {
77
85
debug_assert ! ( row < self . len( ) ) ;
78
- ( * self . ticks . get ( ) ) . get_unchecked_mut ( row)
86
+ self . ticks_mut ( ) . get_unchecked_mut ( row)
79
87
}
80
88
89
+ /// # Safety
90
+ /// index must be in-bounds
81
91
#[ inline]
82
92
pub ( crate ) unsafe fn swap_remove_unchecked ( & mut self , row : usize ) {
83
93
self . data . swap_remove_and_drop_unchecked ( row) ;
84
- ( * self . ticks . get ( ) ) . swap_remove ( row) ;
94
+ self . ticks_mut ( ) . swap_remove ( row) ;
85
95
}
86
96
87
97
#[ inline]
@@ -90,26 +100,22 @@ impl Column {
90
100
row : usize ,
91
101
) -> ( * mut u8 , ComponentTicks ) {
92
102
let data = self . data . swap_remove_and_forget_unchecked ( row) ;
93
- let ticks = ( * self . ticks . get ( ) ) . swap_remove ( row) ;
103
+ let ticks = self . ticks_mut ( ) . swap_remove ( row) ;
94
104
( data, ticks)
95
105
}
96
106
97
- /// # Safety
98
- /// allocated value must be immediately set at the returned row
99
- pub ( crate ) unsafe fn push_uninit ( & mut self ) -> usize {
107
+ // # Safety
108
+ // - ptr must point to valid data of this column's component type
109
+ pub ( crate ) unsafe fn push ( & mut self , ptr : * mut u8 , ticks : ComponentTicks ) {
100
110
let row = self . data . push_uninit ( ) ;
101
- ( * self . ticks . get ( ) ) . push ( ComponentTicks :: new ( 0 ) ) ;
102
- row
111
+ self . data . set_unchecked ( row , ptr ) ;
112
+ self . ticks_mut ( ) . push ( ticks ) ;
103
113
}
104
114
105
115
#[ inline]
106
- pub ( crate ) fn reserve ( & mut self , additional : usize ) {
107
- self . data . reserve ( additional) ;
108
- // SAFE: unique access to self
109
- unsafe {
110
- let ticks = & mut ( * self . ticks . get ( ) ) ;
111
- ticks. reserve ( additional) ;
112
- }
116
+ pub ( crate ) fn reserve_exact ( & mut self , additional : usize ) {
117
+ self . data . reserve_exact ( additional) ;
118
+ self . ticks_mut ( ) . reserve_exact ( additional) ;
113
119
}
114
120
115
121
/// # Safety
@@ -144,8 +150,7 @@ impl Column {
144
150
145
151
#[ inline]
146
152
pub ( crate ) fn check_change_ticks ( & mut self , change_tick : u32 ) {
147
- let ticks = unsafe { ( * self . ticks . get ( ) ) . iter_mut ( ) } ;
148
- for component_ticks in ticks {
153
+ for component_ticks in self . ticks_mut ( ) {
149
154
component_ticks. check_ticks ( change_tick) ;
150
155
}
151
156
}
@@ -154,29 +159,20 @@ impl Column {
154
159
pub struct Table {
155
160
columns : SparseSet < ComponentId , Column > ,
156
161
entities : Vec < Entity > ,
157
- archetypes : Vec < ArchetypeId > ,
158
- grow_amount : usize ,
159
- capacity : usize ,
160
162
}
161
163
162
164
impl Table {
163
- pub const fn new ( grow_amount : usize ) -> Table {
165
+ pub const fn new ( ) -> Table {
164
166
Self {
165
167
columns : SparseSet :: new ( ) ,
166
168
entities : Vec :: new ( ) ,
167
- archetypes : Vec :: new ( ) ,
168
- grow_amount,
169
- capacity : 0 ,
170
169
}
171
170
}
172
171
173
- pub fn with_capacity ( capacity : usize , column_capacity : usize , grow_amount : usize ) -> Table {
172
+ pub fn with_capacity ( capacity : usize , column_capacity : usize ) -> Table {
174
173
Self {
175
174
columns : SparseSet :: with_capacity ( column_capacity) ,
176
175
entities : Vec :: with_capacity ( capacity) ,
177
- archetypes : Vec :: new ( ) ,
178
- grow_amount,
179
- capacity,
180
176
}
181
177
}
182
178
@@ -185,14 +181,10 @@ impl Table {
185
181
& self . entities
186
182
}
187
183
188
- pub fn add_archetype ( & mut self , archetype_id : ArchetypeId ) {
189
- self . archetypes . push ( archetype_id) ;
190
- }
191
-
192
184
pub fn add_column ( & mut self , component_info : & ComponentInfo ) {
193
185
self . columns . insert (
194
186
component_info. id ( ) ,
195
- Column :: with_capacity ( component_info, self . capacity ( ) ) ,
187
+ Column :: with_capacity ( component_info, self . entities . capacity ( ) ) ,
196
188
)
197
189
}
198
190
@@ -232,8 +224,7 @@ impl Table {
232
224
for column in self . columns . values_mut ( ) {
233
225
let ( data, ticks) = column. swap_remove_and_forget_unchecked ( row) ;
234
226
if let Some ( new_column) = new_table. get_column_mut ( column. component_id ) {
235
- new_column. set_unchecked ( new_row, data) ;
236
- * new_column. get_ticks_unchecked_mut ( new_row) = ticks;
227
+ new_column. set_unchecked ( new_row, data, ticks) ;
237
228
}
238
229
}
239
230
TableMoveResult {
@@ -263,8 +254,7 @@ impl Table {
263
254
for column in self . columns . values_mut ( ) {
264
255
if let Some ( new_column) = new_table. get_column_mut ( column. component_id ) {
265
256
let ( data, ticks) = column. swap_remove_and_forget_unchecked ( row) ;
266
- new_column. set_unchecked ( new_row, data) ;
267
- * new_column. get_ticks_unchecked_mut ( new_row) = ticks;
257
+ new_column. set_unchecked ( new_row, data, ticks) ;
268
258
} else {
269
259
column. swap_remove_unchecked ( row) ;
270
260
}
@@ -296,8 +286,7 @@ impl Table {
296
286
for column in self . columns . values_mut ( ) {
297
287
let new_column = new_table. get_column_mut ( column. component_id ) . unwrap ( ) ;
298
288
let ( data, ticks) = column. swap_remove_and_forget_unchecked ( row) ;
299
- new_column. set_unchecked ( new_row, data) ;
300
- * new_column. get_ticks_unchecked_mut ( new_row) = ticks;
289
+ new_column. set_unchecked ( new_row, data, ticks) ;
301
290
}
302
291
TableMoveResult {
303
292
new_row,
@@ -324,20 +313,16 @@ impl Table {
324
313
self . columns . contains ( component_id)
325
314
}
326
315
327
- pub fn reserve ( & mut self , amount : usize ) {
328
- let available_space = self . capacity - self . len ( ) ;
329
- if available_space < amount {
330
- let min_capacity = self . len ( ) + amount;
331
- // normally we would check if min_capacity is 0 for the below calculation, but amount >
332
- // available_space and available_space > 0, so min_capacity > 1
333
- let new_capacity =
334
- ( ( min_capacity + self . grow_amount - 1 ) / self . grow_amount ) * self . grow_amount ;
335
- let reserve_amount = new_capacity - self . len ( ) ;
316
+ pub fn reserve ( & mut self , additional : usize ) {
317
+ if self . entities . capacity ( ) - self . entities . len ( ) < additional {
318
+ self . entities . reserve ( additional) ;
319
+
320
+ // use entities vector capacity as driving capacity for all related allocations
321
+ let new_capacity = self . entities . capacity ( ) ;
322
+
336
323
for column in self . columns . values_mut ( ) {
337
- column. reserve ( reserve_amount ) ;
324
+ column. reserve_exact ( new_capacity - column . len ( ) ) ;
338
325
}
339
- self . entities . reserve ( reserve_amount) ;
340
- self . capacity = new_capacity;
341
326
}
342
327
}
343
328
@@ -358,7 +343,7 @@ impl Table {
358
343
359
344
#[ inline]
360
345
pub fn capacity ( & self ) -> usize {
361
- self . capacity
346
+ self . entities . capacity ( )
362
347
}
363
348
364
349
#[ inline]
@@ -389,7 +374,7 @@ pub struct Tables {
389
374
390
375
impl Default for Tables {
391
376
fn default ( ) -> Self {
392
- let empty_table = Table :: with_capacity ( 0 , 0 , 64 ) ;
377
+ let empty_table = Table :: with_capacity ( 0 , 0 ) ;
393
378
Tables {
394
379
tables : vec ! [ empty_table] ,
395
380
table_ids : HashMap :: default ( ) ,
@@ -446,7 +431,7 @@ impl Tables {
446
431
let hash = hasher. finish ( ) ;
447
432
let tables = & mut self . tables ;
448
433
* self . table_ids . entry ( hash) . or_insert_with ( move || {
449
- let mut table = Table :: with_capacity ( 0 , component_ids. len ( ) , 64 ) ;
434
+ let mut table = Table :: with_capacity ( 0 , component_ids. len ( ) ) ;
450
435
for component_id in component_ids. iter ( ) {
451
436
table. add_column ( components. get_info_unchecked ( * component_id) ) ;
452
437
}
@@ -496,18 +481,19 @@ mod tests {
496
481
let type_info = TypeInfo :: of :: < usize > ( ) ;
497
482
let component_id = components. get_or_insert_with ( type_info. type_id ( ) , || type_info) ;
498
483
let columns = & [ component_id] ;
499
- let mut table = Table :: with_capacity ( 0 , columns. len ( ) , 64 ) ;
484
+ let mut table = Table :: with_capacity ( 0 , columns. len ( ) ) ;
500
485
table. add_column ( components. get_info ( component_id) . unwrap ( ) ) ;
501
486
let entities = ( 0 ..200 ) . map ( Entity :: new) . collect :: < Vec < _ > > ( ) ;
502
- for ( row, entity) in entities. iter ( ) . cloned ( ) . enumerate ( ) {
487
+ for entity in entities. iter ( ) {
488
+ // SAFE: we allocate and immediately set data afterwards
503
489
unsafe {
504
- table. allocate ( entity) ;
490
+ let row = table. allocate ( * entity) ;
505
491
let mut value = row;
506
492
let value_ptr = ( ( & mut value) as * mut usize ) . cast :: < u8 > ( ) ;
507
493
table
508
- . get_column ( component_id)
494
+ . get_column_mut ( component_id)
509
495
. unwrap ( )
510
- . set_unchecked ( row, value_ptr) ;
496
+ . set_data_unchecked ( row, value_ptr) ;
511
497
} ;
512
498
}
513
499
0 commit comments