diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 45f24ba2e09a5..20a81199471e7 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -2025,12 +2025,11 @@ mod tests { #[test] fn remove_component_and_his_required_components() { - // We create this 'require' tree (down is required by up component) // X // \ - // Y - // \ + // Y + // \ // Z V // \ / // W diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 3d581ccb014de..0bdbdc386e483 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -1216,7 +1216,58 @@ impl EntityCommands<'_> { self.add(remove::) } - /// Remove a all components in the bundle and remove all required components for each component in the bundle + /// Removes all components in the bundle and remove all required components for each component in the bundle + /// that are not required by other components of this entity. + /// + /// This function can be noticeably slower than simple remove or retain functions because it dynamically determines which components + /// are still required by entity components outside of the [`Bundle`]. + /// + /// # Example + /// + /// ```rust + /// use bevy_ecs::prelude::*; + /// + /// #[derive(Component)] + /// #[require(Y)] + /// struct X; + /// + /// #[derive(Component, Default)] + /// #[require(Z)] + /// struct Y; + /// + /// #[derive(Component, Default)] + /// struct Z; + /// + /// #[derive(Component)] + /// #[require(Z)] + /// struct W; + /// + /// fn remove_x_system(mut commands: Commands, query: Query>) { + /// for entity in &query { + /// // Remove X and its unused requirements + /// commands.entity(entity).remove_with_required::(); + /// } + /// } + /// + /// // Usage in a system: + /// fn setup(mut commands: Commands) { + /// // Spawn an entity with X, Y, Z, and W components + /// commands.spawn((X, W)); + /// + /// // Initial component tree: + /// // X + /// // \ + /// // Y W + /// // \ / + /// // Z + /// } + /// + /// // After calling remove_x_system: + /// // Resulting component tree: + /// // W + /// // / + /// // Z + /// ``` pub fn remove_with_required(self) -> Self { self.add(remove_with_required::) } @@ -1530,7 +1581,11 @@ fn remove_by_id(component_id: ComponentId) -> impl EntityCommand { } } -/// An [`EntityCommand`] that removes components in a [`Bundle`] from an entity and remove all required components for each component in the [`Bundle`] +/// An [`EntityCommand`] tjhat remove all components in the bundle and remove all required components for each component in the bundle +/// that are not required by other components of this entity. +/// +/// This function can be noticeably slower than simple remove or retain functions because it dynamically determines which components +/// are still required by entity components outside of the [`Bundle`]. fn remove_with_required(entity: Entity, world: &mut World) { if let Some(mut entity) = world.get_entity_mut(entity) { entity.remove_with_required::(); diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index 96d2c90c3f309..e7520507395e3 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -1182,7 +1182,7 @@ impl<'w> EntityWorldMut<'w> { /// Removes all components of this [`Bundle`] and its required components that are not required by other components of this entity. /// - /// This function can be noticeably slower than simple remove or retain functions because it dynamically determines which components + /// This function can be noticeably slower than simple remove or retain functions because it dynamically determines which components /// are still required by entity components outside of the [`Bundle`]. /// /// # Example @@ -1190,9 +1190,9 @@ impl<'w> EntityWorldMut<'w> { /// This example demonstrates safely removing component `X` and all its requirements that are not required outside `X`'s requirement tree: /// /// ```rust - /// + /// /// use bevy_ecs::prelude::*; - /// + /// /// #[derive(Component)] /// #[require(Y)] /// struct X; @@ -1215,7 +1215,7 @@ impl<'w> EntityWorldMut<'w> { /// /// // Initial component tree: /// // X - /// // \ + /// // \ /// // Y W /// // \ / /// // Z @@ -1245,7 +1245,13 @@ impl<'w> EntityWorldMut<'w> { // SAFETY: the `BundleInfo` is initialized above // We make clone of components array to not lock immutable access to world - let contributed_components = unsafe { self.world.bundles.get_unchecked(bundle).contributed_components().to_vec() }; + let contributed_components = unsafe { + self.world + .bundles + .get_unchecked(bundle) + .contributed_components() + .to_vec() + }; let old_location = self.location; let old_archetype = &mut self.world.archetypes[old_location.archetype_id]; @@ -1271,11 +1277,7 @@ impl<'w> EntityWorldMut<'w> { .copied() .collect::>(); - - let to_delete_bundle = self - .world - .bundles - .init_dynamic_info(components, &to_delete); + let to_delete_bundle = self.world.bundles.init_dynamic_info(components, &to_delete); // SAFETY: the dynamic `BundleInfo` is initialized above self.location = unsafe { self.remove_bundle(to_delete_bundle) };