Skip to content

Commit e108585

Browse files
janis-bhmWaterWhisperer
authored andcommitted
set spawn_despawn on the correct entity when despawning (#21364)
# Objective Fixes #21293 Fixes #17314 to ensure that this is tested correctly. ## Solution when despawning an entity, previously the swapped in (archetype) or moved in entity (table) (which both require extra bookkeeping to update archetype or table rows) were marked as `spawned_or_despawned` by the location and tick that the to-be-removed entity was meant to be marked, while the to-be-removed entity wasn't marked. As pointed out by @akimakinai in [#19047](#19047), I've re-added the correct `mark_spawn_despawn` call to `despawn_with_caller`. ## Testing I've added a test `spawned_after_swap_remove` that ensures that despawning an entity by swapping doesn't effect other entities `spawned_or_despawned` location, and that it does effect the despawned entity's index's `spawned_or_despawned` location. Co-Authored By: [email protected] --------- Co-authored-by: WaterWhisperer <[email protected]>
1 parent f76a1bb commit e108585

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

crates/bevy_ecs/src/world/entity_ref.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,9 +2665,6 @@ impl<'w> EntityWorldMut<'w> {
26652665
table_row: swapped_location.table_row,
26662666
}),
26672667
);
2668-
world
2669-
.entities
2670-
.mark_spawn_despawn(swapped_entity.index(), caller, change_tick);
26712668
}
26722669
}
26732670
table_row = remove_result.table_row;
@@ -2697,14 +2694,18 @@ impl<'w> EntityWorldMut<'w> {
26972694
table_row,
26982695
}),
26992696
);
2700-
world
2701-
.entities
2702-
.mark_spawn_despawn(moved_entity.index(), caller, change_tick);
27032697
}
27042698
world.archetypes[moved_location.archetype_id]
27052699
.set_entity_table_row(moved_location.archetype_row, table_row);
27062700
}
27072701
world.flush();
2702+
2703+
// SAFETY: `self.entity` is a valid entity index
2704+
unsafe {
2705+
world
2706+
.entities
2707+
.mark_spawn_despawn(self.entity.index(), caller, change_tick);
2708+
}
27082709
}
27092710

27102711
/// Ensures any commands triggered by the actions of Self are applied, equivalent to [`World::flush`]
@@ -6585,4 +6586,28 @@ mod tests {
65856586
}
65866587
);
65876588
}
6589+
6590+
#[test]
6591+
fn spawned_after_swap_remove() {
6592+
#[derive(Component)]
6593+
struct Marker;
6594+
6595+
let mut world = World::new();
6596+
let id1 = world.spawn(Marker).id();
6597+
let _id2 = world.spawn(Marker).id();
6598+
let id3 = world.spawn(Marker).id();
6599+
6600+
#[cfg(feature = "track_location")]
6601+
let e1_spawned = world.entity(id1).spawned_by();
6602+
6603+
let spawn = world.entity(id3).spawned_by();
6604+
world.entity_mut(id1).despawn();
6605+
#[cfg(feature = "track_location")]
6606+
let e1_despawned = world.entities().entity_get_spawned_or_despawned_by(id1);
6607+
#[cfg(feature = "track_location")]
6608+
assert_ne!(e1_spawned.map(Some), e1_despawned);
6609+
6610+
let spawn_after = world.entity(id3).spawned_by();
6611+
assert_eq!(spawn, spawn_after);
6612+
}
65886613
}

tools/ci/src/commands/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl Prepare for TestCommand {
2020
PreparedCommand::new::<Self>(
2121
cmd!(
2222
sh,
23-
"cargo test --workspace --lib --bins --tests {no_fail_fast...} {jobs_ref...} -- {test_threads_ref...}"
23+
"cargo test --workspace --lib --bins --tests --features bevy_ecs/track_location {no_fail_fast...} {jobs_ref...} -- {test_threads_ref...}"
2424
),
2525
"Please fix failing tests in output above.",
2626
),

0 commit comments

Comments
 (0)