From e0556e4863661c3289247d27a4a5060b72ea8723 Mon Sep 17 00:00:00 2001 From: devil-ira Date: Sun, 23 Apr 2023 21:24:45 +0200 Subject: [PATCH 1/2] Fix --- crates/bevy_hierarchy/src/hierarchy.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index db1a67b5e88b1..c53f6e9c588bb 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -46,9 +46,9 @@ fn despawn_with_children_recursive_inner(world: &mut World, entity: Entity) { } } -fn despawn_children(world: &mut World, entity: Entity) { - if let Some(mut children) = world.get_mut::(entity) { - for e in std::mem::take(&mut children.0) { +fn despawn_children_recursive(world: &mut World, entity: Entity) { + if let Some(children) = world.entity_mut(entity).take::() { + for e in children.0 { despawn_with_children_recursive_inner(world, e); } } @@ -76,7 +76,7 @@ impl Command for DespawnChildrenRecursive { entity = bevy_utils::tracing::field::debug(self.entity) ) .entered(); - despawn_children(world, self.entity); + despawn_children_recursive(world, self.entity); } } @@ -127,11 +127,9 @@ impl<'w> DespawnRecursiveExt for EntityMut<'w> { ) .entered(); - // SAFETY: The location is updated. - unsafe { - despawn_children(self.world_mut(), entity); - self.update_location(); - } + self.world_scope(|world| { + despawn_children_recursive(world, entity); + }); } } From 9724821c6f271fcc5d676f0f939592ec0bdc63ba Mon Sep 17 00:00:00 2001 From: devil-ira Date: Mon, 24 Apr 2023 12:35:21 +0200 Subject: [PATCH 2/2] Add test --- crates/bevy_hierarchy/src/hierarchy.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index c53f6e9c588bb..e8865373a1282 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -224,4 +224,26 @@ mod tests { ] ); } + + #[test] + fn despawn_descendants() { + let mut world = World::default(); + let mut queue = CommandQueue::default(); + let mut commands = Commands::new(&mut queue, &world); + + let parent = commands.spawn_empty().id(); + let child = commands.spawn_empty().id(); + + commands + .entity(parent) + .add_child(child) + .despawn_descendants(); + + queue.apply(&mut world); + + // The parent's Children component should be removed. + assert!(world.entity(parent).get::().is_none()); + // The child should be despawned. + assert!(world.get_entity(child).is_none()); + } }