Skip to content

Commit

Permalink
Comments for remove_with_required in EntityCommands
Browse files Browse the repository at this point in the history
  • Loading branch information
rewin123 committed Sep 4, 2024
1 parent 48065c8 commit 665f0a1
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
5 changes: 2 additions & 3 deletions crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 57 additions & 2 deletions crates/bevy_ecs/src/system/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1216,7 +1216,58 @@ impl EntityCommands<'_> {
self.add(remove::<T>)
}

/// 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<Entity, With<X>>) {
/// for entity in &query {
/// // Remove X and its unused requirements
/// commands.entity(entity).remove_with_required::<X>();
/// }
/// }
///
/// // 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<T: Bundle>(self) -> Self {
self.add(remove_with_required::<T>)
}
Expand Down Expand Up @@ -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<T: Bundle>(entity: Entity, world: &mut World) {
if let Some(mut entity) = world.get_entity_mut(entity) {
entity.remove_with_required::<T>();
Expand Down
22 changes: 12 additions & 10 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,17 +1182,17 @@ 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
///
/// 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;
Expand All @@ -1215,7 +1215,7 @@ impl<'w> EntityWorldMut<'w> {
///
/// // Initial component tree:
/// // X
/// // \
/// // \
/// // Y W
/// // \ /
/// // Z
Expand Down Expand Up @@ -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];
Expand All @@ -1271,11 +1277,7 @@ impl<'w> EntityWorldMut<'w> {
.copied()
.collect::<Vec<_>>();


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) };

Expand Down

0 comments on commit 665f0a1

Please sign in to comment.