Struct EntityCloner
pub struct EntityCloner { /* private fields */ }Expand description
A configuration determining how to clone entities. This can be built using EntityCloner::build_opt_out/
opt_in, which
returns an EntityClonerBuilder.
After configuration is complete an entity can be cloned using Self::clone_entity.
use bevy_ecs::prelude::*;
use bevy_ecs::entity::EntityCloner;
#[derive(Component, Clone, PartialEq, Eq)]
struct A {
field: usize,
}
let mut world = World::default();
let component = A { field: 5 };
let entity = world.spawn(component.clone()).id();
let entity_clone = world.spawn_empty().id();
EntityCloner::build_opt_out(&mut world).clone_entity(entity, entity_clone);
assert!(world.get::<A>(entity_clone).is_some_and(|c| *c == component));§Default cloning strategy
By default, all types that derive Component and implement either Clone or Reflect (with ReflectComponent) will be cloned
(with Clone-based implementation preferred in case component implements both).
It should be noted that if Component is implemented manually or if Clone implementation is conditional
(like when deriving Clone for a type with a generic parameter without Clone bound),
the component will be cloned using the default cloning strategy.
To use Clone-based handler (ComponentCloneBehavior::clone) in this case it should be set manually using one
of the methods mentioned in the Clone Behaviors section
Here’s an example of how to do it using clone_behavior:
#[derive(Clone, Component)]
#[component(clone_behavior = clone::<Self>())]
struct SomeComponent;
§Clone Behaviors
EntityCloner clones entities by cloning components using ComponentCloneBehavior, and there are multiple layers
to decide which handler to use for which component. The overall hierarchy looks like this (priority from most to least):
- local overrides using
EntityClonerBuilder::override_clone_behavior - component-defined handler using
Component::clone_behavior - default handler override using
EntityClonerBuilder::with_default_clone_fn. - reflect-based or noop default clone handler depending on if
bevy_reflectfeature is enabled or not.
§Moving components
EntityCloner can be configured to move components instead of cloning them by using EntityClonerBuilder::move_components.
In this mode components will be moved - removed from source entity and added to the target entity.
Components with ComponentCloneBehavior::Ignore clone behavior will not be moved, while components that
have a ComponentCloneBehavior::Custom clone behavior will be cloned using it and then removed from the source entity.
All other components will be bitwise copied from the source entity onto the target entity and then removed without dropping.
Choosing to move components instead of cloning makes EntityClonerBuilder::with_default_clone_fn ineffective since it’s replaced by
move handler for components that have ComponentCloneBehavior::Default clone behavior.
Note that moving components still triggers on_remove hooks/observers on source entity and on_insert/on_add hooks/observers on the target entity.
Implementations§
§impl EntityCloner
impl EntityCloner
pub fn build_opt_out(world: &mut World) -> EntityClonerBuilder<'_, OptOut>
pub fn build_opt_out(world: &mut World) -> EntityClonerBuilder<'_, OptOut>
Returns a new EntityClonerBuilder using the given world with the OptOut configuration.
This builder tries to clone every component from the source entity except for components that were
explicitly denied, for example by using the deny method.
Required components are not considered by denied components and must be explicitly denied as well if desired.
pub fn build_opt_in(world: &mut World) -> EntityClonerBuilder<'_, OptIn>
pub fn build_opt_in(world: &mut World) -> EntityClonerBuilder<'_, OptIn>
Returns a new EntityClonerBuilder using the given world with the OptIn configuration.
This builder tries to clone every component that was explicitly allowed from the source entity,
for example by using the allow method.
Components allowed to be cloned through this builder would also allow their required components,
which will be cloned from the source entity only if the target entity does not contain them already.
To skip adding required components see without_required_components.
pub fn linked_cloning(&self) -> bool
pub fn linked_cloning(&self) -> bool
Returns true if this cloner is configured to clone entities referenced in cloned components via RelationshipTarget::LINKED_SPAWN.
This will produce “deep” / recursive clones of relationship trees that have “linked spawn”.
pub fn clone_entity(
&mut self,
world: &mut World,
source: Entity,
target: Entity,
)
pub fn clone_entity( &mut self, world: &mut World, source: Entity, target: Entity, )
Clones and inserts components from the source entity into target entity using the stored configuration.
If this EntityCloner has EntityCloner::linked_cloning, then it will recursively spawn entities as defined
by RelationshipTarget components with
RelationshipTarget::LINKED_SPAWN
pub fn spawn_clone(&mut self, world: &mut World, source: Entity) -> Entity
pub fn spawn_clone(&mut self, world: &mut World, source: Entity) -> Entity
Clones and inserts components from the source entity into a newly spawned entity using the stored configuration.
If this EntityCloner has EntityCloner::linked_cloning, then it will recursively spawn entities as defined
by RelationshipTarget components with
RelationshipTarget::LINKED_SPAWN
pub fn clone_entity_mapped(
&mut self,
world: &mut World,
source: Entity,
mapper: &mut dyn EntityMapper,
) -> Entity
pub fn clone_entity_mapped( &mut self, world: &mut World, source: Entity, mapper: &mut dyn EntityMapper, ) -> Entity
Clones the entity into whatever entity mapper chooses for it.
Trait Implementations§
§impl Default for EntityCloner
impl Default for EntityCloner
§fn default() -> EntityCloner
fn default() -> EntityCloner
Auto Trait Implementations§
impl Freeze for EntityCloner
impl !RefUnwindSafe for EntityCloner
impl !Send for EntityCloner
impl !Sync for EntityCloner
impl Unpin for EntityCloner
impl UnsafeUnpin for EntityCloner
impl !UnwindSafe for EntityCloner
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
§fn into_result(self) -> Result<T, RunSystemError>
fn into_result(self) -> Result<T, RunSystemError>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.