@@ -189,84 +189,84 @@ impl<'w> EntityMut<'w> {
189
189
} )
190
190
}
191
191
192
- // TODO: move relevant methods to World (add/remove bundle)
193
- pub fn insert_bundle < T : Bundle > ( & mut self , bundle : T ) -> & mut Self {
194
- // Use a non-generic function to cut down on monomorphization
195
- unsafe fn get_insert_bundle_info < ' a > (
196
- entities : & mut Entities ,
197
- archetypes : & ' a mut Archetypes ,
198
- components : & mut Components ,
199
- storages : & mut Storages ,
200
- bundle_info : & BundleInfo ,
201
- current_location : EntityLocation ,
202
- entity : Entity ,
203
- ) -> ( & ' a Archetype , & ' a Vec < ComponentStatus > , EntityLocation ) {
204
- // SAFE: component ids in `bundle_info` and self.location are valid
205
- let new_archetype_id = add_bundle_to_archetype (
206
- archetypes,
207
- storages,
208
- components,
209
- current_location. archetype_id ,
210
- bundle_info,
211
- ) ;
212
- if new_archetype_id == current_location. archetype_id {
213
- let archetype = & archetypes[ current_location. archetype_id ] ;
214
- let edge = archetype. edges ( ) . get_add_bundle ( bundle_info. id ) . unwrap ( ) ;
215
- ( archetype, & edge. bundle_status , current_location)
192
+ /// # Safety:
193
+ /// Partially moves the entity to a new archetype based on the provided bundle info
194
+ /// You must handle the other part of moving the entity yourself
195
+ unsafe fn get_insert_bundle_info < ' a > (
196
+ entities : & mut Entities ,
197
+ archetypes : & ' a mut Archetypes ,
198
+ components : & mut Components ,
199
+ storages : & mut Storages ,
200
+ bundle_info : & BundleInfo ,
201
+ current_location : EntityLocation ,
202
+ entity : Entity ,
203
+ ) -> ( & ' a Archetype , & ' a Vec < ComponentStatus > , EntityLocation ) {
204
+ // SAFE: component ids in `bundle_info` and self.location are valid
205
+ let new_archetype_id = add_bundle_to_archetype (
206
+ archetypes,
207
+ storages,
208
+ components,
209
+ current_location. archetype_id ,
210
+ bundle_info,
211
+ ) ;
212
+ if new_archetype_id == current_location. archetype_id {
213
+ let archetype = & archetypes[ current_location. archetype_id ] ;
214
+ let edge = archetype. edges ( ) . get_add_bundle ( bundle_info. id ) . unwrap ( ) ;
215
+ ( archetype, & edge. bundle_status , current_location)
216
+ } else {
217
+ let ( old_table_row, old_table_id) = {
218
+ let old_archetype = & mut archetypes[ current_location. archetype_id ] ;
219
+ let result = old_archetype. swap_remove ( current_location. index ) ;
220
+ if let Some ( swapped_entity) = result. swapped_entity {
221
+ entities. meta [ swapped_entity. id as usize ] . location = current_location;
222
+ }
223
+ ( result. table_row , old_archetype. table_id ( ) )
224
+ } ;
225
+
226
+ let new_table_id = archetypes[ new_archetype_id] . table_id ( ) ;
227
+
228
+ let new_location = if old_table_id == new_table_id {
229
+ archetypes[ new_archetype_id] . allocate ( entity, old_table_row)
216
230
} else {
217
- let ( old_table_row, old_table_id) = {
218
- let old_archetype = & mut archetypes[ current_location. archetype_id ] ;
219
- let result = old_archetype. swap_remove ( current_location. index ) ;
220
- if let Some ( swapped_entity) = result. swapped_entity {
221
- entities. meta [ swapped_entity. id as usize ] . location = current_location;
222
- }
223
- ( result. table_row , old_archetype. table_id ( ) )
224
- } ;
225
-
226
- let new_table_id = archetypes[ new_archetype_id] . table_id ( ) ;
227
-
228
- let new_location = if old_table_id == new_table_id {
229
- archetypes[ new_archetype_id] . allocate ( entity, old_table_row)
230
- } else {
231
- let ( old_table, new_table) =
232
- storages. tables . get_2_mut ( old_table_id, new_table_id) ;
233
- // PERF: store "non bundle" components in edge, then just move those to avoid
234
- // redundant copies
235
- let move_result =
236
- old_table. move_to_superset_unchecked ( old_table_row, new_table) ;
237
-
238
- let new_location =
239
- archetypes[ new_archetype_id] . allocate ( entity, move_result. new_row ) ;
240
- // if an entity was moved into this entity's table spot, update its table row
241
- if let Some ( swapped_entity) = move_result. swapped_entity {
242
- let swapped_location = entities. get ( swapped_entity) . unwrap ( ) ;
243
- archetypes[ swapped_location. archetype_id ]
244
- . set_entity_table_row ( swapped_location. index , old_table_row) ;
245
- }
246
- new_location
247
- } ;
248
-
249
- entities. meta [ entity. id as usize ] . location = new_location;
250
- let ( old_archetype, new_archetype) =
251
- archetypes. get_2_mut ( current_location. archetype_id , new_archetype_id) ;
252
- let edge = old_archetype
253
- . edges ( )
254
- . get_add_bundle ( bundle_info. id )
255
- . unwrap ( ) ;
256
- ( & * new_archetype, & edge. bundle_status , new_location)
257
-
258
- // Sparse set components are intentionally ignored here. They don't need to move
259
- }
231
+ let ( old_table, new_table) = storages. tables . get_2_mut ( old_table_id, new_table_id) ;
232
+ // PERF: store "non bundle" components in edge, then just move those to avoid
233
+ // redundant copies
234
+ let move_result = old_table. move_to_superset_unchecked ( old_table_row, new_table) ;
235
+
236
+ let new_location =
237
+ archetypes[ new_archetype_id] . allocate ( entity, move_result. new_row ) ;
238
+ // if an entity was moved into this entity's table spot, update its table row
239
+ if let Some ( swapped_entity) = move_result. swapped_entity {
240
+ let swapped_location = entities. get ( swapped_entity) . unwrap ( ) ;
241
+ archetypes[ swapped_location. archetype_id ]
242
+ . set_entity_table_row ( swapped_location. index , old_table_row) ;
243
+ }
244
+ new_location
245
+ } ;
246
+
247
+ entities. meta [ entity. id as usize ] . location = new_location;
248
+ let ( old_archetype, new_archetype) =
249
+ archetypes. get_2_mut ( current_location. archetype_id , new_archetype_id) ;
250
+ let edge = old_archetype
251
+ . edges ( )
252
+ . get_add_bundle ( bundle_info. id )
253
+ . unwrap ( ) ;
254
+ ( & * new_archetype, & edge. bundle_status , new_location)
255
+
256
+ // Sparse set components are intentionally ignored here. They don't need to move
260
257
}
258
+ }
261
259
260
+ // TODO: move relevant methods to World (add/remove bundle)
261
+ pub fn insert_bundle < T : Bundle > ( & mut self , bundle : T ) -> & mut Self {
262
262
let change_tick = self . world . change_tick ( ) ;
263
263
let bundle_info = self
264
264
. world
265
265
. bundles
266
266
. init_info :: < T > ( & mut self . world . components ) ;
267
267
268
268
let ( archetype, bundle_status, new_location) = unsafe {
269
- get_insert_bundle_info (
269
+ Self :: get_insert_bundle_info (
270
270
& mut self . world . entities ,
271
271
& mut self . world . archetypes ,
272
272
& mut self . world . components ,
0 commit comments