From 42d80375dba1c37374d08e94247aba2fbfb66626 Mon Sep 17 00:00:00 2001 From: Dmytro Banin Date: Fri, 31 May 2024 09:42:03 -0700 Subject: [PATCH] Add ability to clear all components on an entity via EntityWorldMut (#13588) # Objective Adds capability to clear all components on an entity without de-spawning said entity. ## Testing The function calls `remove_by_id` on every component in the entity archetype - wasn't sure if it's worth going out of our way to create a test for this considering `remove_by_id` is already unit tested. --- ## Changelog Added `clear` function to `EntityWorldMut` which removes all components on an entity. ## Migration Guide N/A --------- Co-authored-by: Alice Cecile --- crates/bevy_ecs/src/system/commands/mod.rs | 14 ++++++++++++++ crates/bevy_ecs/src/world/entity_ref.rs | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 9bef1e090d..679f895604 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -1011,6 +1011,11 @@ impl EntityCommands<'_> { self.add(remove_by_id(component_id)) } + /// Removes all components associated with the entity. + pub fn clear(&mut self) -> &mut Self { + self.add(clear()) + } + /// Despawns the entity. /// /// See [`World::despawn`] for more details. @@ -1237,6 +1242,15 @@ fn remove_by_id(component_id: ComponentId) -> impl EntityCommand { } } +/// An [`EntityCommand`] that removes all components associated with a provided entity. +fn clear() -> impl EntityCommand { + move |entity: Entity, world: &mut World| { + if let Some(mut entity) = world.get_entity_mut(entity) { + entity.clear(); + } + } +} + /// An [`EntityCommand`] that removes components from an entity. /// For a [`Bundle`] type `T`, this will remove all components except those in the bundle. /// Any components in the bundle that aren't found on the entity will be ignored. diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 45d90de363..e7396bf3c7 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -1178,6 +1178,22 @@ impl<'w> EntityWorldMut<'w> { self } + /// Removes all components associated with the entity. + pub fn clear(&mut self) -> &mut Self { + let component_ids: Vec = self.archetype().components().collect(); + let components = &mut self.world.components; + + let bundle_id = self + .world + .bundles + .init_dynamic_info(components, component_ids.as_slice()); + + // SAFETY: the `BundleInfo` for this `component_id` is initialized above + self.location = unsafe { self.remove_bundle(bundle_id) }; + + self + } + /// Despawns the current entity. /// /// See [`World::despawn`] for more details.