diff --git a/crates/bevy_ecs/src/reflect/entity_commands.rs b/crates/bevy_ecs/src/reflect/entity_commands.rs index 2e0f649558..ae59cd1e33 100644 --- a/crates/bevy_ecs/src/reflect/entity_commands.rs +++ b/crates/bevy_ecs/src/reflect/entity_commands.rs @@ -140,7 +140,7 @@ pub trait ReflectCommandExt { ) -> &mut Self; } -impl<'w, 's, 'a> ReflectCommandExt for EntityCommands<'w, 's, 'a> { +impl ReflectCommandExt for EntityCommands<'_> { fn insert_reflect(&mut self, component: Box) -> &mut Self { self.commands.add(InsertReflect { entity: self.entity, diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index cd62763fa6..d2ebdce1a0 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -146,6 +146,31 @@ impl<'w, 's> Commands<'w, 's> { } } + /// Returns a [`Commands`] with a smaller lifetime. + /// This is useful if you have `&mut Commands` but need `Commands`. + /// + /// # Examples + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// fn my_system(mut commands: Commands) { + /// // We do our initialization in a separate function, + /// // which expects an owned `Commands`. + /// do_initialization(commands.reborrow()); + /// + /// // Since we only reborrowed the commands instead of moving them, we can still use them. + /// commands.spawn_empty(); + /// } + /// # + /// # fn do_initialization(_: Commands) {} + /// ``` + pub fn reborrow(&mut self) -> Commands<'w, '_> { + Commands { + queue: self.queue.reborrow(), + entities: self.entities, + } + } + /// Take all commands from `other` and append them to `self`, leaving `other` empty pub fn append(&mut self, other: &mut CommandQueue) { self.queue.append(other); @@ -186,11 +211,11 @@ impl<'w, 's> Commands<'w, 's> { /// /// - [`spawn`](Self::spawn) to spawn an entity with a bundle. /// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each. - pub fn spawn_empty<'a>(&'a mut self) -> EntityCommands<'w, 's, 'a> { + pub fn spawn_empty(&mut self) -> EntityCommands { let entity = self.entities.reserve_entity(); EntityCommands { entity, - commands: self, + commands: self.reborrow(), } } @@ -208,13 +233,13 @@ impl<'w, 's> Commands<'w, 's> { /// [`Commands::spawn`]. This method should generally only be used for sharing entities across /// apps, and only when they have a scheme worked out to share an ID space (which doesn't happen /// by default). - pub fn get_or_spawn<'a>(&'a mut self, entity: Entity) -> EntityCommands<'w, 's, 'a> { + pub fn get_or_spawn(&mut self, entity: Entity) -> EntityCommands { self.add(move |world: &mut World| { world.get_or_spawn(entity); }); EntityCommands { entity, - commands: self, + commands: self.reborrow(), } } @@ -268,7 +293,7 @@ impl<'w, 's> Commands<'w, 's> { /// /// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components. /// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each. - pub fn spawn<'a, T: Bundle>(&'a mut self, bundle: T) -> EntityCommands<'w, 's, 'a> { + pub fn spawn(&mut self, bundle: T) -> EntityCommands { let mut e = self.spawn_empty(); e.insert(bundle); e @@ -310,7 +335,7 @@ impl<'w, 's> Commands<'w, 's> { /// - [`get_entity`](Self::get_entity) for the fallible version. #[inline] #[track_caller] - pub fn entity<'a>(&'a mut self, entity: Entity) -> EntityCommands<'w, 's, 'a> { + pub fn entity(&mut self, entity: Entity) -> EntityCommands { #[inline(never)] #[cold] #[track_caller] @@ -359,10 +384,10 @@ impl<'w, 's> Commands<'w, 's> { /// - [`entity`](Self::entity) for the panicking version. #[inline] #[track_caller] - pub fn get_entity<'a>(&'a mut self, entity: Entity) -> Option> { + pub fn get_entity(&mut self, entity: Entity) -> Option { self.entities.contains(entity).then_some(EntityCommands { entity, - commands: self, + commands: self.reborrow(), }) } @@ -674,12 +699,12 @@ where } /// A list of commands that will be run to modify an [entity](crate::entity). -pub struct EntityCommands<'w, 's, 'a> { +pub struct EntityCommands<'a> { pub(crate) entity: Entity, - pub(crate) commands: &'a mut Commands<'w, 's>, + pub(crate) commands: Commands<'a, 'a>, } -impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> { +impl EntityCommands<'_> { /// Returns the [`Entity`] id of the entity. /// /// # Example @@ -698,6 +723,15 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> { self.entity } + /// Returns an [`EntityCommands`] with a smaller lifetime. + /// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`. + pub fn reborrow(&mut self) -> EntityCommands { + EntityCommands { + entity: self.entity, + commands: self.commands.reborrow(), + } + } + /// Adds a [`Bundle`] of components to the entity. /// /// This will overwrite any previous value(s) of the same component type. @@ -956,8 +990,8 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> { } /// Returns the underlying [`Commands`]. - pub fn commands(&mut self) -> &mut Commands<'w, 's> { - self.commands + pub fn commands(&mut self) -> Commands { + self.commands.reborrow() } } diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 2fcdc33240..8168654e18 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -919,6 +919,14 @@ impl<'a, T: SystemBuffer> DerefMut for Deferred<'a, T> { } } +impl Deferred<'_, T> { + /// Returns a [`Deferred`] with a smaller lifetime. + /// This is useful if you have `&mut Deferred` but need `Deferred`. + pub fn reborrow(&mut self) -> Deferred { + Deferred(self.0) + } +} + // SAFETY: Only local state is accessed. unsafe impl ReadOnlySystemParam for Deferred<'_, T> {} diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index d80c44c29e..d119afe95e 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -274,15 +274,15 @@ impl Command for RemoveParent { /// }); /// # } /// ``` -pub struct ChildBuilder<'w, 's, 'a> { - commands: &'a mut Commands<'w, 's>, +pub struct ChildBuilder<'a> { + commands: Commands<'a, 'a>, push_children: PushChildren, } -impl<'w, 's, 'a> ChildBuilder<'w, 's, 'a> { +impl ChildBuilder<'_> { /// Spawns an entity with the given bundle and inserts it into the parent entity's [`Children`]. /// Also adds [`Parent`] component to the created entity. - pub fn spawn(&mut self, bundle: impl Bundle) -> EntityCommands<'w, 's, '_> { + pub fn spawn(&mut self, bundle: impl Bundle) -> EntityCommands { let e = self.commands.spawn(bundle); self.push_children.children.push(e.id()); e @@ -290,7 +290,7 @@ impl<'w, 's, 'a> ChildBuilder<'w, 's, 'a> { /// Spawns an [`Entity`] with no components and inserts it into the parent entity's [`Children`]. /// Also adds [`Parent`] component to the created entity. - pub fn spawn_empty(&mut self) -> EntityCommands<'w, 's, '_> { + pub fn spawn_empty(&mut self) -> EntityCommands { let e = self.commands.spawn_empty(); self.push_children.children.push(e.id()); e @@ -302,7 +302,7 @@ impl<'w, 's, 'a> ChildBuilder<'w, 's, 'a> { } /// Adds a command to be executed, like [`Commands::add`]. - pub fn add_command(&mut self, command: C) -> &mut Self { + pub fn add_command(&mut self, command: C) -> &mut Self { self.commands.add(command); self } @@ -374,7 +374,7 @@ pub trait BuildChildren { fn remove_parent(&mut self) -> &mut Self; } -impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { +impl BuildChildren for EntityCommands<'_> { fn with_children(&mut self, spawn_children: impl FnOnce(&mut ChildBuilder)) -> &mut Self { let parent = self.id(); let mut builder = ChildBuilder { diff --git a/crates/bevy_hierarchy/src/hierarchy.rs b/crates/bevy_hierarchy/src/hierarchy.rs index 817b5e14c5..d707be839c 100644 --- a/crates/bevy_hierarchy/src/hierarchy.rs +++ b/crates/bevy_hierarchy/src/hierarchy.rs @@ -89,7 +89,7 @@ pub trait DespawnRecursiveExt { fn despawn_descendants(&mut self) -> &mut Self; } -impl<'w, 's, 'a> DespawnRecursiveExt for EntityCommands<'w, 's, 'a> { +impl DespawnRecursiveExt for EntityCommands<'_> { /// Despawns the provided entity and its children. fn despawn_recursive(mut self) { let entity = self.id(); diff --git a/crates/bevy_transform/src/commands.rs b/crates/bevy_transform/src/commands.rs index 5f34ead144..1a2f0d4c8a 100644 --- a/crates/bevy_transform/src/commands.rs +++ b/crates/bevy_transform/src/commands.rs @@ -85,7 +85,7 @@ pub trait BuildChildrenTransformExt { /// (during [`apply_deferred`](bevy_ecs::schedule::apply_deferred)). fn remove_parent_in_place(&mut self) -> &mut Self; } -impl<'w, 's, 'a> BuildChildrenTransformExt for EntityCommands<'w, 's, 'a> { +impl BuildChildrenTransformExt for EntityCommands<'_> { fn set_parent_in_place(&mut self, parent: Entity) -> &mut Self { let child = self.id(); self.commands().add(PushChildInPlace { child, parent });