Use an opaque type for EntityCommand::with_entity (#11210)

# Objective

The trait method `with_entity` is used to add an `EntityCommand` to the
command queue. Currently this method returns `WithEntity<C>` which pairs
a command with an `Entity`. By replacing this explicit type with an
opaque type, implementors can override this default implementation by
returning a custom command or closure that does the same thing with a
lower memory footprint.

# Solution

Return an opaque type from the method. As a bonus this file is now
cleaner without the `WithEntity` boilerplate
This commit is contained in:
Joseph 2024-06-26 05:47:46 -07:00 committed by GitHub
parent f0bdce7425
commit a4c621a127
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -14,7 +14,6 @@ use crate::{
}; };
use bevy_utils::tracing::{error, info}; use bevy_utils::tracing::{error, info};
pub use parallel_scope::*; pub use parallel_scope::*;
use std::marker::PhantomData;
/// A [`Command`] queue to perform structural changes to the [`World`]. /// A [`Command`] queue to perform structural changes to the [`World`].
/// ///
@ -825,34 +824,19 @@ impl<'w, 's> Commands<'w, 's> {
/// ``` /// ```
pub trait EntityCommand<Marker = ()>: Send + 'static { pub trait EntityCommand<Marker = ()>: Send + 'static {
/// Executes this command for the given [`Entity`]. /// Executes this command for the given [`Entity`].
fn apply(self, id: Entity, world: &mut World); fn apply(self, entity: Entity, world: &mut World);
/// Returns a [`Command`] which executes this [`EntityCommand`] for the given [`Entity`]. /// Returns a [`Command`] which executes this [`EntityCommand`] for the given [`Entity`].
fn with_entity(self, id: Entity) -> WithEntity<Marker, Self> ///
/// This method is called when adding an [`EntityCommand`] to a command queue via [`Commands`].
/// You can override the provided implementation if you can return a `Command` with a smaller memory
/// footprint than `(Entity, Self)`.
/// In most cases the provided implementation is sufficient.
fn with_entity(self, entity: Entity) -> impl Command
where where
Self: Sized, Self: Sized,
{ {
WithEntity { move |world: &mut World| self.apply(entity, world)
cmd: self,
id,
marker: PhantomData,
}
}
}
/// Turns an [`EntityCommand`] type into a [`Command`] type.
pub struct WithEntity<Marker, C: EntityCommand<Marker>> {
cmd: C,
id: Entity,
marker: PhantomData<fn() -> Marker>,
}
impl<M, C: EntityCommand<M>> Command for WithEntity<M, C>
where
M: 'static,
{
#[inline]
fn apply(self, world: &mut World) {
self.cmd.apply(self.id, world);
} }
} }