11use crate :: {
2- archetype:: ArchetypeId ,
32 component:: { ComponentId , ComponentInfo , ComponentTicks , Components } ,
43 entity:: Entity ,
54 storage:: { BlobVec , SparseSet } ,
@@ -48,12 +47,24 @@ impl Column {
4847 }
4948 }
5049
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+
5163 /// # 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.
5565 #[ 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( ) ) ;
5768 self . data . set_unchecked ( row, data) ;
5869 }
5970
@@ -68,20 +79,19 @@ impl Column {
6879 }
6980
7081 /// # 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.
7483 #[ 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 {
7785 debug_assert ! ( row < self . len( ) ) ;
78- ( * self . ticks . get ( ) ) . get_unchecked_mut ( row)
86+ self . ticks_mut ( ) . get_unchecked_mut ( row)
7987 }
8088
89+ /// # Safety
90+ /// index must be in-bounds
8191 #[ inline]
8292 pub ( crate ) unsafe fn swap_remove_unchecked ( & mut self , row : usize ) {
8393 self . data . swap_remove_and_drop_unchecked ( row) ;
84- ( * self . ticks . get ( ) ) . swap_remove ( row) ;
94+ self . ticks_mut ( ) . swap_remove ( row) ;
8595 }
8696
8797 #[ inline]
@@ -90,26 +100,22 @@ impl Column {
90100 row : usize ,
91101 ) -> ( * mut u8 , ComponentTicks ) {
92102 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) ;
94104 ( data, ticks)
95105 }
96106
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 ) {
100110 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 ) ;
103113 }
104114
105115 #[ 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) ;
113119 }
114120
115121 /// # Safety
@@ -144,8 +150,7 @@ impl Column {
144150
145151 #[ inline]
146152 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 ( ) {
149154 component_ticks. check_ticks ( change_tick) ;
150155 }
151156 }
@@ -154,29 +159,20 @@ impl Column {
154159pub struct Table {
155160 columns : SparseSet < ComponentId , Column > ,
156161 entities : Vec < Entity > ,
157- archetypes : Vec < ArchetypeId > ,
158- grow_amount : usize ,
159- capacity : usize ,
160162}
161163
162164impl Table {
163- pub const fn new ( grow_amount : usize ) -> Table {
165+ pub const fn new ( ) -> Table {
164166 Self {
165167 columns : SparseSet :: new ( ) ,
166168 entities : Vec :: new ( ) ,
167- archetypes : Vec :: new ( ) ,
168- grow_amount,
169- capacity : 0 ,
170169 }
171170 }
172171
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 {
174173 Self {
175174 columns : SparseSet :: with_capacity ( column_capacity) ,
176175 entities : Vec :: with_capacity ( capacity) ,
177- archetypes : Vec :: new ( ) ,
178- grow_amount,
179- capacity,
180176 }
181177 }
182178
@@ -185,14 +181,10 @@ impl Table {
185181 & self . entities
186182 }
187183
188- pub fn add_archetype ( & mut self , archetype_id : ArchetypeId ) {
189- self . archetypes . push ( archetype_id) ;
190- }
191-
192184 pub fn add_column ( & mut self , component_info : & ComponentInfo ) {
193185 self . columns . insert (
194186 component_info. id ( ) ,
195- Column :: with_capacity ( component_info, self . capacity ( ) ) ,
187+ Column :: with_capacity ( component_info, self . entities . capacity ( ) ) ,
196188 )
197189 }
198190
@@ -232,8 +224,7 @@ impl Table {
232224 for column in self . columns . values_mut ( ) {
233225 let ( data, ticks) = column. swap_remove_and_forget_unchecked ( row) ;
234226 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) ;
237228 }
238229 }
239230 TableMoveResult {
@@ -263,8 +254,7 @@ impl Table {
263254 for column in self . columns . values_mut ( ) {
264255 if let Some ( new_column) = new_table. get_column_mut ( column. component_id ) {
265256 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) ;
268258 } else {
269259 column. swap_remove_unchecked ( row) ;
270260 }
@@ -296,8 +286,7 @@ impl Table {
296286 for column in self . columns . values_mut ( ) {
297287 let new_column = new_table. get_column_mut ( column. component_id ) . unwrap ( ) ;
298288 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) ;
301290 }
302291 TableMoveResult {
303292 new_row,
@@ -324,20 +313,16 @@ impl Table {
324313 self . columns . contains ( component_id)
325314 }
326315
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+
336323 for column in self . columns . values_mut ( ) {
337- column. reserve ( reserve_amount ) ;
324+ column. reserve_exact ( new_capacity - column . len ( ) ) ;
338325 }
339- self . entities . reserve ( reserve_amount) ;
340- self . capacity = new_capacity;
341326 }
342327 }
343328
@@ -358,7 +343,7 @@ impl Table {
358343
359344 #[ inline]
360345 pub fn capacity ( & self ) -> usize {
361- self . capacity
346+ self . entities . capacity ( )
362347 }
363348
364349 #[ inline]
@@ -389,7 +374,7 @@ pub struct Tables {
389374
390375impl Default for Tables {
391376 fn default ( ) -> Self {
392- let empty_table = Table :: with_capacity ( 0 , 0 , 64 ) ;
377+ let empty_table = Table :: with_capacity ( 0 , 0 ) ;
393378 Tables {
394379 tables : vec ! [ empty_table] ,
395380 table_ids : HashMap :: default ( ) ,
@@ -446,7 +431,7 @@ impl Tables {
446431 let hash = hasher. finish ( ) ;
447432 let tables = & mut self . tables ;
448433 * 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 ( ) ) ;
450435 for component_id in component_ids. iter ( ) {
451436 table. add_column ( components. get_info_unchecked ( * component_id) ) ;
452437 }
@@ -496,18 +481,19 @@ mod tests {
496481 let type_info = TypeInfo :: of :: < usize > ( ) ;
497482 let component_id = components. get_or_insert_with ( type_info. type_id ( ) , || type_info) ;
498483 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 ( ) ) ;
500485 table. add_column ( components. get_info ( component_id) . unwrap ( ) ) ;
501486 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
503489 unsafe {
504- table. allocate ( entity) ;
490+ let row = table. allocate ( * entity) ;
505491 let mut value = row;
506492 let value_ptr = ( ( & mut value) as * mut usize ) . cast :: < u8 > ( ) ;
507493 table
508- . get_column ( component_id)
494+ . get_column_mut ( component_id)
509495 . unwrap ( )
510- . set_unchecked ( row, value_ptr) ;
496+ . set_data_unchecked ( row, value_ptr) ;
511497 } ;
512498 }
513499
0 commit comments