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 <alice.i.cecile@gmail.com>
This commit is contained in:
Dmytro Banin 2024-05-31 09:42:03 -07:00 committed by GitHub
parent f237cf2441
commit 42d80375db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 0 deletions

View file

@ -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.

View file

@ -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<ComponentId> = 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.