diff --git a/crates/bevy_ecs/src/relationship/mod.rs b/crates/bevy_ecs/src/relationship/mod.rs index 82b39e04e5..f67614ec0e 100644 --- a/crates/bevy_ecs/src/relationship/mod.rs +++ b/crates/bevy_ecs/src/relationship/mod.rs @@ -4,6 +4,8 @@ mod related_methods; mod relationship_query; mod relationship_source_collection; +use core::marker::PhantomData; + use alloc::format; use bevy_utils::prelude::DebugName; @@ -12,7 +14,7 @@ pub use relationship_query::*; pub use relationship_source_collection::*; use crate::{ - component::{Component, Mutable}, + component::{Component, ComponentCloneBehavior, Mutable}, entity::{ComponentCloneCtx, Entity, SourceComponent}, error::CommandWithEntity, lifecycle::HookContext, @@ -323,6 +325,67 @@ pub enum RelationshipHookMode { Skip, } +/// Wrapper for components clone specialization using autoderef. +#[doc(hidden)] +#[derive(Default)] +pub struct RelationshipCloneBehaviorSpecialization(PhantomData); + +/// Base trait for relationship clone specialization using autoderef. +#[doc(hidden)] +pub trait RelationshipCloneBehaviorBase { + fn default_clone_behavior(&self) -> ComponentCloneBehavior; +} + +impl RelationshipCloneBehaviorBase for RelationshipCloneBehaviorSpecialization { + fn default_clone_behavior(&self) -> ComponentCloneBehavior { + // Relationships currently must have `Clone`/`Reflect`-based handler for cloning/moving logic to properly work. + ComponentCloneBehavior::Ignore + } +} + +/// Specialized trait for relationship clone specialization using autoderef. +#[doc(hidden)] +pub trait RelationshipCloneBehaviorViaReflect { + fn default_clone_behavior(&self) -> ComponentCloneBehavior; +} + +#[cfg(feature = "bevy_reflect")] +impl RelationshipCloneBehaviorViaReflect + for &RelationshipCloneBehaviorSpecialization +{ + fn default_clone_behavior(&self) -> ComponentCloneBehavior { + ComponentCloneBehavior::reflect() + } +} + +/// Specialized trait for relationship clone specialization using autoderef. +#[doc(hidden)] +pub trait RelationshipCloneBehaviorViaClone { + fn default_clone_behavior(&self) -> ComponentCloneBehavior; +} + +impl RelationshipCloneBehaviorViaClone + for &&RelationshipCloneBehaviorSpecialization +{ + fn default_clone_behavior(&self) -> ComponentCloneBehavior { + ComponentCloneBehavior::clone::() + } +} + +/// Specialized trait for relationship clone specialization using autoderef. +#[doc(hidden)] +pub trait RelationshipTargetCloneBehavior { + fn default_clone_behavior(&self) -> ComponentCloneBehavior; +} + +impl RelationshipTargetCloneBehavior + for &&&RelationshipCloneBehaviorSpecialization +{ + fn default_clone_behavior(&self) -> ComponentCloneBehavior { + ComponentCloneBehavior::Custom(clone_relationship_target::) + } +} + #[cfg(test)] mod tests { use crate::prelude::{ChildOf, Children};