Skip to main content

bevy_ecs/entity/
clone_entities.rs

1#![expect(
2    unsafe_op_in_unsafe_fn,
3    reason = "See #11590. To be removed once all applicable unsafe code has an unsafe block with a safety comment."
4)]
5
6use crate::{
7    archetype::Archetype,
8    bundle::{Bundle, BundleRemover, InsertMode},
9    change_detection::MaybeLocation,
10    component::{Component, ComponentCloneBehavior, ComponentCloneFn, ComponentId, ComponentInfo},
11    entity::{hash_map::EntityHashMap, Entity, EntityAllocator, EntityMapper},
12    query::DebugCheckedUnwrap,
13    relationship::RelationshipHookMode,
14    world::World,
15};
16use alloc::{boxed::Box, collections::VecDeque, vec::Vec};
17use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet};
18use bevy_ptr::{Ptr, PtrMut};
19use bevy_utils::prelude::DebugName;
20use bumpalo::Bump;
21use core::{any::TypeId, cell::LazyCell, ops::Range};
22use derive_more::From;
23
24/// Provides read access to the source component (the component being cloned) in a [`ComponentCloneFn`].
25pub struct SourceComponent<'a> {
26    ptr: Ptr<'a>,
27    info: &'a ComponentInfo,
28}
29
30impl<'a> SourceComponent<'a> {
31    /// Returns a reference to the component on the source entity.
32    ///
33    /// Will return `None` if `ComponentId` of requested component does not match `ComponentId` of source component
34    pub fn read<C: Component>(&self) -> Option<&C> {
35        if self
36            .info
37            .type_id()
38            .is_some_and(|id| id == TypeId::of::<C>())
39        {
40            // SAFETY:
41            // - Components and ComponentId are from the same world
42            // - source_component_ptr holds valid data of the type referenced by ComponentId
43            unsafe { Some(self.ptr.deref::<C>()) }
44        } else {
45            None
46        }
47    }
48
49    /// Returns the "raw" pointer to the source component.
50    pub fn ptr(&self) -> Ptr<'a> {
51        self.ptr
52    }
53
54    /// Returns a reference to the component on the source entity as [`&dyn Reflect`](bevy_reflect::Reflect).
55    ///
56    /// Will return `None` if:
57    /// - World does not have [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`).
58    /// - Component does not implement [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr).
59    /// - Component is not registered.
60    /// - Component does not have [`TypeId`]
61    /// - Registered [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr)'s [`TypeId`] does not match component's [`TypeId`]
62    #[cfg(feature = "bevy_reflect")]
63    pub fn read_reflect(
64        &self,
65        registry: &bevy_reflect::TypeRegistry,
66    ) -> Option<&dyn bevy_reflect::Reflect> {
67        let type_id = self.info.type_id()?;
68        let reflect_from_ptr = registry.get_type_data::<bevy_reflect::ReflectFromPtr>(type_id)?;
69        if reflect_from_ptr.type_id() != type_id {
70            return None;
71        }
72        // SAFETY: `source_component_ptr` stores data represented by `component_id`, which we used to get `ReflectFromPtr`.
73        unsafe { Some(reflect_from_ptr.as_reflect(self.ptr)) }
74    }
75}
76
77/// Context for component clone handlers.
78///
79/// Provides fast access to useful resources like [`AppTypeRegistry`](crate::reflect::AppTypeRegistry)
80/// and allows component clone handler to get information about component being cloned.
81pub struct ComponentCloneCtx<'a, 'b> {
82    component_id: ComponentId,
83    target_component_written: bool,
84    target_component_moved: bool,
85    bundle_scratch: &'a mut BundleScratchSpace<'b>,
86    bundle_scratch_allocator: &'b Bump,
87    allocator: &'a EntityAllocator,
88    source: Entity,
89    target: Entity,
90    component_info: &'a ComponentInfo,
91    state: &'a mut EntityClonerState,
92    mapper: &'a mut dyn EntityMapper,
93    #[cfg(feature = "bevy_reflect")]
94    type_registry: Option<&'a crate::reflect::AppTypeRegistry>,
95    #[cfg(not(feature = "bevy_reflect"))]
96    #[expect(dead_code, reason = "type_registry is only used with bevy_reflect")]
97    type_registry: Option<&'a ()>,
98}
99
100impl<'a, 'b> ComponentCloneCtx<'a, 'b> {
101    /// Create a new instance of `ComponentCloneCtx` that can be passed to component clone handlers.
102    ///
103    /// # Safety
104    /// Caller must ensure that:
105    /// - `component_info` corresponds to the `component_id` in the same world,.
106    /// - `source_component_ptr` points to a valid component of type represented by `component_id`.
107    unsafe fn new(
108        component_id: ComponentId,
109        source: Entity,
110        target: Entity,
111        bundle_scratch_allocator: &'b Bump,
112        bundle_scratch: &'a mut BundleScratchSpace<'b>,
113        allocator: &'a EntityAllocator,
114        component_info: &'a ComponentInfo,
115        entity_cloner: &'a mut EntityClonerState,
116        mapper: &'a mut dyn EntityMapper,
117        #[cfg(feature = "bevy_reflect")] type_registry: Option<&'a crate::reflect::AppTypeRegistry>,
118        #[cfg(not(feature = "bevy_reflect"))] type_registry: Option<&'a ()>,
119    ) -> Self {
120        Self {
121            component_id,
122            source,
123            target,
124            bundle_scratch,
125            target_component_written: false,
126            target_component_moved: false,
127            bundle_scratch_allocator,
128            allocator,
129            mapper,
130            component_info,
131            state: entity_cloner,
132            type_registry,
133        }
134    }
135
136    /// Returns true if [`write_target_component`](`Self::write_target_component`) was called before.
137    pub fn target_component_written(&self) -> bool {
138        self.target_component_written
139    }
140
141    /// Returns `true` if used in moving context
142    pub fn moving(&self) -> bool {
143        self.state.move_components
144    }
145
146    /// Returns the current source entity.
147    pub fn source(&self) -> Entity {
148        self.source
149    }
150
151    /// Returns the current target entity.
152    pub fn target(&self) -> Entity {
153        self.target
154    }
155
156    /// Returns the [`ComponentId`] of the component being cloned.
157    pub fn component_id(&self) -> ComponentId {
158        self.component_id
159    }
160
161    /// Returns the [`ComponentInfo`] of the component being cloned.
162    pub fn component_info(&self) -> &ComponentInfo {
163        self.component_info
164    }
165
166    /// Returns true if the [`EntityCloner`] is configured to recursively clone entities. When this is enabled,
167    /// entities stored in a cloned entity's [`RelationshipTarget`](crate::relationship::RelationshipTarget) component with
168    /// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN) will also be cloned.
169    #[inline]
170    pub fn linked_cloning(&self) -> bool {
171        self.state.linked_cloning
172    }
173
174    /// Returns this context's [`EntityMapper`].
175    pub fn entity_mapper(&mut self) -> &mut dyn EntityMapper {
176        self.mapper
177    }
178
179    /// Writes component data to target entity.
180    ///
181    /// # Panics
182    /// This will panic if:
183    /// - Component has already been written once.
184    /// - Component being written is not registered in the world.
185    /// - `ComponentId` of component being written does not match expected `ComponentId`.
186    pub fn write_target_component<C: Component>(&mut self, mut component: C) {
187        C::map_entities(&mut component, &mut self.mapper);
188        let debug_name = DebugName::type_name::<C>();
189        let short_name = debug_name.shortname();
190        if self.target_component_written {
191            panic!("Trying to write component '{short_name}' multiple times")
192        }
193        if self
194            .component_info
195            .type_id()
196            .is_none_or(|id| id != TypeId::of::<C>())
197        {
198            panic!("TypeId of component '{short_name}' does not match source component TypeId")
199        };
200        // SAFETY: the TypeId of self.component_id has been checked to ensure it matches `C`
201        unsafe {
202            self.bundle_scratch
203                .push(self.bundle_scratch_allocator, self.component_id, component);
204        };
205        self.target_component_written = true;
206    }
207
208    /// Writes component data to target entity by providing a pointer to source component data.
209    ///
210    /// # Safety
211    /// Caller must ensure that the passed in `ptr` references data that corresponds to the type of the source / target [`ComponentId`].
212    /// `ptr` must also contain data that the written component can "own" (for example, this should not directly copy non-Copy data).
213    ///
214    /// # Panics
215    /// This will panic if component has already been written once.
216    pub unsafe fn write_target_component_ptr(&mut self, ptr: Ptr) {
217        if self.target_component_written {
218            panic!("Trying to write component multiple times")
219        }
220        let layout = self.component_info.layout();
221        let target_ptr = self.bundle_scratch_allocator.alloc_layout(layout);
222        core::ptr::copy_nonoverlapping(ptr.as_ptr(), target_ptr.as_ptr(), layout.size());
223        self.bundle_scratch
224            .push_ptr(self.component_id, PtrMut::new(target_ptr));
225        self.target_component_written = true;
226    }
227
228    /// Writes component data to target entity.
229    ///
230    /// # Panics
231    /// This will panic if:
232    /// - World does not have [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`).
233    /// - Component does not implement [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr).
234    /// - Source component does not have [`TypeId`].
235    /// - Passed component's [`TypeId`] does not match source component [`TypeId`].
236    /// - Component has already been written once.
237    #[cfg(feature = "bevy_reflect")]
238    pub fn write_target_component_reflect(&mut self, component: Box<dyn bevy_reflect::Reflect>) {
239        if self.target_component_written {
240            panic!("Trying to write component multiple times")
241        }
242        let source_type_id = self
243            .component_info
244            .type_id()
245            .expect("Source component must have TypeId");
246        let component_type_id = component.type_id();
247        if source_type_id != component_type_id {
248            panic!("Passed component TypeId does not match source component TypeId")
249        }
250        let component_layout = self.component_info.layout();
251
252        let component_data_ptr = Box::into_raw(component).cast::<u8>();
253        let target_component_data_ptr =
254            self.bundle_scratch_allocator.alloc_layout(component_layout);
255        // SAFETY:
256        // - target_component_data_ptr and component_data have the same data type.
257        // - component_data_ptr has layout of component_layout
258        unsafe {
259            core::ptr::copy_nonoverlapping(
260                component_data_ptr,
261                target_component_data_ptr.as_ptr(),
262                component_layout.size(),
263            );
264            self.bundle_scratch
265                .push_ptr(self.component_id, PtrMut::new(target_component_data_ptr));
266
267            if component_layout.size() > 0 {
268                // Ensure we don't attempt to deallocate zero-sized components
269                alloc::alloc::dealloc(component_data_ptr, component_layout);
270            }
271        }
272
273        self.target_component_written = true;
274    }
275
276    /// Returns [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`) if it exists in the world.
277    ///
278    /// NOTE: Prefer this method instead of manually reading the resource from the world.
279    #[cfg(feature = "bevy_reflect")]
280    pub fn type_registry(&self) -> Option<&crate::reflect::AppTypeRegistry> {
281        self.type_registry
282    }
283
284    /// Queues the `entity` to be cloned by the current [`EntityCloner`]
285    pub fn queue_entity_clone(&mut self, entity: Entity) {
286        let target = self.allocator.alloc();
287        self.mapper.set_mapped(entity, target);
288        self.state.clone_queue.push_back(entity);
289    }
290
291    /// Queues a deferred clone operation, which will run with exclusive [`World`] access immediately after calling the clone handler for each component on an entity.
292    /// This exists, despite its similarity to [`Commands`](crate::system::Commands), to provide access to the entity mapper in the current context.
293    pub fn queue_deferred(
294        &mut self,
295        deferred: impl FnOnce(&mut World, &mut dyn EntityMapper) + 'static,
296    ) {
297        self.state.deferred_commands.push_back(Box::new(deferred));
298    }
299
300    /// Marks component as moved and it's `drop` won't run.
301    fn move_component(&mut self) {
302        self.target_component_moved = true;
303        self.target_component_written = true;
304    }
305}
306
307/// A configuration determining how to clone entities. This can be built using [`EntityCloner::build_opt_out`]/
308/// [`opt_in`](EntityCloner::build_opt_in), which
309/// returns an [`EntityClonerBuilder`].
310///
311/// After configuration is complete an entity can be cloned using [`Self::clone_entity`].
312///
313///```
314/// use bevy_ecs::prelude::*;
315/// use bevy_ecs::entity::EntityCloner;
316///
317/// #[derive(Component, Clone, PartialEq, Eq)]
318/// struct A {
319///     field: usize,
320/// }
321///
322/// let mut world = World::default();
323///
324/// let component = A { field: 5 };
325///
326/// let entity = world.spawn(component.clone()).id();
327/// let entity_clone = world.spawn_empty().id();
328///
329/// EntityCloner::build_opt_out(&mut world).clone_entity(entity, entity_clone);
330///
331/// assert!(world.get::<A>(entity_clone).is_some_and(|c| *c == component));
332///```
333///
334/// # Default cloning strategy
335/// By default, all types that derive [`Component`] and implement either [`Clone`] or `Reflect` (with `ReflectComponent`) will be cloned
336/// (with `Clone`-based implementation preferred in case component implements both).
337///
338/// It should be noted that if `Component` is implemented manually or if `Clone` implementation is conditional
339/// (like when deriving `Clone` for a type with a generic parameter without `Clone` bound),
340/// the component will be cloned using the [default cloning strategy](crate::component::ComponentCloneBehavior::global_default_fn).
341/// To use `Clone`-based handler ([`ComponentCloneBehavior::clone`]) in this case it should be set manually using one
342/// of the methods mentioned in the [Clone Behaviors](#Clone-Behaviors) section
343///
344/// Here's an example of how to do it using [`clone_behavior`](Component::clone_behavior):
345/// ```
346/// # use bevy_ecs::prelude::*;
347/// # use bevy_ecs::component::{StorageType, ComponentCloneBehavior, Mutable};
348/// #[derive(Clone, Component)]
349/// #[component(clone_behavior = clone::<Self>())]
350/// struct SomeComponent;
351///
352/// ```
353///
354/// # Clone Behaviors
355/// [`EntityCloner`] clones entities by cloning components using [`ComponentCloneBehavior`], and there are multiple layers
356/// to decide which handler to use for which component. The overall hierarchy looks like this (priority from most to least):
357/// 1. local overrides using [`EntityClonerBuilder::override_clone_behavior`]
358/// 2. component-defined handler using [`Component::clone_behavior`]
359/// 3. default handler override using [`EntityClonerBuilder::with_default_clone_fn`].
360/// 4. reflect-based or noop default clone handler depending on if `bevy_reflect` feature is enabled or not.
361///
362/// # Moving components
363/// [`EntityCloner`] can be configured to move components instead of cloning them by using [`EntityClonerBuilder::move_components`].
364/// In this mode components will be moved - removed from source entity and added to the target entity.
365///
366/// Components with [`ComponentCloneBehavior::Ignore`] clone behavior will not be moved, while components that
367/// have a [`ComponentCloneBehavior::Custom`] clone behavior will be cloned using it and then removed from the source entity.
368/// All other components will be bitwise copied from the source entity onto the target entity and then removed without dropping.
369///
370/// Choosing to move components instead of cloning makes [`EntityClonerBuilder::with_default_clone_fn`] ineffective since it's replaced by
371/// move handler for components that have [`ComponentCloneBehavior::Default`] clone behavior.
372///
373/// Note that moving components still triggers `on_remove` hooks/observers on source entity and `on_insert`/`on_add` hooks/observers on the target entity.
374#[derive(Default)]
375pub struct EntityCloner {
376    filter: EntityClonerFilter,
377    state: EntityClonerState,
378}
379
380/// An expandable scratch space for defining a dynamic bundle.
381struct BundleScratchSpace<'a> {
382    component_ids: Vec<ComponentId>,
383    component_ptrs: Vec<PtrMut<'a>>,
384}
385
386impl<'a> BundleScratchSpace<'a> {
387    pub(crate) fn with_capacity(capacity: usize) -> Self {
388        Self {
389            component_ids: Vec::with_capacity(capacity),
390            component_ptrs: Vec::with_capacity(capacity),
391        }
392    }
393
394    /// Pushes the `ptr` component onto this storage with the given `id` [`ComponentId`].
395    ///
396    /// # Safety
397    /// The `id` [`ComponentId`] must match the component `ptr` for whatever [`World`] this scratch will
398    /// be written to. `ptr` must contain valid uniquely-owned data that matches the type of component referenced
399    /// in `id`.
400    pub(crate) unsafe fn push_ptr(&mut self, id: ComponentId, ptr: PtrMut<'a>) {
401        self.component_ids.push(id);
402        self.component_ptrs.push(ptr);
403    }
404
405    /// Pushes the `C` component onto this storage with the given `id` [`ComponentId`], using the given `bump` allocator.
406    ///
407    /// # Safety
408    /// The `id` [`ComponentId`] must match the component `C` for whatever [`World`] this scratch will
409    /// be written to.
410    pub(crate) unsafe fn push<C: Component>(
411        &mut self,
412        allocator: &'a Bump,
413        id: ComponentId,
414        component: C,
415    ) {
416        let component_ref = allocator.alloc(component);
417        self.component_ids.push(id);
418        self.component_ptrs.push(PtrMut::from(component_ref));
419    }
420
421    /// Writes the scratch components to the given entity in the given world.
422    ///
423    /// # Safety
424    /// All [`ComponentId`] values in this instance must come from `world`.
425    #[track_caller]
426    pub(crate) unsafe fn write(
427        self,
428        world: &mut World,
429        entity: Entity,
430        relationship_hook_insert_mode: RelationshipHookMode,
431    ) {
432        // SAFETY:
433        // - All `component_ids` are from the same world as `entity`
434        // - All `component_data_ptrs` are valid types represented by `component_ids`
435        unsafe {
436            world.entity_mut(entity).insert_by_ids_internal(
437                &self.component_ids,
438                self.component_ptrs.into_iter().map(|ptr| ptr.promote()),
439                relationship_hook_insert_mode,
440            );
441        }
442    }
443}
444
445impl EntityCloner {
446    /// Returns a new [`EntityClonerBuilder`] using the given `world` with the [`OptOut`] configuration.
447    ///
448    /// This builder tries to clone every component from the source entity except for components that were
449    /// explicitly denied, for example by using the [`deny`](EntityClonerBuilder<OptOut>::deny) method.
450    ///
451    /// Required components are not considered by denied components and must be explicitly denied as well if desired.
452    pub fn build_opt_out(world: &mut World) -> EntityClonerBuilder<'_, OptOut> {
453        EntityClonerBuilder {
454            world,
455            filter: Default::default(),
456            state: Default::default(),
457        }
458    }
459
460    /// Returns a new [`EntityClonerBuilder`] using the given `world` with the [`OptIn`] configuration.
461    ///
462    /// This builder tries to clone every component that was explicitly allowed from the source entity,
463    /// for example by using the [`allow`](EntityClonerBuilder<OptIn>::allow) method.
464    ///
465    /// Components allowed to be cloned through this builder would also allow their required components,
466    /// which will be cloned from the source entity only if the target entity does not contain them already.
467    /// To skip adding required components see [`without_required_components`](EntityClonerBuilder<OptIn>::without_required_components).
468    pub fn build_opt_in(world: &mut World) -> EntityClonerBuilder<'_, OptIn> {
469        EntityClonerBuilder {
470            world,
471            filter: Default::default(),
472            state: Default::default(),
473        }
474    }
475
476    /// Returns `true` if this cloner is configured to clone entities referenced in cloned components via [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN).
477    /// This will produce "deep" / recursive clones of relationship trees that have "linked spawn".
478    #[inline]
479    pub fn linked_cloning(&self) -> bool {
480        self.state.linked_cloning
481    }
482
483    /// Clones and inserts components from the `source` entity into `target` entity using the stored configuration.
484    /// If this [`EntityCloner`] has [`EntityCloner::linked_cloning`], then it will recursively spawn entities as defined
485    /// by [`RelationshipTarget`](crate::relationship::RelationshipTarget) components with
486    /// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN)
487    #[track_caller]
488    pub fn clone_entity(&mut self, world: &mut World, source: Entity, target: Entity) {
489        let mut map = EntityHashMap::<Entity>::new();
490        map.set_mapped(source, target);
491        self.clone_entity_mapped(world, source, &mut map);
492    }
493
494    /// Clones and inserts components from the `source` entity into a newly spawned entity using the stored configuration.
495    /// If this [`EntityCloner`] has [`EntityCloner::linked_cloning`], then it will recursively spawn entities as defined
496    /// by [`RelationshipTarget`](crate::relationship::RelationshipTarget) components with
497    /// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN)
498    #[track_caller]
499    pub fn spawn_clone(&mut self, world: &mut World, source: Entity) -> Entity {
500        let target = world.spawn_empty().id();
501        self.clone_entity(world, source, target);
502        target
503    }
504
505    /// Clones the entity into whatever entity `mapper` chooses for it.
506    #[track_caller]
507    pub fn clone_entity_mapped(
508        &mut self,
509        world: &mut World,
510        source: Entity,
511        mapper: &mut dyn EntityMapper,
512    ) -> Entity {
513        Self::clone_entity_mapped_internal(&mut self.state, &mut self.filter, world, source, mapper)
514    }
515
516    #[track_caller]
517    #[inline]
518    fn clone_entity_mapped_internal(
519        state: &mut EntityClonerState,
520        filter: &mut impl CloneByFilter,
521        world: &mut World,
522        source: Entity,
523        mapper: &mut dyn EntityMapper,
524    ) -> Entity {
525        // All relationships on the root should have their hooks run
526        let target = Self::clone_entity_internal(
527            state,
528            filter,
529            world,
530            source,
531            mapper,
532            RelationshipHookMode::Run,
533        );
534        let child_hook_insert_mode = if state.linked_cloning {
535            // When spawning "linked relationships", we want to ignore hooks for relationships we are spawning, while
536            // still registering with original relationship targets that are "not linked" to the current recursive spawn.
537            RelationshipHookMode::RunIfNotLinked
538        } else {
539            // If we are not cloning "linked relationships" recursively, then we want any cloned relationship components to
540            // register themselves with their original relationship target.
541            RelationshipHookMode::Run
542        };
543        loop {
544            let queued = state.clone_queue.pop_front();
545            if let Some(queued) = queued {
546                Self::clone_entity_internal(
547                    state,
548                    filter,
549                    world,
550                    queued,
551                    mapper,
552                    child_hook_insert_mode,
553                );
554            } else {
555                break;
556            }
557        }
558        target
559    }
560
561    /// Clones and inserts components from the `source` entity into the entity mapped by `mapper` from `source` using the stored configuration.
562    #[track_caller]
563    fn clone_entity_internal(
564        state: &mut EntityClonerState,
565        filter: &mut impl CloneByFilter,
566        world: &mut World,
567        source: Entity,
568        mapper: &mut dyn EntityMapper,
569        relationship_hook_insert_mode: RelationshipHookMode,
570    ) -> Entity {
571        let target = mapper.get_mapped(source);
572        // The target may need to be constructed if it hasn't been already.
573        // If this fails, it either didn't need to be constructed (ok) or doesn't exist (caught better later).
574        let _ = world.spawn_empty_at(target);
575
576        // PERF: reusing allocated space across clones would be more efficient. Consider an allocation model similar to `Commands`.
577        let bundle_scratch_allocator = Bump::new();
578        let mut bundle_scratch: BundleScratchSpace;
579        let mut moved_components: Vec<ComponentId> = Vec::new();
580        let mut deferred_cloned_component_ids: Vec<ComponentId> = Vec::new();
581        {
582            let world = world.as_unsafe_world_cell();
583            let source_entity = world
584                .get_entity(source)
585                .expect("Source entity must be valid and spawned.");
586            let source_archetype = source_entity.archetype();
587
588            #[cfg(feature = "bevy_reflect")]
589            // SAFETY: we have unique access to `world`, nothing else accesses the registry at this moment, and we clone
590            // the registry, which prevents future conflicts.
591            let app_registry = unsafe {
592                world
593                    .get_resource::<crate::reflect::AppTypeRegistry>()
594                    .cloned()
595            };
596            #[cfg(not(feature = "bevy_reflect"))]
597            let app_registry = Option::<()>::None;
598
599            bundle_scratch = BundleScratchSpace::with_capacity(source_archetype.component_count());
600
601            let target_archetype = LazyCell::new(|| {
602                world
603                    .get_entity(target)
604                    .expect("Target entity must be valid and spawned.")
605                    .archetype()
606            });
607
608            if state.move_components {
609                moved_components.reserve(source_archetype.component_count());
610                // Replace default handler with special handler which would track if component was moved instead of cloned.
611                // This is later used to determine whether we need to run component's drop function when removing it from the source entity or not.
612                state.default_clone_fn = |_, ctx| ctx.move_component();
613            }
614
615            filter.clone_components(source_archetype, target_archetype, |component| {
616                let handler = match state.clone_behavior_overrides.get(&component).or_else(|| {
617                    world
618                        .components()
619                        .get_info(component)
620                        .map(ComponentInfo::clone_behavior)
621                }) {
622                    Some(behavior) => match behavior {
623                        ComponentCloneBehavior::Default => state.default_clone_fn,
624                        ComponentCloneBehavior::Ignore => return,
625                        ComponentCloneBehavior::Custom(custom) => *custom,
626                    },
627                    None => state.default_clone_fn,
628                };
629
630                // SAFETY: This component exists because it is present on the archetype.
631                let info = unsafe { world.components().get_info_unchecked(component) };
632
633                // SAFETY:
634                // - There are no other mutable references to source entity.
635                // - `component` is from `source_entity`'s archetype
636                let source_component_ptr =
637                    unsafe { source_entity.get_by_id(component).debug_checked_unwrap() };
638
639                let source_component = SourceComponent {
640                    info,
641                    ptr: source_component_ptr,
642                };
643
644                // SAFETY:
645                // - `components` and `component` are from the same world
646                // - `source_component_ptr` is valid and points to the same type as represented by `component`
647                let mut ctx = unsafe {
648                    ComponentCloneCtx::new(
649                        component,
650                        source,
651                        target,
652                        &bundle_scratch_allocator,
653                        &mut bundle_scratch,
654                        world.entity_allocator(),
655                        info,
656                        state,
657                        mapper,
658                        app_registry.as_ref(),
659                    )
660                };
661
662                (handler)(&source_component, &mut ctx);
663
664                if ctx.state.move_components {
665                    if ctx.target_component_moved {
666                        moved_components.push(component);
667                    }
668                    // Component wasn't written by the clone handler, so assume it's going to be
669                    // cloned/processed using deferred_commands instead.
670                    // This means that it's ComponentId won't be present in BundleScratch's component_ids,
671                    // but it should still be removed when move_components is true.
672                    else if !ctx.target_component_written() {
673                        deferred_cloned_component_ids.push(component);
674                    }
675                }
676            });
677        }
678
679        world.flush();
680
681        for deferred in state.deferred_commands.drain(..) {
682            (deferred)(world, mapper);
683        }
684
685        if !world.entities.contains(target) {
686            panic!("Target entity does not exist");
687        }
688
689        if state.move_components {
690            let mut source_entity = world.entity_mut(source);
691
692            let cloned_components = if deferred_cloned_component_ids.is_empty() {
693                &bundle_scratch.component_ids
694            } else {
695                // Remove all cloned components with drop by concatenating both vectors
696                deferred_cloned_component_ids.extend(&bundle_scratch.component_ids);
697                &deferred_cloned_component_ids
698            };
699            source_entity.remove_by_ids_with_caller(
700                cloned_components,
701                MaybeLocation::caller(),
702                RelationshipHookMode::RunIfNotLinked,
703                BundleRemover::empty_pre_remove,
704            );
705
706            let table_row = source_entity.location().table_row;
707
708            // Copy moved components and then forget them without calling drop
709            source_entity.remove_by_ids_with_caller(
710                &moved_components,
711                MaybeLocation::caller(),
712                RelationshipHookMode::RunIfNotLinked,
713                |sparse_sets, mut table, components, bundle| {
714                    for &component_id in bundle {
715                        let Some(component_ptr) = sparse_sets
716                            .get(component_id)
717                            .and_then(|component| component.get(source))
718                            .or_else(|| {
719                                // SAFETY: table_row is within this table because we just got it from entity's current location
720                                table.as_mut().and_then(|table| unsafe {
721                                    table.get_component(component_id, table_row)
722                                })
723                            })
724                        else {
725                            // Component was removed by some other component's clone side effect before we got to it.
726                            continue;
727                        };
728
729                        // SAFETY: component_id is valid because remove_by_ids_with_caller checked it before calling this closure
730                        let info = unsafe { components.get_info_unchecked(component_id) };
731                        let layout = info.layout();
732                        let target_ptr = bundle_scratch_allocator.alloc_layout(layout);
733                        // SAFETY:
734                        // - component_ptr points to data with component layout
735                        // - target_ptr was just allocated with component layout
736                        // - component_ptr and target_ptr don't overlap
737                        // - component_ptr matches component_id
738                        unsafe {
739                            core::ptr::copy_nonoverlapping(
740                                component_ptr.as_ptr(),
741                                target_ptr.as_ptr(),
742                                layout.size(),
743                            );
744                            bundle_scratch.push_ptr(component_id, PtrMut::new(target_ptr));
745                        }
746                    }
747
748                    (/* should drop? */ false, ())
749                },
750            );
751        }
752
753        // SAFETY:
754        // - All `component_ids` are from the same world as `target` entity
755        // - All `component_data_ptrs` are valid types represented by `component_ids`
756        unsafe { bundle_scratch.write(world, target, relationship_hook_insert_mode) };
757        target
758    }
759}
760
761/// Part of the [`EntityCloner`], see there for more information.
762struct EntityClonerState {
763    clone_behavior_overrides: HashMap<ComponentId, ComponentCloneBehavior>,
764    move_components: bool,
765    linked_cloning: bool,
766    default_clone_fn: ComponentCloneFn,
767    clone_queue: VecDeque<Entity>,
768    deferred_commands: VecDeque<Box<dyn FnOnce(&mut World, &mut dyn EntityMapper)>>,
769}
770
771impl Default for EntityClonerState {
772    fn default() -> Self {
773        Self {
774            move_components: false,
775            linked_cloning: false,
776            default_clone_fn: ComponentCloneBehavior::global_default_fn(),
777            clone_behavior_overrides: Default::default(),
778            clone_queue: Default::default(),
779            deferred_commands: Default::default(),
780        }
781    }
782}
783
784/// A builder for configuring [`EntityCloner`]. See [`EntityCloner`] for more information.
785pub struct EntityClonerBuilder<'w, Filter> {
786    world: &'w mut World,
787    filter: Filter,
788    state: EntityClonerState,
789}
790
791impl<'w, Filter: CloneByFilter> EntityClonerBuilder<'w, Filter> {
792    /// Internally calls [`EntityCloner::clone_entity`] on the builder's [`World`].
793    pub fn clone_entity(&mut self, source: Entity, target: Entity) -> &mut Self {
794        let mut mapper = EntityHashMap::<Entity>::new();
795        mapper.set_mapped(source, target);
796        EntityCloner::clone_entity_mapped_internal(
797            &mut self.state,
798            &mut self.filter,
799            self.world,
800            source,
801            &mut mapper,
802        );
803        self
804    }
805
806    /// Finishes configuring [`EntityCloner`] returns it.
807    pub fn finish(self) -> EntityCloner {
808        EntityCloner {
809            filter: self.filter.into(),
810            state: self.state,
811        }
812    }
813
814    /// Sets the default clone function to use.
815    ///
816    /// Will be overridden if [`EntityClonerBuilder::move_components`] is enabled.
817    pub fn with_default_clone_fn(&mut self, clone_fn: ComponentCloneFn) -> &mut Self {
818        self.state.default_clone_fn = clone_fn;
819        self
820    }
821
822    /// Sets whether the cloner should remove any components that were cloned,
823    /// effectively moving them from the source entity to the target.
824    ///
825    /// This is disabled by default.
826    ///
827    /// The setting only applies to components that are allowed through the filter
828    /// at the time [`EntityClonerBuilder::clone_entity`] is called.
829    ///
830    /// Enabling this overrides any custom function set with [`EntityClonerBuilder::with_default_clone_fn`].
831    pub fn move_components(&mut self, enable: bool) -> &mut Self {
832        self.state.move_components = enable;
833        self
834    }
835
836    /// Overrides the [`ComponentCloneBehavior`] for a component in this builder.
837    /// This handler will be used to clone the component instead of the global one defined by the [`EntityCloner`].
838    ///
839    /// See [Clone Behaviors section of `EntityCloner`](EntityCloner#clone-behaviors) to understand how this affects handler priority.
840    pub fn override_clone_behavior<T: Component>(
841        &mut self,
842        clone_behavior: ComponentCloneBehavior,
843    ) -> &mut Self {
844        if let Some(id) = self.world.components().valid_component_id::<T>() {
845            self.state
846                .clone_behavior_overrides
847                .insert(id, clone_behavior);
848        }
849        self
850    }
851
852    /// Overrides the [`ComponentCloneBehavior`] for a component with the given `component_id` in this builder.
853    /// This handler will be used to clone the component instead of the global one defined by the [`EntityCloner`].
854    ///
855    /// See [Clone Behaviors section of `EntityCloner`](EntityCloner#clone-behaviors) to understand how this affects handler priority.
856    pub fn override_clone_behavior_with_id(
857        &mut self,
858        component_id: ComponentId,
859        clone_behavior: ComponentCloneBehavior,
860    ) -> &mut Self {
861        self.state
862            .clone_behavior_overrides
863            .insert(component_id, clone_behavior);
864        self
865    }
866
867    /// Removes a previously set override of [`ComponentCloneBehavior`] for a component in this builder.
868    pub fn remove_clone_behavior_override<T: Component>(&mut self) -> &mut Self {
869        if let Some(id) = self.world.components().valid_component_id::<T>() {
870            self.state.clone_behavior_overrides.remove(&id);
871        }
872        self
873    }
874
875    /// Removes a previously set override of [`ComponentCloneBehavior`] for a given `component_id` in this builder.
876    pub fn remove_clone_behavior_override_with_id(
877        &mut self,
878        component_id: ComponentId,
879    ) -> &mut Self {
880        self.state.clone_behavior_overrides.remove(&component_id);
881        self
882    }
883
884    /// When true this cloner will be configured to clone entities referenced in cloned components via [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN).
885    /// This will produce "deep" / recursive clones of relationship trees that have "linked spawn".
886    pub fn linked_cloning(&mut self, linked_cloning: bool) -> &mut Self {
887        self.state.linked_cloning = linked_cloning;
888        self
889    }
890}
891
892impl<'w> EntityClonerBuilder<'w, OptOut> {
893    /// By default, any components denied through the filter will automatically
894    /// deny all of components they are required by too.
895    ///
896    /// This method allows for a scoped mode where any changes to the filter
897    /// will not involve these requiring components.
898    ///
899    /// If component `A` is denied in the `builder` closure here and component `B`
900    /// requires `A`, then `A` will be inserted with the value defined in `B`'s
901    /// [`Component` derive](https://docs.rs/bevy/latest/bevy/ecs/component/trait.Component.html#required-components).
902    /// This assumes `A` is missing yet at the target entity.
903    pub fn without_required_by_components(&mut self, builder: impl FnOnce(&mut Self)) -> &mut Self {
904        self.filter.attach_required_by_components = false;
905        builder(self);
906        self.filter.attach_required_by_components = true;
907        self
908    }
909
910    /// Sets whether components are always cloned ([`InsertMode::Replace`], the default) or only if it is missing
911    /// ([`InsertMode::Keep`]) at the target entity.
912    ///
913    /// This makes no difference if the target is spawned by the cloner.
914    pub fn insert_mode(&mut self, insert_mode: InsertMode) -> &mut Self {
915        self.filter.insert_mode = insert_mode;
916        self
917    }
918
919    /// Disallows all components of the bundle from being cloned.
920    ///
921    /// If component `A` is denied here and component `B` requires `A`, then `A`
922    /// is denied as well. See [`Self::without_required_by_components`] to alter
923    /// this behavior.
924    pub fn deny<T: Bundle>(&mut self) -> &mut Self {
925        let bundle_id = self.world.register_bundle::<T>().id();
926        self.deny_by_ids(bundle_id)
927    }
928
929    /// Extends the list of components that shouldn't be cloned.
930    /// Supports filtering by [`TypeId`], [`ComponentId`], [`BundleId`](`crate::bundle::BundleId`), and [`IntoIterator`] yielding one of these.
931    ///
932    /// If component `A` is denied here and component `B` requires `A`, then `A`
933    /// is denied as well. See [`Self::without_required_by_components`] to alter
934    /// this behavior.
935    pub fn deny_by_ids<M: Marker>(&mut self, ids: impl FilterableIds<M>) -> &mut Self {
936        ids.filter_ids(&mut |ids| match ids {
937            FilterableId::Type(type_id) => {
938                if let Some(id) = self.world.components().get_valid_id(type_id) {
939                    self.filter.filter_deny(id, self.world);
940                }
941            }
942            FilterableId::Component(component_id) => {
943                self.filter.filter_deny(component_id, self.world);
944            }
945            FilterableId::Bundle(bundle_id) => {
946                if let Some(bundle) = self.world.bundles().get(bundle_id) {
947                    let ids = bundle.explicit_components().iter();
948                    for &id in ids {
949                        self.filter.filter_deny(id, self.world);
950                    }
951                }
952            }
953        });
954        self
955    }
956}
957
958impl<'w> EntityClonerBuilder<'w, OptIn> {
959    /// By default, any components allowed through the filter will automatically
960    /// allow all of their required components.
961    ///
962    /// This method allows for a scoped mode where any changes to the filter
963    /// will not involve required components.
964    ///
965    /// If component `A` is allowed in the `builder` closure here and requires
966    /// component `B`, then `B` will be inserted with the value defined in `A`'s
967    /// [`Component` derive](https://docs.rs/bevy/latest/bevy/ecs/component/trait.Component.html#required-components).
968    /// This assumes `B` is missing yet at the target entity.
969    pub fn without_required_components(&mut self, builder: impl FnOnce(&mut Self)) -> &mut Self {
970        self.filter.attach_required_components = false;
971        builder(self);
972        self.filter.attach_required_components = true;
973        self
974    }
975
976    /// Adds all components of the bundle to the list of components to clone.
977    ///
978    /// If component `A` is allowed here and requires component `B`, then `B`
979    /// is allowed as well. See [`Self::without_required_components`]
980    /// to alter this behavior.
981    pub fn allow<T: Bundle>(&mut self) -> &mut Self {
982        let bundle_id = self.world.register_bundle::<T>().id();
983        self.allow_by_ids(bundle_id)
984    }
985
986    /// Adds all components of the bundle to the list of components to clone if
987    /// the target does not contain them.
988    ///
989    /// If component `A` is allowed here and requires component `B`, then `B`
990    /// is allowed as well. See [`Self::without_required_components`]
991    /// to alter this behavior.
992    pub fn allow_if_new<T: Bundle>(&mut self) -> &mut Self {
993        let bundle_id = self.world.register_bundle::<T>().id();
994        self.allow_by_ids_if_new(bundle_id)
995    }
996
997    /// Extends the list of components to clone.
998    /// Supports filtering by [`TypeId`], [`ComponentId`], [`BundleId`](`crate::bundle::BundleId`), and [`IntoIterator`] yielding one of these.
999    ///
1000    /// If component `A` is allowed here and requires component `B`, then `B`
1001    /// is allowed as well. See [`Self::without_required_components`]
1002    /// to alter this behavior.
1003    pub fn allow_by_ids<M: Marker>(&mut self, ids: impl FilterableIds<M>) -> &mut Self {
1004        self.allow_by_ids_inner(ids, InsertMode::Replace);
1005        self
1006    }
1007
1008    /// Extends the list of components to clone if the target does not contain them.
1009    /// Supports filtering by [`TypeId`], [`ComponentId`], [`BundleId`](`crate::bundle::BundleId`), and [`IntoIterator`] yielding one of these.
1010    ///
1011    /// If component `A` is allowed here and requires component `B`, then `B`
1012    /// is allowed as well. See [`Self::without_required_components`]
1013    /// to alter this behavior.
1014    pub fn allow_by_ids_if_new<M: Marker>(&mut self, ids: impl FilterableIds<M>) -> &mut Self {
1015        self.allow_by_ids_inner(ids, InsertMode::Keep);
1016        self
1017    }
1018
1019    fn allow_by_ids_inner<M: Marker>(
1020        &mut self,
1021        ids: impl FilterableIds<M>,
1022        insert_mode: InsertMode,
1023    ) {
1024        ids.filter_ids(&mut |id| match id {
1025            FilterableId::Type(type_id) => {
1026                if let Some(id) = self.world.components().get_valid_id(type_id) {
1027                    self.filter.filter_allow(id, self.world, insert_mode);
1028                }
1029            }
1030            FilterableId::Component(component_id) => {
1031                self.filter
1032                    .filter_allow(component_id, self.world, insert_mode);
1033            }
1034            FilterableId::Bundle(bundle_id) => {
1035                if let Some(bundle) = self.world.bundles().get(bundle_id) {
1036                    let ids = bundle.explicit_components().iter();
1037                    for &id in ids {
1038                        self.filter.filter_allow(id, self.world, insert_mode);
1039                    }
1040                }
1041            }
1042        });
1043    }
1044}
1045
1046/// Filters that can selectively clone components depending on its inner configuration are unified with this trait.
1047#[doc(hidden)]
1048pub trait CloneByFilter: Into<EntityClonerFilter> {
1049    /// The filter will call `clone_component` for every [`ComponentId`] that passes it.
1050    fn clone_components<'a>(
1051        &mut self,
1052        source_archetype: &Archetype,
1053        target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1054        clone_component: impl FnMut(ComponentId),
1055    );
1056}
1057
1058/// Part of the [`EntityCloner`], see there for more information.
1059#[doc(hidden)]
1060#[derive(From)]
1061pub enum EntityClonerFilter {
1062    OptOut(OptOut),
1063    OptIn(OptIn),
1064}
1065
1066impl Default for EntityClonerFilter {
1067    fn default() -> Self {
1068        Self::OptOut(Default::default())
1069    }
1070}
1071
1072impl CloneByFilter for EntityClonerFilter {
1073    #[inline]
1074    fn clone_components<'a>(
1075        &mut self,
1076        source_archetype: &Archetype,
1077        target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1078        clone_component: impl FnMut(ComponentId),
1079    ) {
1080        match self {
1081            Self::OptOut(filter) => {
1082                filter.clone_components(source_archetype, target_archetype, clone_component);
1083            }
1084            Self::OptIn(filter) => {
1085                filter.clone_components(source_archetype, target_archetype, clone_component);
1086            }
1087        }
1088    }
1089}
1090
1091/// Generic for [`EntityClonerBuilder`] that makes the cloner try to clone every component from the source entity
1092/// except for components that were explicitly denied, for example by using the
1093/// [`deny`](EntityClonerBuilder::deny) method.
1094///
1095/// Required components are not considered by denied components and must be explicitly denied as well if desired.
1096pub struct OptOut {
1097    /// Contains the components that should not be cloned.
1098    deny: HashSet<ComponentId>,
1099
1100    /// Determines if a component is inserted when it is existing already.
1101    insert_mode: InsertMode,
1102
1103    /// Is `true` unless during [`EntityClonerBuilder::without_required_by_components`] which will suppress
1104    /// components that require denied components to be denied as well, causing them to be created independent
1105    /// from the value at the source entity if needed.
1106    attach_required_by_components: bool,
1107}
1108
1109impl Default for OptOut {
1110    fn default() -> Self {
1111        Self {
1112            deny: Default::default(),
1113            insert_mode: InsertMode::Replace,
1114            attach_required_by_components: true,
1115        }
1116    }
1117}
1118
1119impl CloneByFilter for OptOut {
1120    #[inline]
1121    fn clone_components<'a>(
1122        &mut self,
1123        source_archetype: &Archetype,
1124        target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1125        mut clone_component: impl FnMut(ComponentId),
1126    ) {
1127        match self.insert_mode {
1128            InsertMode::Replace => {
1129                for component in source_archetype.iter_components() {
1130                    if !self.deny.contains(&component) {
1131                        clone_component(component);
1132                    }
1133                }
1134            }
1135            InsertMode::Keep => {
1136                for component in source_archetype.iter_components() {
1137                    if !target_archetype.contains(component) && !self.deny.contains(&component) {
1138                        clone_component(component);
1139                    }
1140                }
1141            }
1142        }
1143    }
1144}
1145
1146impl OptOut {
1147    /// Denies a component through the filter, also deny components that require `id` if
1148    /// [`Self::attach_required_by_components`] is true.
1149    #[inline]
1150    fn filter_deny(&mut self, id: ComponentId, world: &World) {
1151        self.deny.insert(id);
1152        if self.attach_required_by_components
1153            && let Some(required_by) = world.components().get_required_by(id)
1154        {
1155            self.deny.extend(required_by.iter());
1156        };
1157    }
1158}
1159
1160/// Generic for [`EntityClonerBuilder`] that makes the cloner try to clone every component that was explicitly
1161/// allowed from the source entity, for example by using the [`allow`](EntityClonerBuilder::allow) method.
1162///
1163/// Required components are also cloned when the target entity does not contain them.
1164pub struct OptIn {
1165    /// Contains the components explicitly allowed to be cloned.
1166    allow: HashMap<ComponentId, Explicit>,
1167
1168    /// Lists of required components, [`Explicit`] refers to a range in it.
1169    required_of_allow: Vec<ComponentId>,
1170
1171    /// Contains the components required by those in [`Self::allow`].
1172    /// Also contains the number of components in [`Self::allow`] each is required by to track
1173    /// when to skip cloning a required component after skipping explicit components that require it.
1174    required: HashMap<ComponentId, Required>,
1175
1176    /// Is `true` unless during [`EntityClonerBuilder::without_required_components`] which will suppress
1177    /// evaluating required components to clone, causing them to be created independent from the value at
1178    /// the source entity if needed.
1179    attach_required_components: bool,
1180}
1181
1182impl Default for OptIn {
1183    fn default() -> Self {
1184        Self {
1185            allow: Default::default(),
1186            required_of_allow: Default::default(),
1187            required: Default::default(),
1188            attach_required_components: true,
1189        }
1190    }
1191}
1192
1193impl CloneByFilter for OptIn {
1194    #[inline]
1195    fn clone_components<'a>(
1196        &mut self,
1197        source_archetype: &Archetype,
1198        target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1199        mut clone_component: impl FnMut(ComponentId),
1200    ) {
1201        // track the amount of components left not being cloned yet to exit this method early
1202        let mut uncloned_components = source_archetype.component_count();
1203
1204        // track if any `Required::required_by_reduced` has been reduced so they are reset
1205        let mut reduced_any = false;
1206
1207        // clone explicit components
1208        for (&component, explicit) in self.allow.iter() {
1209            if uncloned_components == 0 {
1210                // exhausted all source components, reset changed `Required::required_by_reduced`
1211                if reduced_any {
1212                    self.required
1213                        .iter_mut()
1214                        .for_each(|(_, required)| required.reset());
1215                }
1216                return;
1217            }
1218
1219            let do_clone = source_archetype.contains(component)
1220                && (explicit.insert_mode == InsertMode::Replace
1221                    || !target_archetype.contains(component));
1222            if do_clone {
1223                clone_component(component);
1224                uncloned_components -= 1;
1225            } else if let Some(range) = explicit.required_range.clone() {
1226                for component in self.required_of_allow[range].iter() {
1227                    // may be None if required component was also added as explicit later
1228                    if let Some(required) = self.required.get_mut(component) {
1229                        required.required_by_reduced -= 1;
1230                        reduced_any = true;
1231                    }
1232                }
1233            }
1234        }
1235
1236        let mut required_iter = self.required.iter_mut();
1237
1238        // clone required components
1239        let required_components = required_iter
1240            .by_ref()
1241            .filter_map(|(&component, required)| {
1242                let do_clone = required.required_by_reduced > 0 // required by a cloned component
1243                    && source_archetype.contains(component) // must exist to clone, may miss if removed
1244                    && !target_archetype.contains(component); // do not overwrite existing values
1245
1246                // reset changed `Required::required_by_reduced` as this is done being checked here
1247                required.reset();
1248
1249                do_clone.then_some(component)
1250            })
1251            .take(uncloned_components);
1252
1253        for required_component in required_components {
1254            clone_component(required_component);
1255        }
1256
1257        // if the `required_components` iterator has not been exhausted yet because the source has no more
1258        // components to clone, iterate the rest to reset changed `Required::required_by_reduced` for the
1259        // next clone
1260        if reduced_any {
1261            required_iter.for_each(|(_, required)| required.reset());
1262        }
1263    }
1264}
1265
1266impl OptIn {
1267    /// Allows a component through the filter, also allow required components if
1268    /// [`Self::attach_required_components`] is true.
1269    #[inline]
1270    fn filter_allow(&mut self, id: ComponentId, world: &World, mut insert_mode: InsertMode) {
1271        match self.allow.entry(id) {
1272            Entry::Vacant(explicit) => {
1273                // explicit components should not appear in the required map
1274                self.required.remove(&id);
1275
1276                if !self.attach_required_components {
1277                    explicit.insert(Explicit {
1278                        insert_mode,
1279                        required_range: None,
1280                    });
1281                } else {
1282                    self.filter_allow_with_required(id, world, insert_mode);
1283                }
1284            }
1285            Entry::Occupied(mut explicit) => {
1286                let explicit = explicit.get_mut();
1287
1288                // set required component range if it was inserted with `None` earlier
1289                if self.attach_required_components && explicit.required_range.is_none() {
1290                    if explicit.insert_mode == InsertMode::Replace {
1291                        // do not overwrite with Keep if component was allowed as Replace earlier
1292                        insert_mode = InsertMode::Replace;
1293                    }
1294
1295                    self.filter_allow_with_required(id, world, insert_mode);
1296                } else if explicit.insert_mode == InsertMode::Keep {
1297                    // potentially overwrite Keep with Replace
1298                    explicit.insert_mode = insert_mode;
1299                }
1300            }
1301        };
1302    }
1303
1304    // Allow a component through the filter and include required components.
1305    #[inline]
1306    fn filter_allow_with_required(
1307        &mut self,
1308        id: ComponentId,
1309        world: &World,
1310        insert_mode: InsertMode,
1311    ) {
1312        let Some(info) = world.components().get_info(id) else {
1313            return;
1314        };
1315
1316        let iter = info
1317            .required_components()
1318            .iter_ids()
1319            .filter(|id| !self.allow.contains_key(id))
1320            .inspect(|id| {
1321                // set or increase the number of components this `id` is required by
1322                self.required
1323                    .entry(*id)
1324                    .and_modify(|required| {
1325                        required.required_by += 1;
1326                        required.required_by_reduced += 1;
1327                    })
1328                    .or_insert(Required {
1329                        required_by: 1,
1330                        required_by_reduced: 1,
1331                    });
1332            });
1333
1334        let start = self.required_of_allow.len();
1335        self.required_of_allow.extend(iter);
1336        let end = self.required_of_allow.len();
1337
1338        self.allow.insert(
1339            id,
1340            Explicit {
1341                insert_mode,
1342                required_range: Some(start..end),
1343            },
1344        );
1345    }
1346}
1347
1348/// Contains the components explicitly allowed to be cloned.
1349struct Explicit {
1350    /// If component was added via [`allow`](EntityClonerBuilder::allow) etc, this is `Overwrite`.
1351    ///
1352    /// If component was added via [`allow_if_new`](EntityClonerBuilder::allow_if_new) etc, this is `Keep`.
1353    insert_mode: InsertMode,
1354
1355    /// Contains the range in [`OptIn::required_of_allow`] for this component containing its
1356    /// required components.
1357    ///
1358    /// Is `None` if [`OptIn::attach_required_components`] was `false` when added.
1359    /// It may be set to `Some` later if the component is later added explicitly again with
1360    /// [`OptIn::attach_required_components`] being `true`.
1361    ///
1362    /// Range is empty if this component has no required components that are not also explicitly allowed.
1363    required_range: Option<Range<usize>>,
1364}
1365
1366struct Required {
1367    /// Amount of explicit components this component is required by.
1368    required_by: u32,
1369
1370    /// As [`Self::required_by`] but is reduced during cloning when an explicit component is not cloned,
1371    /// either because [`Explicit::insert_mode`] is `Keep` or the source entity does not contain it.
1372    ///
1373    /// If this is zero, the required component is not cloned.
1374    ///
1375    /// The counter is reset to `required_by` when the cloning is over in case another entity needs to be
1376    /// cloned by the same [`EntityCloner`].
1377    required_by_reduced: u32,
1378}
1379
1380impl Required {
1381    // Revert reductions for the next entity to clone with this EntityCloner
1382    #[inline]
1383    fn reset(&mut self) {
1384        self.required_by_reduced = self.required_by;
1385    }
1386}
1387
1388mod private {
1389    use crate::{bundle::BundleId, component::ComponentId};
1390    use core::any::TypeId;
1391    use derive_more::From;
1392
1393    /// Marker trait to allow multiple blanket implementations for [`FilterableIds`].
1394    pub trait Marker {}
1395    /// Marker struct for [`FilterableIds`] implementation for single-value types.
1396    pub struct ScalarType {}
1397    impl Marker for ScalarType {}
1398    /// Marker struct for [`FilterableIds`] implementation for [`IntoIterator`] types.
1399    pub struct VectorType {}
1400    impl Marker for VectorType {}
1401
1402    /// Defines types of ids that [`EntityClonerBuilder`](`super::EntityClonerBuilder`) can filter components by.
1403    #[derive(From)]
1404    pub enum FilterableId {
1405        Type(TypeId),
1406        Component(ComponentId),
1407        Bundle(BundleId),
1408    }
1409
1410    impl<'a, T> From<&'a T> for FilterableId
1411    where
1412        T: Into<FilterableId> + Copy,
1413    {
1414        #[inline]
1415        fn from(value: &'a T) -> Self {
1416            (*value).into()
1417        }
1418    }
1419
1420    /// A trait to allow [`EntityClonerBuilder`](`super::EntityClonerBuilder`) filter by any supported id type and their iterators,
1421    /// reducing the number of method permutations required for all id types.
1422    ///
1423    /// The supported id types that can be used to filter components are defined by [`FilterableId`], which allows following types: [`TypeId`], [`ComponentId`] and [`BundleId`].
1424    ///
1425    /// `M` is a generic marker to allow multiple blanket implementations of this trait.
1426    /// This works because `FilterableId<M1>` is a different trait from `FilterableId<M2>`, so multiple blanket implementations for different `M` are allowed.
1427    /// The reason this is required is because supporting `IntoIterator` requires blanket implementation, but that will conflict with implementation for `TypeId`
1428    /// since `IntoIterator` can technically be implemented for `TypeId` in the future.
1429    /// Functions like `allow_by_ids` rely on type inference to automatically select proper type for `M` at call site.
1430    pub trait FilterableIds<M: Marker> {
1431        /// Takes in a function that processes all types of [`FilterableId`] one-by-one.
1432        fn filter_ids(self, ids: &mut impl FnMut(FilterableId));
1433    }
1434
1435    impl<I, T> FilterableIds<VectorType> for I
1436    where
1437        I: IntoIterator<Item = T>,
1438        T: Into<FilterableId>,
1439    {
1440        #[inline]
1441        fn filter_ids(self, ids: &mut impl FnMut(FilterableId)) {
1442            for id in self.into_iter() {
1443                ids(id.into());
1444            }
1445        }
1446    }
1447
1448    impl<T> FilterableIds<ScalarType> for T
1449    where
1450        T: Into<FilterableId>,
1451    {
1452        #[inline]
1453        fn filter_ids(self, ids: &mut impl FnMut(FilterableId)) {
1454            ids(self.into());
1455        }
1456    }
1457}
1458
1459use private::{FilterableId, FilterableIds, Marker};
1460
1461#[cfg(test)]
1462mod tests {
1463    use super::*;
1464    use crate::{
1465        component::{ComponentDescriptor, StorageType},
1466        lifecycle::HookContext,
1467        prelude::{ChildOf, Children, Resource},
1468        world::{DeferredWorld, FromWorld, World},
1469    };
1470    use bevy_ptr::OwningPtr;
1471    use core::marker::PhantomData;
1472    use core::{alloc::Layout, ops::Deref};
1473
1474    #[cfg(feature = "bevy_reflect")]
1475    mod reflect {
1476        use super::*;
1477        use crate::reflect::{AppTypeRegistry, ReflectComponent, ReflectFromWorld};
1478        use alloc::vec;
1479        use bevy_reflect::{std_traits::ReflectDefault, FromType, Reflect, ReflectFromPtr};
1480
1481        #[test]
1482        fn clone_entity_using_reflect() {
1483            #[derive(Component, Reflect, Clone, PartialEq, Eq)]
1484            #[reflect(Component)]
1485            struct A {
1486                field: usize,
1487            }
1488
1489            let mut world = World::default();
1490            world.init_resource::<AppTypeRegistry>();
1491            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1492            registry.write().register::<A>();
1493
1494            world.register_component::<A>();
1495            let component = A { field: 5 };
1496
1497            let e = world.spawn(component.clone()).id();
1498            let e_clone = world.spawn_empty().id();
1499
1500            EntityCloner::build_opt_out(&mut world)
1501                .override_clone_behavior::<A>(ComponentCloneBehavior::reflect())
1502                .clone_entity(e, e_clone);
1503
1504            assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1505        }
1506
1507        #[test]
1508        fn clone_entity_using_reflect_all_paths() {
1509            #[derive(PartialEq, Eq, Default, Debug)]
1510            struct NotClone;
1511
1512            // `reflect_clone`-based fast path
1513            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1514            #[reflect(from_reflect = false)]
1515            struct A {
1516                field: usize,
1517                field2: Vec<usize>,
1518            }
1519
1520            // `ReflectDefault`-based fast path
1521            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1522            #[reflect(Default)]
1523            #[reflect(from_reflect = false)]
1524            struct B {
1525                field: usize,
1526                field2: Vec<usize>,
1527                #[reflect(ignore)]
1528                ignored: NotClone,
1529            }
1530
1531            // `ReflectFromReflect`-based fast path
1532            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1533            struct C {
1534                field: usize,
1535                field2: Vec<usize>,
1536                #[reflect(ignore)]
1537                ignored: NotClone,
1538            }
1539
1540            // `ReflectFromWorld`-based fast path
1541            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1542            #[reflect(FromWorld)]
1543            #[reflect(from_reflect = false)]
1544            struct D {
1545                field: usize,
1546                field2: Vec<usize>,
1547                #[reflect(ignore)]
1548                ignored: NotClone,
1549            }
1550
1551            let mut world = World::default();
1552            world.init_resource::<AppTypeRegistry>();
1553            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1554            registry.write().register::<(A, B, C, D)>();
1555
1556            let a_id = world.register_component::<A>();
1557            let b_id = world.register_component::<B>();
1558            let c_id = world.register_component::<C>();
1559            let d_id = world.register_component::<D>();
1560            let component_a = A {
1561                field: 5,
1562                field2: vec![1, 2, 3, 4, 5],
1563            };
1564            let component_b = B {
1565                field: 5,
1566                field2: vec![1, 2, 3, 4, 5],
1567                ignored: NotClone,
1568            };
1569            let component_c = C {
1570                field: 6,
1571                field2: vec![1, 2, 3, 4, 5],
1572                ignored: NotClone,
1573            };
1574            let component_d = D {
1575                field: 7,
1576                field2: vec![1, 2, 3, 4, 5],
1577                ignored: NotClone,
1578            };
1579
1580            let e = world
1581                .spawn((component_a, component_b, component_c, component_d))
1582                .id();
1583            let e_clone = world.spawn_empty().id();
1584
1585            EntityCloner::build_opt_out(&mut world)
1586                .override_clone_behavior_with_id(a_id, ComponentCloneBehavior::reflect())
1587                .override_clone_behavior_with_id(b_id, ComponentCloneBehavior::reflect())
1588                .override_clone_behavior_with_id(c_id, ComponentCloneBehavior::reflect())
1589                .override_clone_behavior_with_id(d_id, ComponentCloneBehavior::reflect())
1590                .clone_entity(e, e_clone);
1591
1592            assert_eq!(world.get::<A>(e_clone), Some(world.get::<A>(e).unwrap()));
1593            assert_eq!(world.get::<B>(e_clone), Some(world.get::<B>(e).unwrap()));
1594            assert_eq!(world.get::<C>(e_clone), Some(world.get::<C>(e).unwrap()));
1595            assert_eq!(world.get::<D>(e_clone), Some(world.get::<D>(e).unwrap()));
1596        }
1597
1598        #[test]
1599        fn read_source_component_reflect_should_return_none_on_invalid_reflect_from_ptr() {
1600            #[derive(Component, Reflect)]
1601            struct A;
1602
1603            #[derive(Component, Reflect)]
1604            struct B;
1605
1606            fn test_handler(source: &SourceComponent, ctx: &mut ComponentCloneCtx) {
1607                let registry = ctx.type_registry().unwrap();
1608                assert!(source.read_reflect(&registry.read()).is_none());
1609            }
1610
1611            let mut world = World::default();
1612            world.init_resource::<AppTypeRegistry>();
1613            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1614            {
1615                let mut registry = registry.write();
1616                registry.register::<A>();
1617                registry
1618                    .get_mut(TypeId::of::<A>())
1619                    .unwrap()
1620                    .insert(<ReflectFromPtr as FromType<B>>::from_type());
1621            }
1622
1623            let e = world.spawn(A).id();
1624            let e_clone = world.spawn_empty().id();
1625
1626            EntityCloner::build_opt_out(&mut world)
1627                .override_clone_behavior::<A>(ComponentCloneBehavior::Custom(test_handler))
1628                .clone_entity(e, e_clone);
1629        }
1630
1631        #[test]
1632        fn clone_entity_specialization() {
1633            #[derive(Component, Reflect, PartialEq, Eq)]
1634            #[reflect(Component)]
1635            struct A {
1636                field: usize,
1637            }
1638
1639            impl Clone for A {
1640                fn clone(&self) -> Self {
1641                    Self { field: 10 }
1642                }
1643            }
1644
1645            let mut world = World::default();
1646            world.init_resource::<AppTypeRegistry>();
1647            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1648            registry.write().register::<A>();
1649
1650            let component = A { field: 5 };
1651
1652            let e = world.spawn(component.clone()).id();
1653            let e_clone = world.spawn_empty().id();
1654
1655            EntityCloner::build_opt_out(&mut world).clone_entity(e, e_clone);
1656
1657            assert!(world
1658                .get::<A>(e_clone)
1659                .is_some_and(|comp| *comp == A { field: 10 }));
1660        }
1661
1662        #[test]
1663        fn clone_entity_using_reflect_should_skip_without_panic() {
1664            // Not reflected
1665            #[derive(Component, PartialEq, Eq, Default, Debug)]
1666            struct A;
1667
1668            // No valid type data and not `reflect_clone`-able
1669            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1670            #[reflect(Component)]
1671            #[reflect(from_reflect = false)]
1672            struct B(#[reflect(ignore)] PhantomData<()>);
1673
1674            let mut world = World::default();
1675
1676            // No AppTypeRegistry
1677            let e = world.spawn((A, B(Default::default()))).id();
1678            let e_clone = world.spawn_empty().id();
1679            EntityCloner::build_opt_out(&mut world)
1680                .override_clone_behavior::<A>(ComponentCloneBehavior::reflect())
1681                .override_clone_behavior::<B>(ComponentCloneBehavior::reflect())
1682                .clone_entity(e, e_clone);
1683            assert_eq!(world.get::<A>(e_clone), None);
1684            assert_eq!(world.get::<B>(e_clone), None);
1685
1686            // With AppTypeRegistry
1687            world.init_resource::<AppTypeRegistry>();
1688            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1689            registry.write().register::<B>();
1690
1691            let e = world.spawn((A, B(Default::default()))).id();
1692            let e_clone = world.spawn_empty().id();
1693            EntityCloner::build_opt_out(&mut world).clone_entity(e, e_clone);
1694            assert_eq!(world.get::<A>(e_clone), None);
1695            assert_eq!(world.get::<B>(e_clone), None);
1696        }
1697
1698        #[test]
1699        fn clone_with_reflect_from_world() {
1700            #[derive(Component, Reflect, PartialEq, Eq, Debug)]
1701            #[reflect(Component, FromWorld, from_reflect = false)]
1702            struct SomeRef(
1703                #[entities] Entity,
1704                // We add an ignored field here to ensure `reflect_clone` fails and `FromWorld` is used
1705                #[reflect(ignore)] PhantomData<()>,
1706            );
1707
1708            #[derive(Resource)]
1709            struct FromWorldCalled(bool);
1710
1711            impl FromWorld for SomeRef {
1712                fn from_world(world: &mut World) -> Self {
1713                    world.insert_resource(FromWorldCalled(true));
1714                    SomeRef(Entity::PLACEHOLDER, Default::default())
1715                }
1716            }
1717            let mut world = World::new();
1718            let registry = AppTypeRegistry::default();
1719            registry.write().register::<SomeRef>();
1720            world.insert_resource(registry);
1721
1722            let a = world.spawn_empty().id();
1723            let b = world.spawn_empty().id();
1724            let c = world.spawn(SomeRef(a, Default::default())).id();
1725            let d = world.spawn_empty().id();
1726            let mut map = EntityHashMap::<Entity>::new();
1727            map.insert(a, b);
1728            map.insert(c, d);
1729
1730            let cloned = EntityCloner::default().clone_entity_mapped(&mut world, c, &mut map);
1731            assert_eq!(
1732                *world.entity(cloned).get::<SomeRef>().unwrap(),
1733                SomeRef(b, Default::default())
1734            );
1735            assert!(world.resource::<FromWorldCalled>().0);
1736        }
1737    }
1738
1739    #[test]
1740    fn clone_entity_using_clone() {
1741        #[derive(Component, Clone, PartialEq, Eq)]
1742        struct A {
1743            field: usize,
1744        }
1745
1746        let mut world = World::default();
1747
1748        let component = A { field: 5 };
1749
1750        let e = world.spawn(component.clone()).id();
1751        let e_clone = world.spawn_empty().id();
1752
1753        EntityCloner::build_opt_out(&mut world).clone_entity(e, e_clone);
1754
1755        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1756    }
1757
1758    #[test]
1759    fn clone_entity_with_allow_filter() {
1760        #[derive(Component, Clone, PartialEq, Eq)]
1761        struct A {
1762            field: usize,
1763        }
1764
1765        #[derive(Component, Clone)]
1766        struct B;
1767
1768        let mut world = World::default();
1769
1770        let component = A { field: 5 };
1771
1772        let e = world.spawn((component.clone(), B)).id();
1773        let e_clone = world.spawn_empty().id();
1774
1775        EntityCloner::build_opt_in(&mut world)
1776            .allow::<A>()
1777            .clone_entity(e, e_clone);
1778
1779        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1780        assert!(world.get::<B>(e_clone).is_none());
1781    }
1782
1783    #[test]
1784    fn clone_entity_with_deny_filter() {
1785        #[derive(Component, Clone, PartialEq, Eq)]
1786        struct A {
1787            field: usize,
1788        }
1789
1790        #[derive(Component, Clone)]
1791        #[require(C)]
1792        struct B;
1793
1794        #[derive(Component, Clone, Default)]
1795        struct C;
1796
1797        let mut world = World::default();
1798
1799        let component = A { field: 5 };
1800
1801        let e = world.spawn((component.clone(), B, C)).id();
1802        let e_clone = world.spawn_empty().id();
1803
1804        EntityCloner::build_opt_out(&mut world)
1805            .deny::<C>()
1806            .clone_entity(e, e_clone);
1807
1808        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1809        assert!(world.get::<B>(e_clone).is_none());
1810        assert!(world.get::<C>(e_clone).is_none());
1811    }
1812
1813    #[test]
1814    fn clone_entity_with_deny_filter_without_required_by() {
1815        #[derive(Component, Clone)]
1816        #[require(B { field: 5 })]
1817        struct A;
1818
1819        #[derive(Component, Clone, PartialEq, Eq)]
1820        struct B {
1821            field: usize,
1822        }
1823
1824        let mut world = World::default();
1825
1826        let e = world.spawn((A, B { field: 10 })).id();
1827        let e_clone = world.spawn_empty().id();
1828
1829        EntityCloner::build_opt_out(&mut world)
1830            .without_required_by_components(|builder| {
1831                builder.deny::<B>();
1832            })
1833            .clone_entity(e, e_clone);
1834
1835        assert!(world.get::<A>(e_clone).is_some());
1836        assert!(world
1837            .get::<B>(e_clone)
1838            .is_some_and(|c| *c == B { field: 5 }));
1839    }
1840
1841    #[test]
1842    fn clone_entity_with_deny_filter_if_new() {
1843        #[derive(Component, Clone, PartialEq, Eq)]
1844        struct A {
1845            field: usize,
1846        }
1847
1848        #[derive(Component, Clone)]
1849        struct B;
1850
1851        #[derive(Component, Clone)]
1852        struct C;
1853
1854        let mut world = World::default();
1855
1856        let e = world.spawn((A { field: 5 }, B, C)).id();
1857        let e_clone = world.spawn(A { field: 8 }).id();
1858
1859        EntityCloner::build_opt_out(&mut world)
1860            .deny::<B>()
1861            .insert_mode(InsertMode::Keep)
1862            .clone_entity(e, e_clone);
1863
1864        assert!(world
1865            .get::<A>(e_clone)
1866            .is_some_and(|c| *c == A { field: 8 }));
1867        assert!(world.get::<B>(e_clone).is_none());
1868        assert!(world.get::<C>(e_clone).is_some());
1869    }
1870
1871    #[test]
1872    fn allow_and_allow_if_new_always_allows() {
1873        #[derive(Component, Clone, PartialEq, Debug)]
1874        struct A(u8);
1875
1876        let mut world = World::default();
1877        let e = world.spawn(A(1)).id();
1878        let e_clone1 = world.spawn(A(2)).id();
1879
1880        EntityCloner::build_opt_in(&mut world)
1881            .allow_if_new::<A>()
1882            .allow::<A>()
1883            .clone_entity(e, e_clone1);
1884
1885        assert_eq!(world.get::<A>(e_clone1), Some(&A(1)));
1886
1887        let e_clone2 = world.spawn(A(2)).id();
1888
1889        EntityCloner::build_opt_in(&mut world)
1890            .allow::<A>()
1891            .allow_if_new::<A>()
1892            .clone_entity(e, e_clone2);
1893
1894        assert_eq!(world.get::<A>(e_clone2), Some(&A(1)));
1895    }
1896
1897    #[test]
1898    fn with_and_without_required_components_include_required() {
1899        #[derive(Component, Clone, PartialEq, Debug)]
1900        #[require(B(5))]
1901        struct A;
1902
1903        #[derive(Component, Clone, PartialEq, Debug)]
1904        struct B(u8);
1905
1906        let mut world = World::default();
1907        let e = world.spawn((A, B(10))).id();
1908        let e_clone1 = world.spawn_empty().id();
1909        EntityCloner::build_opt_in(&mut world)
1910            .without_required_components(|builder| {
1911                builder.allow::<A>();
1912            })
1913            .allow::<A>()
1914            .clone_entity(e, e_clone1);
1915
1916        assert_eq!(world.get::<B>(e_clone1), Some(&B(10)));
1917
1918        let e_clone2 = world.spawn_empty().id();
1919
1920        EntityCloner::build_opt_in(&mut world)
1921            .allow::<A>()
1922            .without_required_components(|builder| {
1923                builder.allow::<A>();
1924            })
1925            .clone_entity(e, e_clone2);
1926
1927        assert_eq!(world.get::<B>(e_clone2), Some(&B(10)));
1928    }
1929
1930    #[test]
1931    fn clone_required_becoming_explicit() {
1932        #[derive(Component, Clone, PartialEq, Debug)]
1933        #[require(B(5))]
1934        struct A;
1935
1936        #[derive(Component, Clone, PartialEq, Debug)]
1937        struct B(u8);
1938
1939        let mut world = World::default();
1940        let e = world.spawn((A, B(10))).id();
1941        let e_clone1 = world.spawn(B(20)).id();
1942        EntityCloner::build_opt_in(&mut world)
1943            .allow::<A>()
1944            .allow::<B>()
1945            .clone_entity(e, e_clone1);
1946
1947        assert_eq!(world.get::<B>(e_clone1), Some(&B(10)));
1948
1949        let e_clone2 = world.spawn(B(20)).id();
1950        EntityCloner::build_opt_in(&mut world)
1951            .allow::<A>()
1952            .allow::<B>()
1953            .clone_entity(e, e_clone2);
1954
1955        assert_eq!(world.get::<B>(e_clone2), Some(&B(10)));
1956    }
1957
1958    #[test]
1959    fn required_not_cloned_because_requiring_missing() {
1960        #[derive(Component, Clone)]
1961        #[require(B)]
1962        struct A;
1963
1964        #[derive(Component, Clone, Default)]
1965        struct B;
1966
1967        let mut world = World::default();
1968        let e = world.spawn(B).id();
1969        let e_clone1 = world.spawn_empty().id();
1970
1971        EntityCloner::build_opt_in(&mut world)
1972            .allow::<A>()
1973            .clone_entity(e, e_clone1);
1974
1975        assert!(world.get::<B>(e_clone1).is_none());
1976    }
1977
1978    #[test]
1979    fn clone_entity_with_required_components() {
1980        #[derive(Component, Clone, PartialEq, Debug)]
1981        #[require(B)]
1982        struct A;
1983
1984        #[derive(Component, Clone, PartialEq, Debug, Default)]
1985        #[require(C(5))]
1986        struct B;
1987
1988        #[derive(Component, Clone, PartialEq, Debug)]
1989        struct C(u32);
1990
1991        let mut world = World::default();
1992
1993        let e = world.spawn(A).id();
1994        let e_clone = world.spawn_empty().id();
1995
1996        EntityCloner::build_opt_in(&mut world)
1997            .allow::<B>()
1998            .clone_entity(e, e_clone);
1999
2000        assert_eq!(world.entity(e_clone).get::<A>(), None);
2001        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
2002        assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
2003    }
2004
2005    #[test]
2006    fn clone_entity_with_default_required_components() {
2007        #[derive(Component, Clone, PartialEq, Debug)]
2008        #[require(B)]
2009        struct A;
2010
2011        #[derive(Component, Clone, PartialEq, Debug, Default)]
2012        #[require(C(5))]
2013        struct B;
2014
2015        #[derive(Component, Clone, PartialEq, Debug)]
2016        struct C(u32);
2017
2018        let mut world = World::default();
2019
2020        let e = world.spawn((A, C(0))).id();
2021        let e_clone = world.spawn_empty().id();
2022
2023        EntityCloner::build_opt_in(&mut world)
2024            .without_required_components(|builder| {
2025                builder.allow::<A>();
2026            })
2027            .clone_entity(e, e_clone);
2028
2029        assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
2030        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
2031        assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
2032    }
2033
2034    #[test]
2035    fn clone_entity_with_missing_required_components() {
2036        #[derive(Component, Clone, PartialEq, Debug)]
2037        #[require(B)]
2038        struct A;
2039
2040        #[derive(Component, Clone, PartialEq, Debug, Default)]
2041        #[require(C(5))]
2042        struct B;
2043
2044        #[derive(Component, Clone, PartialEq, Debug)]
2045        struct C(u32);
2046
2047        let mut world = World::default();
2048
2049        let e = world.spawn(A).remove::<C>().id();
2050        let e_clone = world.spawn_empty().id();
2051
2052        EntityCloner::build_opt_in(&mut world)
2053            .allow::<A>()
2054            .clone_entity(e, e_clone);
2055
2056        assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
2057        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
2058        assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
2059    }
2060
2061    #[test]
2062    fn skipped_required_components_counter_is_reset_on_early_return() {
2063        #[derive(Component, Clone, PartialEq, Debug, Default)]
2064        #[require(B(5))]
2065        struct A;
2066
2067        #[derive(Component, Clone, PartialEq, Debug)]
2068        struct B(u32);
2069
2070        #[derive(Component, Clone, PartialEq, Debug, Default)]
2071        struct C;
2072
2073        let mut world = World::default();
2074
2075        let e1 = world.spawn(C).id();
2076        let e2 = world.spawn((A, B(0))).id();
2077        let e_clone = world.spawn_empty().id();
2078
2079        let mut builder = EntityCloner::build_opt_in(&mut world);
2080        builder.allow::<(A, C)>();
2081        let mut cloner = builder.finish();
2082        cloner.clone_entity(&mut world, e1, e_clone);
2083        cloner.clone_entity(&mut world, e2, e_clone);
2084
2085        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B(0)));
2086    }
2087
2088    #[test]
2089    fn clone_entity_with_dynamic_components() {
2090        const COMPONENT_SIZE: usize = 10;
2091        fn test_handler(source: &SourceComponent, ctx: &mut ComponentCloneCtx) {
2092            // SAFETY: the passed in ptr corresponds to copy-able data that matches the type of the source / target component
2093            unsafe {
2094                ctx.write_target_component_ptr(source.ptr());
2095            }
2096        }
2097
2098        let mut world = World::default();
2099
2100        let layout = Layout::array::<u8>(COMPONENT_SIZE).unwrap();
2101        // SAFETY:
2102        // - No drop command is required
2103        // - The component will store [u8; COMPONENT_SIZE], which is Send + Sync
2104        let descriptor = unsafe {
2105            ComponentDescriptor::new_with_layout(
2106                "DynamicComp",
2107                StorageType::Table,
2108                layout,
2109                None,
2110                true,
2111                ComponentCloneBehavior::Custom(test_handler),
2112                None,
2113            )
2114        };
2115        let component_id = world.register_component_with_descriptor(descriptor);
2116
2117        let mut entity = world.spawn_empty();
2118        let data = [5u8; COMPONENT_SIZE];
2119
2120        // SAFETY:
2121        // - ptr points to data represented by component_id ([u8; COMPONENT_SIZE])
2122        // - component_id is from the same world as entity
2123        OwningPtr::make(data, |ptr| unsafe {
2124            entity.insert_by_id(component_id, ptr);
2125        });
2126        let entity = entity.id();
2127
2128        let entity_clone = world.spawn_empty().id();
2129        EntityCloner::build_opt_out(&mut world).clone_entity(entity, entity_clone);
2130
2131        let ptr = world.get_by_id(entity, component_id).unwrap();
2132        let clone_ptr = world.get_by_id(entity_clone, component_id).unwrap();
2133        // SAFETY: ptr and clone_ptr store component represented by [u8; COMPONENT_SIZE]
2134        unsafe {
2135            assert_eq!(
2136                core::slice::from_raw_parts(ptr.as_ptr(), COMPONENT_SIZE),
2137                core::slice::from_raw_parts(clone_ptr.as_ptr(), COMPONENT_SIZE),
2138            );
2139        }
2140    }
2141
2142    #[test]
2143    fn recursive_clone() {
2144        let mut world = World::new();
2145        let root = world.spawn_empty().id();
2146        let child1 = world.spawn(ChildOf(root)).id();
2147        let grandchild = world.spawn(ChildOf(child1)).id();
2148        let child2 = world.spawn(ChildOf(root)).id();
2149
2150        let clone_root = world.spawn_empty().id();
2151        EntityCloner::build_opt_out(&mut world)
2152            .linked_cloning(true)
2153            .clone_entity(root, clone_root);
2154
2155        let root_children = world
2156            .entity(clone_root)
2157            .get::<Children>()
2158            .unwrap()
2159            .iter()
2160            .cloned()
2161            .collect::<Vec<_>>();
2162
2163        assert!(root_children.iter().all(|e| *e != child1 && *e != child2));
2164        assert_eq!(root_children.len(), 2);
2165        assert_eq!(
2166            (
2167                world.get::<ChildOf>(root_children[0]),
2168                world.get::<ChildOf>(root_children[1])
2169            ),
2170            (Some(&ChildOf(clone_root)), Some(&ChildOf(clone_root)))
2171        );
2172        let child1_children = world.entity(root_children[0]).get::<Children>().unwrap();
2173        assert_eq!(child1_children.len(), 1);
2174        assert_ne!(child1_children[0], grandchild);
2175        assert!(world.entity(root_children[1]).get::<Children>().is_none());
2176        assert_eq!(
2177            world.get::<ChildOf>(child1_children[0]),
2178            Some(&ChildOf(root_children[0]))
2179        );
2180
2181        assert_eq!(
2182            world.entity(root).get::<Children>().unwrap().deref(),
2183            &[child1, child2]
2184        );
2185    }
2186
2187    #[test]
2188    fn cloning_with_required_components_preserves_existing() {
2189        #[derive(Component, Clone, PartialEq, Debug, Default)]
2190        #[require(B(5))]
2191        struct A;
2192
2193        #[derive(Component, Clone, PartialEq, Debug)]
2194        struct B(u32);
2195
2196        let mut world = World::default();
2197
2198        let e = world.spawn((A, B(0))).id();
2199        let e_clone = world.spawn(B(1)).id();
2200
2201        EntityCloner::build_opt_in(&mut world)
2202            .allow::<A>()
2203            .clone_entity(e, e_clone);
2204
2205        assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
2206        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B(1)));
2207    }
2208
2209    #[test]
2210    fn move_without_clone() {
2211        #[derive(Component, PartialEq, Debug)]
2212        #[component(storage = "SparseSet")]
2213        struct A;
2214
2215        #[derive(Component, PartialEq, Debug)]
2216        struct B(Vec<u8>);
2217
2218        let mut world = World::default();
2219        let e = world.spawn((A, B(alloc::vec![1, 2, 3]))).id();
2220        let e_clone = world.spawn_empty().id();
2221        let mut builder = EntityCloner::build_opt_out(&mut world);
2222        builder.move_components(true);
2223        let mut cloner = builder.finish();
2224
2225        cloner.clone_entity(&mut world, e, e_clone);
2226
2227        assert_eq!(world.get::<A>(e), None);
2228        assert_eq!(world.get::<B>(e), None);
2229
2230        assert_eq!(world.get::<A>(e_clone), Some(&A));
2231        assert_eq!(world.get::<B>(e_clone), Some(&B(alloc::vec![1, 2, 3])));
2232    }
2233
2234    #[test]
2235    fn move_with_remove_hook() {
2236        #[derive(Component, PartialEq, Debug)]
2237        #[component(on_remove=remove_hook)]
2238        struct B(Option<Vec<u8>>);
2239
2240        fn remove_hook(mut world: DeferredWorld, ctx: HookContext) {
2241            world.get_mut::<B>(ctx.entity).unwrap().0.take();
2242        }
2243
2244        let mut world = World::default();
2245        let e = world.spawn(B(Some(alloc::vec![1, 2, 3]))).id();
2246        let e_clone = world.spawn_empty().id();
2247        let mut builder = EntityCloner::build_opt_out(&mut world);
2248        builder.move_components(true);
2249        let mut cloner = builder.finish();
2250
2251        cloner.clone_entity(&mut world, e, e_clone);
2252
2253        assert_eq!(world.get::<B>(e), None);
2254        assert_eq!(world.get::<B>(e_clone), Some(&B(None)));
2255    }
2256
2257    #[test]
2258    fn move_with_deferred() {
2259        #[derive(Component, PartialEq, Debug)]
2260        #[component(clone_behavior=Custom(custom))]
2261        struct A(u32);
2262
2263        #[derive(Component, PartialEq, Debug)]
2264        struct B(u32);
2265
2266        fn custom(_src: &SourceComponent, ctx: &mut ComponentCloneCtx) {
2267            // Clone using deferred
2268            let source = ctx.source();
2269            ctx.queue_deferred(move |world, mapper| {
2270                let target = mapper.get_mapped(source);
2271                world.entity_mut(target).insert(A(10));
2272            });
2273        }
2274
2275        let mut world = World::default();
2276        let e = world.spawn((A(0), B(1))).id();
2277        let e_clone = world.spawn_empty().id();
2278        let mut builder = EntityCloner::build_opt_out(&mut world);
2279        builder.move_components(true);
2280        let mut cloner = builder.finish();
2281
2282        cloner.clone_entity(&mut world, e, e_clone);
2283
2284        assert_eq!(world.get::<A>(e), None);
2285        assert_eq!(world.get::<A>(e_clone), Some(&A(10)));
2286        assert_eq!(world.get::<B>(e), None);
2287        assert_eq!(world.get::<B>(e_clone), Some(&B(1)));
2288    }
2289
2290    #[test]
2291    fn move_relationship() {
2292        #[derive(Component, Clone, PartialEq, Eq, Debug)]
2293        #[relationship(relationship_target=Target)]
2294        struct Source(Entity);
2295
2296        #[derive(Component, Clone, PartialEq, Eq, Debug)]
2297        #[relationship_target(relationship=Source)]
2298        struct Target(Vec<Entity>);
2299
2300        #[derive(Component, PartialEq, Debug)]
2301        struct A(u32);
2302
2303        let mut world = World::default();
2304        let e_target = world.spawn(A(1)).id();
2305        let e_source = world.spawn((A(2), Source(e_target))).id();
2306
2307        let mut builder = EntityCloner::build_opt_out(&mut world);
2308        builder.move_components(true);
2309        let mut cloner = builder.finish();
2310
2311        let e_source_moved = world.spawn_empty().id();
2312
2313        cloner.clone_entity(&mut world, e_source, e_source_moved);
2314
2315        assert_eq!(world.get::<A>(e_source), None);
2316        assert_eq!(world.get::<A>(e_source_moved), Some(&A(2)));
2317        assert_eq!(world.get::<Source>(e_source), None);
2318        assert_eq!(world.get::<Source>(e_source_moved), Some(&Source(e_target)));
2319        assert_eq!(
2320            world.get::<Target>(e_target),
2321            Some(&Target(alloc::vec![e_source_moved]))
2322        );
2323
2324        let e_target_moved = world.spawn_empty().id();
2325
2326        cloner.clone_entity(&mut world, e_target, e_target_moved);
2327
2328        assert_eq!(world.get::<A>(e_target), None);
2329        assert_eq!(world.get::<A>(e_target_moved), Some(&A(1)));
2330        assert_eq!(world.get::<Target>(e_target), None);
2331        assert_eq!(
2332            world.get::<Target>(e_target_moved),
2333            Some(&Target(alloc::vec![e_source_moved]))
2334        );
2335        assert_eq!(
2336            world.get::<Source>(e_source_moved),
2337            Some(&Source(e_target_moved))
2338        );
2339    }
2340
2341    #[test]
2342    fn move_hierarchy() {
2343        #[derive(Component, PartialEq, Debug)]
2344        struct A(u32);
2345
2346        let mut world = World::default();
2347        let e_parent = world.spawn(A(1)).id();
2348        let e_child1 = world.spawn((A(2), ChildOf(e_parent))).id();
2349        let e_child2 = world.spawn((A(3), ChildOf(e_parent))).id();
2350        let e_child1_1 = world.spawn((A(4), ChildOf(e_child1))).id();
2351
2352        let e_parent_clone = world.spawn_empty().id();
2353
2354        let mut builder = EntityCloner::build_opt_out(&mut world);
2355        builder.move_components(true).linked_cloning(true);
2356        let mut cloner = builder.finish();
2357
2358        cloner.clone_entity(&mut world, e_parent, e_parent_clone);
2359
2360        assert_eq!(world.get::<A>(e_parent), None);
2361        assert_eq!(world.get::<A>(e_child1), None);
2362        assert_eq!(world.get::<A>(e_child2), None);
2363        assert_eq!(world.get::<A>(e_child1_1), None);
2364
2365        let mut children = world.get::<Children>(e_parent_clone).unwrap().iter();
2366        let e_child1_clone = *children.next().unwrap();
2367        let e_child2_clone = *children.next().unwrap();
2368        let mut children = world.get::<Children>(e_child1_clone).unwrap().iter();
2369        let e_child1_1_clone = *children.next().unwrap();
2370
2371        assert_eq!(world.get::<A>(e_parent_clone), Some(&A(1)));
2372        assert_eq!(world.get::<A>(e_child1_clone), Some(&A(2)));
2373        assert_eq!(
2374            world.get::<ChildOf>(e_child1_clone),
2375            Some(&ChildOf(e_parent_clone))
2376        );
2377        assert_eq!(world.get::<A>(e_child2_clone), Some(&A(3)));
2378        assert_eq!(
2379            world.get::<ChildOf>(e_child2_clone),
2380            Some(&ChildOf(e_parent_clone))
2381        );
2382        assert_eq!(world.get::<A>(e_child1_1_clone), Some(&A(4)));
2383        assert_eq!(
2384            world.get::<ChildOf>(e_child1_1_clone),
2385            Some(&ChildOf(e_child1_clone))
2386        );
2387    }
2388
2389    // Original: E1 Target{target: [E2], data: [4,5,6]}
2390    //            | E2 Source{target: E1, data: [1,2,3]}
2391    //
2392    // Cloned:   E3 Target{target: [], data: [4,5,6]}
2393    #[test]
2394    fn clone_relationship_with_data() {
2395        #[derive(Component, Clone)]
2396        #[relationship(relationship_target=Target)]
2397        struct Source {
2398            #[relationship]
2399            target: Entity,
2400            data: Vec<u8>,
2401        }
2402
2403        #[derive(Component, Clone)]
2404        #[relationship_target(relationship=Source)]
2405        struct Target {
2406            #[relationship]
2407            target: Vec<Entity>,
2408            data: Vec<u8>,
2409        }
2410
2411        let mut world = World::default();
2412        let e_target = world.spawn_empty().id();
2413        let e_source = world
2414            .spawn(Source {
2415                target: e_target,
2416                data: alloc::vec![1, 2, 3],
2417            })
2418            .id();
2419        world.get_mut::<Target>(e_target).unwrap().data = alloc::vec![4, 5, 6];
2420
2421        let builder = EntityCloner::build_opt_out(&mut world);
2422        let mut cloner = builder.finish();
2423
2424        let e_target_clone = world.spawn_empty().id();
2425        cloner.clone_entity(&mut world, e_target, e_target_clone);
2426
2427        let target = world.get::<Target>(e_target).unwrap();
2428        let cloned_target = world.get::<Target>(e_target_clone).unwrap();
2429
2430        assert_eq!(cloned_target.data, target.data);
2431        assert_eq!(target.target, alloc::vec![e_source]);
2432        assert_eq!(cloned_target.target.len(), 0);
2433
2434        let source = world.get::<Source>(e_source).unwrap();
2435
2436        assert_eq!(source.data, alloc::vec![1, 2, 3]);
2437    }
2438
2439    // Original: E1 Target{target: [E2], data: [4,5,6]}
2440    //            | E2 Source{target: E1, data: [1,2,3]}
2441    //
2442    // Cloned:   E3 Target{target: [E4], data: [4,5,6]}
2443    //            | E4 Source{target: E3, data: [1,2,3]}
2444    #[test]
2445    fn clone_linked_relationship_with_data() {
2446        #[derive(Component, Clone)]
2447        #[relationship(relationship_target=Target)]
2448        struct Source {
2449            #[relationship]
2450            target: Entity,
2451            data: Vec<u8>,
2452        }
2453
2454        #[derive(Component, Clone)]
2455        #[relationship_target(relationship=Source, linked_spawn)]
2456        struct Target {
2457            #[relationship]
2458            target: Vec<Entity>,
2459            data: Vec<u8>,
2460        }
2461
2462        let mut world = World::default();
2463        let e_target = world.spawn_empty().id();
2464        let e_source = world
2465            .spawn(Source {
2466                target: e_target,
2467                data: alloc::vec![1, 2, 3],
2468            })
2469            .id();
2470        world.get_mut::<Target>(e_target).unwrap().data = alloc::vec![4, 5, 6];
2471
2472        let mut builder = EntityCloner::build_opt_out(&mut world);
2473        builder.linked_cloning(true);
2474        let mut cloner = builder.finish();
2475
2476        let e_target_clone = world.spawn_empty().id();
2477        cloner.clone_entity(&mut world, e_target, e_target_clone);
2478
2479        let target = world.get::<Target>(e_target).unwrap();
2480        let cloned_target = world.get::<Target>(e_target_clone).unwrap();
2481
2482        assert_eq!(cloned_target.data, target.data);
2483        assert_eq!(target.target, alloc::vec![e_source]);
2484        assert_eq!(cloned_target.target.len(), 1);
2485
2486        let source = world.get::<Source>(e_source).unwrap();
2487        let cloned_source = world.get::<Source>(cloned_target.target[0]).unwrap();
2488
2489        assert_eq!(cloned_source.data, source.data);
2490        assert_eq!(source.target, e_target);
2491        assert_eq!(cloned_source.target, e_target_clone);
2492    }
2493
2494    // Original: E1
2495    //           E2
2496    //
2497    // Moved:    E3 Target{target: [], data: [4,5,6]}
2498    #[test]
2499    fn move_relationship_with_data() {
2500        #[derive(Component, Clone, PartialEq, Eq, Debug)]
2501        #[relationship(relationship_target=Target)]
2502        struct Source {
2503            #[relationship]
2504            target: Entity,
2505            data: Vec<u8>,
2506        }
2507
2508        #[derive(Component, Clone, PartialEq, Eq, Debug)]
2509        #[relationship_target(relationship=Source)]
2510        struct Target {
2511            #[relationship]
2512            target: Vec<Entity>,
2513            data: Vec<u8>,
2514        }
2515
2516        let source_data = alloc::vec![1, 2, 3];
2517        let target_data = alloc::vec![4, 5, 6];
2518
2519        let mut world = World::default();
2520        let e_target = world.spawn_empty().id();
2521        let e_source = world
2522            .spawn(Source {
2523                target: e_target,
2524                data: source_data.clone(),
2525            })
2526            .id();
2527        world.get_mut::<Target>(e_target).unwrap().data = target_data.clone();
2528
2529        let mut builder = EntityCloner::build_opt_out(&mut world);
2530        builder.move_components(true);
2531        let mut cloner = builder.finish();
2532
2533        let e_target_moved = world.spawn_empty().id();
2534        cloner.clone_entity(&mut world, e_target, e_target_moved);
2535
2536        assert_eq!(world.get::<Target>(e_target), None);
2537        assert_eq!(
2538            world.get::<Source>(e_source),
2539            Some(&Source {
2540                data: source_data,
2541                target: e_target_moved,
2542            })
2543        );
2544        assert_eq!(
2545            world.get::<Target>(e_target_moved),
2546            Some(&Target {
2547                target: alloc::vec![e_source],
2548                data: target_data
2549            })
2550        );
2551    }
2552
2553    // Original: E1
2554    //           E2
2555    //
2556    // Moved:    E3 Target{target: [E4], data: [4,5,6]}
2557    //            | E4 Source{target: E3, data: [1,2,3]}
2558    #[test]
2559    fn move_linked_relationship_with_data() {
2560        #[derive(Component, Clone, PartialEq, Eq, Debug)]
2561        #[relationship(relationship_target=Target)]
2562        struct Source {
2563            #[relationship]
2564            target: Entity,
2565            data: Vec<u8>,
2566        }
2567
2568        #[derive(Component, Clone, PartialEq, Eq, Debug)]
2569        #[relationship_target(relationship=Source, linked_spawn)]
2570        struct Target {
2571            #[relationship]
2572            target: Vec<Entity>,
2573            data: Vec<u8>,
2574        }
2575
2576        let source_data = alloc::vec![1, 2, 3];
2577        let target_data = alloc::vec![4, 5, 6];
2578
2579        let mut world = World::default();
2580        let e_target = world.spawn_empty().id();
2581        let e_source = world
2582            .spawn(Source {
2583                target: e_target,
2584                data: source_data.clone(),
2585            })
2586            .id();
2587        world.get_mut::<Target>(e_target).unwrap().data = target_data.clone();
2588
2589        let mut builder = EntityCloner::build_opt_out(&mut world);
2590        builder.move_components(true).linked_cloning(true);
2591        let mut cloner = builder.finish();
2592
2593        let e_target_moved = world.spawn_empty().id();
2594        cloner.clone_entity(&mut world, e_target, e_target_moved);
2595
2596        assert_eq!(world.get::<Target>(e_target), None);
2597        assert_eq!(world.get::<Source>(e_source), None);
2598
2599        let moved_target = world.get::<Target>(e_target_moved).unwrap();
2600        assert_eq!(moved_target.data, target_data);
2601        assert_eq!(moved_target.target.len(), 1);
2602
2603        let moved_source = world.get::<Source>(moved_target.target[0]).unwrap();
2604        assert_eq!(moved_source.data, source_data);
2605        assert_eq!(moved_source.target, e_target_moved);
2606    }
2607}