Skip to main content

bevy_ecs/entity/
clone_entities.rs

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