update component cloning documentation to mention moving components

This commit is contained in:
eugineerd 2025-07-09 20:31:06 +00:00
parent 0a30bf1283
commit e275156de5
4 changed files with 45 additions and 10 deletions

View File

@ -1035,16 +1035,16 @@ impl ComponentDescriptor {
}
}
/// Function type that can be used to clone an entity.
/// Function type that can be used to clone a component of an entity.
pub type ComponentCloneFn = fn(&SourceComponent, &mut ComponentCloneCtx);
/// The clone behavior to use when cloning a [`Component`].
/// The clone behavior to use when cloning or moving a [`Component`].
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub enum ComponentCloneBehavior {
/// Uses the default behavior (which is passed to [`ComponentCloneBehavior::resolve`])
#[default]
Default,
/// Do not clone this component.
/// Do not clone/move this component.
Ignore,
/// Uses a custom [`ComponentCloneFn`].
Custom(ComponentCloneFn),

View File

@ -349,6 +349,19 @@ impl<'a, 'b> ComponentCloneCtx<'a, 'b> {
/// 2. component-defined handler using [`Component::clone_behavior`]
/// 3. default handler override using [`EntityClonerBuilder::with_default_clone_fn`].
/// 4. reflect-based or noop default clone handler depending on if `bevy_reflect` feature 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.
#[derive(Default)]
pub struct EntityCloner {
filter: EntityClonerFilter,
@ -400,6 +413,7 @@ impl<'a> BundleScratch<'a> {
///
/// # Safety
/// All [`ComponentId`] values in this instance must come from `world`.
#[track_caller]
pub(crate) unsafe fn write(
self,
world: &mut World,
@ -709,7 +723,7 @@ impl EntityCloner {
}
}
(/* don't drop */ false, ())
(/* should drop? */ false, ())
},
);
}
@ -776,6 +790,8 @@ impl<'w, Filter: CloneByFilter> EntityClonerBuilder<'w, Filter> {
}
/// Sets the default clone function to use.
///
/// Will be overridden if [`EntityClonerBuilder::move_components`] is enabled.
pub fn with_default_clone_fn(&mut self, clone_fn: ComponentCloneFn) -> &mut Self {
self.state.default_clone_fn = clone_fn;
self
@ -788,6 +804,8 @@ impl<'w, Filter: CloneByFilter> EntityClonerBuilder<'w, Filter> {
///
/// The setting only applies to components that are allowed through the filter
/// at the time [`EntityClonerBuilder::clone_entity`] is called.
///
/// Enabling this overrides any custom function set with [`EntityClonerBuilder::with_default_clone_fn`].
pub fn move_components(&mut self, enable: bool) -> &mut Self {
self.state.move_components = enable;
self

View File

@ -310,8 +310,20 @@ pub fn clone_components<B: Bundle>(target: Entity) -> impl EntityCommand {
}
}
/// An [`EntityCommand`] that clones the specified components of an entity
/// and inserts them into another entity, then removes them from the original entity.
/// An [`EntityCommand`] moves the specified components of this entity into another entity.
///
/// Components with [`Ignore`] clone behavior will not be moved, while components that
/// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.
/// All other components will be moved without any other special handling.
///
/// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.
///
/// # Panics
///
/// The command will panic when applied if the target entity does not exist.
///
/// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore
/// [`Custom`]: crate::component::ComponentCloneBehavior::Custom
pub fn move_components<B: Bundle>(target: Entity) -> impl EntityCommand {
move |mut entity: EntityWorldMut| {
entity.move_components::<B>(target);

View File

@ -2234,15 +2234,20 @@ impl<'a> EntityCommands<'a> {
self.queue(entity_command::clone_components::<B>(target))
}
/// Clones the specified components of this entity and inserts them into another entity,
/// then removes the components from this entity.
/// Moves the specified components of this entity into another entity.
///
/// Components can only be cloned if they implement
/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
/// Components with [`Ignore`] clone behavior will not be moved, while components that
/// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.
/// All other components will be moved without any other special handling.
///
/// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.
///
/// # Panics
///
/// The command will panic when applied if the target entity does not exist.
///
/// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore
/// [`Custom`]: crate::component::ComponentCloneBehavior::Custom
pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
self.queue(entity_command::move_components::<B>(target))
}