@@ -340,6 +340,42 @@ impl<'w> EntityMut<'w> {
340
340
} )
341
341
} ;
342
342
343
+ unsafe {
344
+ Self :: move_entity_from_remove :: < false > (
345
+ entity,
346
+ & mut self . location ,
347
+ old_location. archetype_id ,
348
+ old_location,
349
+ entities,
350
+ archetypes,
351
+ storages,
352
+ new_archetype_id,
353
+ ) ;
354
+ }
355
+
356
+ Some ( result)
357
+ }
358
+
359
+ /// Safety: `new_archetype_id` must have the same or a subset of the components
360
+ /// in `old_archetype_id`. Probably more safety stuff too, audit a call to
361
+ /// this fn as if the code here was written inline
362
+ ///
363
+ /// when DROP is true removed components will be dropped otherwise they will be forgotten
364
+ ///
365
+ // We use a const generic here so that we are less reliant on
366
+ // inlining for rustc to optimize out the `match DROP`
367
+ #[ allow( clippy:: too_many_arguments) ]
368
+ unsafe fn move_entity_from_remove < const DROP : bool > (
369
+ entity : Entity ,
370
+ self_location : & mut EntityLocation ,
371
+ old_archetype_id : ArchetypeId ,
372
+ old_location : EntityLocation ,
373
+ entities : & mut Entities ,
374
+ archetypes : & mut Archetypes ,
375
+ storages : & mut Storages ,
376
+ new_archetype_id : ArchetypeId ,
377
+ ) {
378
+ let old_archetype = & mut archetypes[ old_archetype_id] ;
343
379
let remove_result = old_archetype. swap_remove ( old_location. index ) ;
344
380
if let Some ( swapped_entity) = remove_result. swapped_entity {
345
381
entities. meta [ swapped_entity. id as usize ] . location = old_location;
@@ -349,34 +385,34 @@ impl<'w> EntityMut<'w> {
349
385
let new_archetype = & mut archetypes[ new_archetype_id] ;
350
386
351
387
let new_location = if old_table_id == new_archetype. table_id ( ) {
352
- unsafe { new_archetype. allocate ( entity, old_table_row) }
388
+ new_archetype. allocate ( entity, old_table_row)
353
389
} else {
354
390
let ( old_table, new_table) = storages
355
391
. tables
356
392
. get_2_mut ( old_table_id, new_archetype. table_id ( ) ) ;
357
393
358
- // SAFE: table_row exists. All "missing" components have been extracted into the bundle
359
- // above and the caller takes ownership
360
- let move_result =
361
- unsafe { old_table. move_to_and_forget_missing_unchecked ( old_table_row, new_table) } ;
394
+ // SAFE: old_table_row exists
395
+ let move_result = if DROP {
396
+ old_table. move_to_and_drop_missing_unchecked ( old_table_row, new_table)
397
+ } else {
398
+ old_table. move_to_and_forget_missing_unchecked ( old_table_row, new_table)
399
+ } ;
362
400
363
- // SAFE: new_table_row is a valid position in new_archetype's table
364
- let new_location = unsafe { new_archetype. allocate ( entity, move_result. new_row ) } ;
401
+ // SAFE: move_result.new_row is a valid position in new_archetype's table
402
+ let new_location = new_archetype. allocate ( entity, move_result. new_row ) ;
365
403
366
404
// if an entity was moved into this entity's table spot, update its table row
367
405
if let Some ( swapped_entity) = move_result. swapped_entity {
368
406
let swapped_location = entities. get ( swapped_entity) . unwrap ( ) ;
369
- let archetype = & mut archetypes[ swapped_location. archetype_id ] ;
370
- archetype . set_entity_table_row ( swapped_location. index , old_table_row) ;
407
+ archetypes[ swapped_location. archetype_id ]
408
+ . set_entity_table_row ( swapped_location. index , old_table_row) ;
371
409
}
372
410
373
411
new_location
374
412
} ;
375
413
376
- self . location = new_location;
377
- entities. meta [ self . entity . id as usize ] . location = new_location;
378
-
379
- Some ( result)
414
+ * self_location = new_location;
415
+ entities. meta [ entity. id as usize ] . location = new_location;
380
416
}
381
417
382
418
/// Remove any components in the bundle that the entity has.
@@ -425,40 +461,18 @@ impl<'w> EntityMut<'w> {
425
461
}
426
462
}
427
463
428
- let remove_result = old_archetype. swap_remove ( old_location. index ) ;
429
- if let Some ( swapped_entity) = remove_result. swapped_entity {
430
- entities. meta [ swapped_entity. id as usize ] . location = old_location;
464
+ unsafe {
465
+ Self :: move_entity_from_remove :: < true > (
466
+ entity,
467
+ & mut self . location ,
468
+ old_location. archetype_id ,
469
+ old_location,
470
+ entities,
471
+ archetypes,
472
+ storages,
473
+ new_archetype_id,
474
+ )
431
475
}
432
- let old_table_row = remove_result. table_row ;
433
- let old_table_id = old_archetype. table_id ( ) ;
434
- let new_archetype = & mut archetypes[ new_archetype_id] ;
435
-
436
- let new_location = if old_table_id == new_archetype. table_id ( ) {
437
- unsafe { new_archetype. allocate ( entity, old_table_row) }
438
- } else {
439
- let ( old_table, new_table) = storages
440
- . tables
441
- . get_2_mut ( old_table_id, new_archetype. table_id ( ) ) ;
442
-
443
- // SAFE: table_row exists
444
- let move_result =
445
- unsafe { old_table. move_to_and_drop_missing_unchecked ( old_table_row, new_table) } ;
446
-
447
- // SAFE: new_table_row is a valid position in new_archetype's table
448
- let new_location = unsafe { new_archetype. allocate ( entity, move_result. new_row ) } ;
449
-
450
- // if an entity was moved into this entity's table spot, update its table row
451
- if let Some ( swapped_entity) = move_result. swapped_entity {
452
- let swapped_location = entities. get ( swapped_entity) . unwrap ( ) ;
453
- archetypes[ swapped_location. archetype_id ]
454
- . set_entity_table_row ( swapped_location. index , old_table_row) ;
455
- }
456
-
457
- new_location
458
- } ;
459
-
460
- self . location = new_location;
461
- entities. meta [ self . entity . id as usize ] . location = new_location;
462
476
}
463
477
464
478
pub fn insert < T : Component > ( & mut self , value : T ) -> & mut Self {
0 commit comments