From db4c468fe2bd52dcf86d73ac9430c3ff7f2913a8 Mon Sep 17 00:00:00 2001 From: JaySpruce Date: Mon, 9 Dec 2024 21:26:15 -0600 Subject: [PATCH] Rename `EntityCommands::clone` to `clone_and_spawn` (#16696) ## Objective Follow-up to #16672. `EntityCommands::clone` looks the same as the `Clone` trait, which could be confusing. A discord discussion has made me realize that's probably a bigger problem than I thought. Oops :P ## Solution Renamed `EntityCommands::clone` to `EntityCommands::clone_and_spawn`, renamed `EntityCommands::clone_with` to `EntityCommands::clone_and_spawn_with`. Also added some docs explaining the commands' relation to `Clone` (components need to implement it (or `Reflect`)). ## Showcase ``` // Create a new entity and keep its EntityCommands let mut entity = commands.spawn((ComponentA(10), ComponentB(20))); // Create a clone of the first entity let mut entity_clone = entity.clone_and_spawn(); ``` ## The Bikeshed - `clone_and_spawn` (Alice's suggestion) - `spawn_clone` (benfrankel's suggestion) - `spawn_cloned` (rparrett's suggestion) --- crates/bevy_ecs/src/system/commands/mod.rs | 31 +++++++++++++++------- crates/bevy_hierarchy/src/hierarchy.rs | 4 +-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 0879b8520f94f..a2cbbea764c37 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -1720,6 +1720,12 @@ impl<'a> EntityCommands<'a> { /// Clones an entity and returns the [`EntityCommands`] of the clone. /// + /// The clone will receive all the components of the original that implement + /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect). + /// + /// To configure cloning behavior (such as only cloning certain components), + /// use [`EntityCommands::clone_and_spawn_with`]. + /// /// # Panics /// /// The command will panic when applied if the original entity does not exist. @@ -1735,20 +1741,27 @@ impl<'a> EntityCommands<'a> { /// struct ComponentB(u32); /// /// fn example_system(mut commands: Commands) { - /// // Create a new entity and keep its EntityCommands. + /// // Create a new entity and keep its EntityCommands /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20))); /// /// // Create a clone of the first entity - /// let entity_clone = entity.clone(); + /// let mut entity_clone = entity.clone_and_spawn(); /// } /// # bevy_ecs::system::assert_is_system(example_system); - pub fn clone(&mut self) -> EntityCommands<'_> { - self.clone_with(|_| {}) + pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> { + self.clone_and_spawn_with(|_| {}) } /// Clones an entity and allows configuring cloning behavior using [`EntityCloneBuilder`], /// returning the [`EntityCommands`] of the clone. /// + /// By default, the clone will receive all the components of the original that implement + /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect). + /// + /// To exclude specific components, use [`EntityCloneBuilder::deny`]. + /// To only include specific components, use [`EntityCloneBuilder::deny_all`] + /// followed by [`EntityCloneBuilder::allow`]. + /// /// # Panics /// /// The command will panic when applied if the original entity does not exist. @@ -1764,21 +1777,21 @@ impl<'a> EntityCommands<'a> { /// struct ComponentB(u32); /// /// fn example_system(mut commands: Commands) { - /// // Create a new entity and keep its EntityCommands. + /// // Create a new entity and keep its EntityCommands /// let mut entity = commands.spawn((ComponentA(10), ComponentB(20))); /// /// // Create a clone of the first entity, but without ComponentB - /// let entity_clone = entity.clone_with(|builder| { + /// let mut entity_clone = entity.clone_and_spawn_with(|builder| { /// builder.deny::(); /// }); /// } /// # bevy_ecs::system::assert_is_system(example_system); - pub fn clone_with( + pub fn clone_and_spawn_with( &mut self, f: impl FnOnce(&mut EntityCloneBuilder) + Send + Sync + 'static, ) -> EntityCommands<'_> { let entity_clone = self.commands().spawn_empty().id(); - self.queue(clone_entity_with(entity_clone, f)); + self.queue(clone_and_spawn_with(entity_clone, f)); EntityCommands { commands: self.commands_mut().reborrow(), entity: entity_clone, @@ -2258,7 +2271,7 @@ fn observe( } } -fn clone_entity_with( +fn clone_and_spawn_with( entity_clone: Entity, f: impl FnOnce(&mut EntityCloneBuilder) + Send + Sync + 'static, ) -> impl EntityCommand { diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index b3215bfb66d53..e5a8ba6b1967d 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -444,7 +444,7 @@ mod tests { .id(); let e_clone = commands .entity(e) - .clone_with(|builder| { + .clone_and_spawn_with(|builder| { builder.recursive(true); }) .id(); @@ -483,7 +483,7 @@ mod tests { let child_clone = commands .entity(child) - .clone_with(|builder| { + .clone_and_spawn_with(|builder| { builder.as_child(true); }) .id();