Create EntityCommands::remove_if (#18899)

# Objective

Fixes #18857.

## Solution

Add the requested method, and a `try_` variant as well.

## Testing

It compiles, doctests succeed, and is trivial enough that I don't think
it needs a unit test (correct me if I'm wrong though).
This commit is contained in:
Olle Lukowski 2025-04-26 14:32:02 -07:00 committed by GitHub
parent 2b7cecd5b3
commit 9167f02bdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1618,6 +1618,63 @@ impl<'a> EntityCommands<'a> {
self.queue_handled(entity_command::remove::<B>(), warn)
}
/// Removes a [`Bundle`] of components from the entity if the predicate returns true.
///
/// This is useful for chaining method calls.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource)]
/// # struct PlayerEntity { entity: Entity }
/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }
/// #[derive(Component)]
/// struct Health(u32);
/// #[derive(Component)]
/// struct Strength(u32);
/// #[derive(Component)]
/// struct Defense(u32);
///
/// #[derive(Bundle)]
/// struct CombatBundle {
/// health: Health,
/// strength: Strength,
/// }
///
/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands
/// .entity(player.entity)
/// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator());
/// }
/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);
/// ```
#[track_caller]
pub fn remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {
if condition() {
self.remove::<B>()
} else {
self
}
}
/// Removes a [`Bundle`] of components from the entity if the predicate returns true.
///
/// This is useful for chaining method calls.
///
/// # Note
///
/// If the entity does not exist when this command is executed,
/// the resulting error will be ignored.
#[track_caller]
pub fn try_remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {
if condition() {
self.try_remove::<B>()
} else {
self
}
}
/// Removes a [`Bundle`] of components from the entity.
///
/// This will remove all components that intersect with the provided bundle;