bevy_ecs/entity/
clone_entities.rs

1use alloc::{borrow::ToOwned, boxed::Box, collections::VecDeque, vec::Vec};
2use bevy_platform::collections::{HashMap, HashSet};
3use bevy_ptr::{Ptr, PtrMut};
4use bumpalo::Bump;
5use core::any::TypeId;
6
7use crate::{
8    bundle::Bundle,
9    component::{Component, ComponentCloneBehavior, ComponentCloneFn, ComponentId, ComponentInfo},
10    entity::{hash_map::EntityHashMap, Entities, Entity, EntityMapper},
11    query::DebugCheckedUnwrap,
12    relationship::RelationshipHookMode,
13    world::World,
14};
15
16/// Provides read access to the source component (the component being cloned) in a [`ComponentCloneFn`].
17pub struct SourceComponent<'a> {
18    ptr: Ptr<'a>,
19    info: &'a ComponentInfo,
20}
21
22impl<'a> SourceComponent<'a> {
23    /// Returns a reference to the component on the source entity.
24    ///
25    /// Will return `None` if `ComponentId` of requested component does not match `ComponentId` of source component
26    pub fn read<C: Component>(&self) -> Option<&C> {
27        if self
28            .info
29            .type_id()
30            .is_some_and(|id| id == TypeId::of::<C>())
31        {
32            // SAFETY:
33            // - Components and ComponentId are from the same world
34            // - source_component_ptr holds valid data of the type referenced by ComponentId
35            unsafe { Some(self.ptr.deref::<C>()) }
36        } else {
37            None
38        }
39    }
40
41    /// Returns the "raw" pointer to the source component.
42    pub fn ptr(&self) -> Ptr<'a> {
43        self.ptr
44    }
45
46    /// Returns a reference to the component on the source entity as [`&dyn Reflect`](bevy_reflect::Reflect).
47    ///
48    /// Will return `None` if:
49    /// - World does not have [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`).
50    /// - Component does not implement [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr).
51    /// - Component is not registered.
52    /// - Component does not have [`TypeId`]
53    /// - Registered [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr)'s [`TypeId`] does not match component's [`TypeId`]
54    #[cfg(feature = "bevy_reflect")]
55    pub fn read_reflect(
56        &self,
57        registry: &bevy_reflect::TypeRegistry,
58    ) -> Option<&dyn bevy_reflect::Reflect> {
59        let type_id = self.info.type_id()?;
60        let reflect_from_ptr = registry.get_type_data::<bevy_reflect::ReflectFromPtr>(type_id)?;
61        if reflect_from_ptr.type_id() != type_id {
62            return None;
63        }
64        // SAFETY: `source_component_ptr` stores data represented by `component_id`, which we used to get `ReflectFromPtr`.
65        unsafe { Some(reflect_from_ptr.as_reflect(self.ptr)) }
66    }
67}
68
69/// Context for component clone handlers.
70///
71/// Provides fast access to useful resources like [`AppTypeRegistry`](crate::reflect::AppTypeRegistry)
72/// and allows component clone handler to get information about component being cloned.
73pub struct ComponentCloneCtx<'a, 'b> {
74    component_id: ComponentId,
75    target_component_written: bool,
76    bundle_scratch: &'a mut BundleScratch<'b>,
77    bundle_scratch_allocator: &'b Bump,
78    entities: &'a Entities,
79    source: Entity,
80    target: Entity,
81    component_info: &'a ComponentInfo,
82    entity_cloner: &'a mut EntityCloner,
83    mapper: &'a mut dyn EntityMapper,
84    #[cfg(feature = "bevy_reflect")]
85    type_registry: Option<&'a crate::reflect::AppTypeRegistry>,
86    #[cfg(not(feature = "bevy_reflect"))]
87    #[expect(dead_code)]
88    type_registry: Option<&'a ()>,
89}
90
91impl<'a, 'b> ComponentCloneCtx<'a, 'b> {
92    /// Create a new instance of `ComponentCloneCtx` that can be passed to component clone handlers.
93    ///
94    /// # Safety
95    /// Caller must ensure that:
96    /// - `component_info` corresponds to the `component_id` in the same world,.
97    /// - `source_component_ptr` points to a valid component of type represented by `component_id`.
98    unsafe fn new(
99        component_id: ComponentId,
100        source: Entity,
101        target: Entity,
102        bundle_scratch_allocator: &'b Bump,
103        bundle_scratch: &'a mut BundleScratch<'b>,
104        entities: &'a Entities,
105        component_info: &'a ComponentInfo,
106        entity_cloner: &'a mut EntityCloner,
107        mapper: &'a mut dyn EntityMapper,
108        #[cfg(feature = "bevy_reflect")] type_registry: Option<&'a crate::reflect::AppTypeRegistry>,
109        #[cfg(not(feature = "bevy_reflect"))] type_registry: Option<&'a ()>,
110    ) -> Self {
111        Self {
112            component_id,
113            source,
114            target,
115            bundle_scratch,
116            target_component_written: false,
117            bundle_scratch_allocator,
118            entities,
119            mapper,
120            component_info,
121            entity_cloner,
122            type_registry,
123        }
124    }
125
126    /// Returns true if [`write_target_component`](`Self::write_target_component`) was called before.
127    pub fn target_component_written(&self) -> bool {
128        self.target_component_written
129    }
130
131    /// Returns the current source entity.
132    pub fn source(&self) -> Entity {
133        self.source
134    }
135
136    /// Returns the current target entity.
137    pub fn target(&self) -> Entity {
138        self.target
139    }
140
141    /// Returns the [`ComponentId`] of the component being cloned.
142    pub fn component_id(&self) -> ComponentId {
143        self.component_id
144    }
145
146    /// Returns the [`ComponentInfo`] of the component being cloned.
147    pub fn component_info(&self) -> &ComponentInfo {
148        self.component_info
149    }
150
151    /// Returns true if the [`EntityCloner`] is configured to recursively clone entities. When this is enabled,
152    /// entities stored in a cloned entity's [`RelationshipTarget`](crate::relationship::RelationshipTarget) component with
153    /// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN) will also be cloned.
154    #[inline]
155    pub fn linked_cloning(&self) -> bool {
156        self.entity_cloner.linked_cloning
157    }
158
159    /// Returns this context's [`EntityMapper`].
160    pub fn entity_mapper(&mut self) -> &mut dyn EntityMapper {
161        self.mapper
162    }
163
164    /// Writes component data to target entity.
165    ///
166    /// # Panics
167    /// This will panic if:
168    /// - Component has already been written once.
169    /// - Component being written is not registered in the world.
170    /// - `ComponentId` of component being written does not match expected `ComponentId`.
171    pub fn write_target_component<C: Component>(&mut self, mut component: C) {
172        C::map_entities(&mut component, &mut self.mapper);
173        let short_name = disqualified::ShortName::of::<C>();
174        if self.target_component_written {
175            panic!("Trying to write component '{short_name}' multiple times")
176        }
177        if self
178            .component_info
179            .type_id()
180            .is_none_or(|id| id != TypeId::of::<C>())
181        {
182            panic!("TypeId of component '{short_name}' does not match source component TypeId")
183        };
184        // SAFETY: the TypeId of self.component_id has been checked to ensure it matches `C`
185        unsafe {
186            self.bundle_scratch
187                .push(self.bundle_scratch_allocator, self.component_id, component);
188        };
189        self.target_component_written = true;
190    }
191
192    /// Writes component data to target entity by providing a pointer to source component data.
193    ///
194    /// # Safety
195    /// Caller must ensure that the passed in `ptr` references data that corresponds to the type of the source / target [`ComponentId`].
196    /// `ptr` must also contain data that the written component can "own" (for example, this should not directly copy non-Copy data).
197    ///
198    /// # Panics
199    /// This will panic if component has already been written once.
200    pub unsafe fn write_target_component_ptr(&mut self, ptr: Ptr) {
201        if self.target_component_written {
202            panic!("Trying to write component multiple times")
203        }
204        let layout = self.component_info.layout();
205        let target_ptr = self.bundle_scratch_allocator.alloc_layout(layout);
206        core::ptr::copy_nonoverlapping(ptr.as_ptr(), target_ptr.as_ptr(), layout.size());
207        self.bundle_scratch
208            .push_ptr(self.component_id, PtrMut::new(target_ptr));
209        self.target_component_written = true;
210    }
211
212    /// Writes component data to target entity.
213    ///
214    /// # Panics
215    /// This will panic if:
216    /// - World does not have [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`).
217    /// - Component does not implement [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr).
218    /// - Source component does not have [`TypeId`].
219    /// - Passed component's [`TypeId`] does not match source component [`TypeId`].
220    /// - Component has already been written once.
221    #[cfg(feature = "bevy_reflect")]
222    pub fn write_target_component_reflect(&mut self, component: Box<dyn bevy_reflect::Reflect>) {
223        if self.target_component_written {
224            panic!("Trying to write component multiple times")
225        }
226        let source_type_id = self
227            .component_info
228            .type_id()
229            .expect("Source component must have TypeId");
230        let component_type_id = component.type_id();
231        if source_type_id != component_type_id {
232            panic!("Passed component TypeId does not match source component TypeId")
233        }
234        let component_layout = self.component_info.layout();
235
236        let component_data_ptr = Box::into_raw(component).cast::<u8>();
237        let target_component_data_ptr =
238            self.bundle_scratch_allocator.alloc_layout(component_layout);
239        // SAFETY:
240        // - target_component_data_ptr and component_data have the same data type.
241        // - component_data_ptr has layout of component_layout
242        unsafe {
243            core::ptr::copy_nonoverlapping(
244                component_data_ptr,
245                target_component_data_ptr.as_ptr(),
246                component_layout.size(),
247            );
248            self.bundle_scratch
249                .push_ptr(self.component_id, PtrMut::new(target_component_data_ptr));
250
251            if component_layout.size() > 0 {
252                // Ensure we don't attempt to deallocate zero-sized components
253                alloc::alloc::dealloc(component_data_ptr, component_layout);
254            }
255        }
256
257        self.target_component_written = true;
258    }
259
260    /// Returns [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`) if it exists in the world.
261    ///
262    /// NOTE: Prefer this method instead of manually reading the resource from the world.
263    #[cfg(feature = "bevy_reflect")]
264    pub fn type_registry(&self) -> Option<&crate::reflect::AppTypeRegistry> {
265        self.type_registry
266    }
267
268    /// Queues the `entity` to be cloned by the current [`EntityCloner`]
269    pub fn queue_entity_clone(&mut self, entity: Entity) {
270        let target = self.entities.reserve_entity();
271        self.mapper.set_mapped(entity, target);
272        self.entity_cloner.clone_queue.push_back(entity);
273    }
274
275    /// Queues a deferred clone operation, which will run with exclusive [`World`] access immediately after calling the clone handler for each component on an entity.
276    /// This exists, despite its similarity to [`Commands`](crate::system::Commands), to provide access to the entity mapper in the current context.
277    pub fn queue_deferred(
278        &mut self,
279        deferred: impl FnOnce(&mut World, &mut dyn EntityMapper) + 'static,
280    ) {
281        self.entity_cloner
282            .deferred_commands
283            .push_back(Box::new(deferred));
284    }
285}
286
287/// A configuration determining how to clone entities. This can be built using [`EntityCloner::build`], which
288/// returns an [`EntityClonerBuilder`].
289///
290/// After configuration is complete an entity can be cloned using [`Self::clone_entity`].
291///
292///```
293/// use bevy_ecs::prelude::*;
294/// use bevy_ecs::entity::EntityCloner;
295///
296/// #[derive(Component, Clone, PartialEq, Eq)]
297/// struct A {
298///     field: usize,
299/// }
300///
301/// let mut world = World::default();
302///
303/// let component = A { field: 5 };
304///
305/// let entity = world.spawn(component.clone()).id();
306/// let entity_clone = world.spawn_empty().id();
307///
308/// EntityCloner::build(&mut world).clone_entity(entity, entity_clone);
309///
310/// assert!(world.get::<A>(entity_clone).is_some_and(|c| *c == component));
311///```
312///
313/// # Default cloning strategy
314/// By default, all types that derive [`Component`] and implement either [`Clone`] or `Reflect` (with `ReflectComponent`) will be cloned
315/// (with `Clone`-based implementation preferred in case component implements both).
316///
317/// It should be noted that if `Component` is implemented manually or if `Clone` implementation is conditional
318/// (like when deriving `Clone` for a type with a generic parameter without `Clone` bound),
319/// the component will be cloned using the [default cloning strategy](crate::component::ComponentCloneBehavior::global_default_fn).
320/// To use `Clone`-based handler ([`ComponentCloneBehavior::clone`]) in this case it should be set manually using one
321/// of the methods mentioned in the [Clone Behaviors](#Clone-Behaviors) section
322///
323/// Here's an example of how to do it using [`clone_behavior`](Component::clone_behavior):
324/// ```
325/// # use bevy_ecs::prelude::*;
326/// # use bevy_ecs::component::{StorageType, ComponentCloneBehavior, Mutable};
327/// #[derive(Clone)]
328/// struct SomeComponent;
329///
330/// impl Component for SomeComponent {
331///     const STORAGE_TYPE: StorageType = StorageType::Table;
332///     type Mutability = Mutable;
333///     fn clone_behavior() -> ComponentCloneBehavior {
334///         ComponentCloneBehavior::clone::<Self>()
335///     }
336/// }
337/// ```
338///
339/// # Clone Behaviors
340/// [`EntityCloner`] clones entities by cloning components using [`ComponentCloneBehavior`], and there are multiple layers
341/// to decide which handler to use for which component. The overall hierarchy looks like this (priority from most to least):
342/// 1. local overrides using [`EntityClonerBuilder::override_clone_behavior`]
343/// 2. component-defined handler using [`Component::clone_behavior`]
344/// 3. default handler override using [`EntityClonerBuilder::with_default_clone_fn`].
345/// 4. reflect-based or noop default clone handler depending on if `bevy_reflect` feature is enabled or not.
346pub struct EntityCloner {
347    filter_allows_components: bool,
348    filter: HashSet<ComponentId>,
349    clone_behavior_overrides: HashMap<ComponentId, ComponentCloneBehavior>,
350    move_components: bool,
351    linked_cloning: bool,
352    default_clone_fn: ComponentCloneFn,
353    clone_queue: VecDeque<Entity>,
354    deferred_commands: VecDeque<Box<dyn FnOnce(&mut World, &mut dyn EntityMapper)>>,
355}
356
357impl Default for EntityCloner {
358    fn default() -> Self {
359        Self {
360            filter_allows_components: false,
361            move_components: false,
362            linked_cloning: false,
363            default_clone_fn: ComponentCloneBehavior::global_default_fn(),
364            filter: Default::default(),
365            clone_behavior_overrides: Default::default(),
366            clone_queue: Default::default(),
367            deferred_commands: Default::default(),
368        }
369    }
370}
371
372/// An expandable scratch space for defining a dynamic bundle.
373struct BundleScratch<'a> {
374    component_ids: Vec<ComponentId>,
375    component_ptrs: Vec<PtrMut<'a>>,
376}
377
378impl<'a> BundleScratch<'a> {
379    pub(crate) fn with_capacity(capacity: usize) -> Self {
380        Self {
381            component_ids: Vec::with_capacity(capacity),
382            component_ptrs: Vec::with_capacity(capacity),
383        }
384    }
385
386    /// Pushes the `ptr` component onto this storage with the given `id` [`ComponentId`].
387    ///
388    /// # Safety
389    /// The `id` [`ComponentId`] must match the component `ptr` for whatever [`World`] this scratch will
390    /// be written to. `ptr` must contain valid uniquely-owned data that matches the type of component referenced
391    /// in `id`.
392    pub(crate) unsafe fn push_ptr(&mut self, id: ComponentId, ptr: PtrMut<'a>) {
393        self.component_ids.push(id);
394        self.component_ptrs.push(ptr);
395    }
396
397    /// Pushes the `C` component onto this storage with the given `id` [`ComponentId`], using the given `bump` allocator.
398    ///
399    /// # Safety
400    /// The `id` [`ComponentId`] must match the component `C` for whatever [`World`] this scratch will
401    /// be written to.
402    pub(crate) unsafe fn push<C: Component>(
403        &mut self,
404        allocator: &'a Bump,
405        id: ComponentId,
406        component: C,
407    ) {
408        let component_ref = allocator.alloc(component);
409        self.component_ids.push(id);
410        self.component_ptrs.push(PtrMut::from(component_ref));
411    }
412
413    /// Writes the scratch components to the given entity in the given world.
414    ///
415    /// # Safety
416    /// All [`ComponentId`] values in this instance must come from `world`.
417    pub(crate) unsafe fn write(
418        self,
419        world: &mut World,
420        entity: Entity,
421        relationship_hook_insert_mode: RelationshipHookMode,
422    ) {
423        // SAFETY:
424        // - All `component_ids` are from the same world as `target` entity
425        // - All `component_data_ptrs` are valid types represented by `component_ids`
426        unsafe {
427            world.entity_mut(entity).insert_by_ids_internal(
428                &self.component_ids,
429                self.component_ptrs.into_iter().map(|ptr| ptr.promote()),
430                relationship_hook_insert_mode,
431            );
432        }
433    }
434}
435
436impl EntityCloner {
437    /// Returns a new [`EntityClonerBuilder`] using the given `world`.
438    pub fn build(world: &mut World) -> EntityClonerBuilder {
439        EntityClonerBuilder {
440            world,
441            attach_required_components: true,
442            entity_cloner: EntityCloner::default(),
443        }
444    }
445
446    /// Returns `true` if this cloner is configured to clone entities referenced in cloned components via [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN).
447    /// This will produce "deep" / recursive clones of relationship trees that have "linked spawn".
448    #[inline]
449    pub fn linked_cloning(&self) -> bool {
450        self.linked_cloning
451    }
452
453    /// Clones and inserts components from the `source` entity into the entity mapped by `mapper` from `source` using the stored configuration.
454    fn clone_entity_internal(
455        &mut self,
456        world: &mut World,
457        source: Entity,
458        mapper: &mut dyn EntityMapper,
459        relationship_hook_insert_mode: RelationshipHookMode,
460    ) -> Entity {
461        let target = mapper.get_mapped(source);
462        // PERF: reusing allocated space across clones would be more efficient. Consider an allocation model similar to `Commands`.
463        let bundle_scratch_allocator = Bump::new();
464        let mut bundle_scratch: BundleScratch;
465        {
466            let world = world.as_unsafe_world_cell();
467            let source_entity = world.get_entity(source).expect("Source entity must exist");
468
469            #[cfg(feature = "bevy_reflect")]
470            // SAFETY: we have unique access to `world`, nothing else accesses the registry at this moment, and we clone
471            // the registry, which prevents future conflicts.
472            let app_registry = unsafe {
473                world
474                    .get_resource::<crate::reflect::AppTypeRegistry>()
475                    .cloned()
476            };
477            #[cfg(not(feature = "bevy_reflect"))]
478            let app_registry = Option::<()>::None;
479
480            let archetype = source_entity.archetype();
481            bundle_scratch = BundleScratch::with_capacity(archetype.component_count());
482
483            for component in archetype.components() {
484                if !self.is_cloning_allowed(&component) {
485                    continue;
486                }
487
488                let handler = match self.clone_behavior_overrides.get(&component) {
489                    Some(clone_behavior) => clone_behavior.resolve(self.default_clone_fn),
490                    None => world
491                        .components()
492                        .get_info(component)
493                        .map(|info| info.clone_behavior().resolve(self.default_clone_fn))
494                        .unwrap_or(self.default_clone_fn),
495                };
496
497                // SAFETY: This component exists because it is present on the archetype.
498                let info = unsafe { world.components().get_info_unchecked(component) };
499
500                // SAFETY:
501                // - There are no other mutable references to source entity.
502                // - `component` is from `source_entity`'s archetype
503                let source_component_ptr =
504                    unsafe { source_entity.get_by_id(component).debug_checked_unwrap() };
505
506                let source_component = SourceComponent {
507                    info,
508                    ptr: source_component_ptr,
509                };
510
511                // SAFETY:
512                // - `components` and `component` are from the same world
513                // - `source_component_ptr` is valid and points to the same type as represented by `component`
514                let mut ctx = unsafe {
515                    ComponentCloneCtx::new(
516                        component,
517                        source,
518                        target,
519                        &bundle_scratch_allocator,
520                        &mut bundle_scratch,
521                        world.entities(),
522                        info,
523                        self,
524                        mapper,
525                        app_registry.as_ref(),
526                    )
527                };
528
529                (handler)(&source_component, &mut ctx);
530            }
531        }
532
533        world.flush();
534
535        for deferred in self.deferred_commands.drain(..) {
536            (deferred)(world, mapper);
537        }
538
539        if !world.entities.contains(target) {
540            panic!("Target entity does not exist");
541        }
542
543        if self.move_components {
544            world
545                .entity_mut(source)
546                .remove_by_ids(&bundle_scratch.component_ids);
547        }
548
549        // SAFETY:
550        // - All `component_ids` are from the same world as `target` entity
551        // - All `component_data_ptrs` are valid types represented by `component_ids`
552        unsafe { bundle_scratch.write(world, target, relationship_hook_insert_mode) };
553        target
554    }
555
556    /// Clones and inserts components from the `source` entity into `target` entity using the stored configuration.
557    /// If this [`EntityCloner`] has [`EntityCloner::linked_cloning`], then it will recursively spawn entities as defined
558    /// by [`RelationshipTarget`](crate::relationship::RelationshipTarget) components with
559    /// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN)
560    #[track_caller]
561    pub fn clone_entity(&mut self, world: &mut World, source: Entity, target: Entity) {
562        let mut map = EntityHashMap::<Entity>::new();
563        map.set_mapped(source, target);
564        self.clone_entity_mapped(world, source, &mut map);
565    }
566
567    /// Clones and inserts components from the `source` entity into a newly spawned entity using the stored configuration.
568    /// If this [`EntityCloner`] has [`EntityCloner::linked_cloning`], then it will recursively spawn entities as defined
569    /// by [`RelationshipTarget`](crate::relationship::RelationshipTarget) components with
570    /// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN)
571    #[track_caller]
572    pub fn spawn_clone(&mut self, world: &mut World, source: Entity) -> Entity {
573        let target = world.spawn_empty().id();
574        self.clone_entity(world, source, target);
575        target
576    }
577
578    /// Clones the entity into whatever entity `mapper` chooses for it.
579    #[track_caller]
580    pub fn clone_entity_mapped(
581        &mut self,
582        world: &mut World,
583        source: Entity,
584        mapper: &mut dyn EntityMapper,
585    ) -> Entity {
586        // All relationships on the root should have their hooks run
587        let target = self.clone_entity_internal(world, source, mapper, RelationshipHookMode::Run);
588        let child_hook_insert_mode = if self.linked_cloning {
589            // When spawning "linked relationships", we want to ignore hooks for relationships we are spawning, while
590            // still registering with original relationship targets that are "not linked" to the current recursive spawn.
591            RelationshipHookMode::RunIfNotLinked
592        } else {
593            // If we are not cloning "linked relationships" recursively, then we want any cloned relationship components to
594            // register themselves with their original relationship target.
595            RelationshipHookMode::Run
596        };
597        loop {
598            let queued = self.clone_queue.pop_front();
599            if let Some(queued) = queued {
600                self.clone_entity_internal(world, queued, mapper, child_hook_insert_mode);
601            } else {
602                break;
603            }
604        }
605        target
606    }
607
608    fn is_cloning_allowed(&self, component: &ComponentId) -> bool {
609        (self.filter_allows_components && self.filter.contains(component))
610            || (!self.filter_allows_components && !self.filter.contains(component))
611    }
612}
613
614/// A builder for configuring [`EntityCloner`]. See [`EntityCloner`] for more information.
615pub struct EntityClonerBuilder<'w> {
616    world: &'w mut World,
617    entity_cloner: EntityCloner,
618    attach_required_components: bool,
619}
620
621impl<'w> EntityClonerBuilder<'w> {
622    /// Internally calls [`EntityCloner::clone_entity`] on the builder's [`World`].
623    pub fn clone_entity(&mut self, source: Entity, target: Entity) -> &mut Self {
624        self.entity_cloner.clone_entity(self.world, source, target);
625        self
626    }
627    /// Finishes configuring [`EntityCloner`] returns it.
628    pub fn finish(self) -> EntityCloner {
629        self.entity_cloner
630    }
631
632    /// By default, any components allowed/denied through the filter will automatically
633    /// allow/deny all of their required components.
634    ///
635    /// This method allows for a scoped mode where any changes to the filter
636    /// will not involve required components.
637    pub fn without_required_components(
638        &mut self,
639        builder: impl FnOnce(&mut EntityClonerBuilder),
640    ) -> &mut Self {
641        self.attach_required_components = false;
642        builder(self);
643        self.attach_required_components = true;
644        self
645    }
646
647    /// Sets the default clone function to use.
648    pub fn with_default_clone_fn(&mut self, clone_fn: ComponentCloneFn) -> &mut Self {
649        self.entity_cloner.default_clone_fn = clone_fn;
650        self
651    }
652
653    /// Sets whether the cloner should remove any components that were cloned,
654    /// effectively moving them from the source entity to the target.
655    ///
656    /// This is disabled by default.
657    ///
658    /// The setting only applies to components that are allowed through the filter
659    /// at the time [`EntityClonerBuilder::clone_entity`] is called.
660    pub fn move_components(&mut self, enable: bool) -> &mut Self {
661        self.entity_cloner.move_components = enable;
662        self
663    }
664
665    /// Adds all components of the bundle to the list of components to clone.
666    ///
667    /// Note that all components are allowed by default, to clone only explicitly allowed components make sure to call
668    /// [`deny_all`](`Self::deny_all`) before calling any of the `allow` methods.
669    pub fn allow<T: Bundle>(&mut self) -> &mut Self {
670        let bundle = self.world.register_bundle::<T>();
671        let ids = bundle.explicit_components().to_owned();
672        for id in ids {
673            self.filter_allow(id);
674        }
675        self
676    }
677
678    /// Extends the list of components to clone.
679    ///
680    /// Note that all components are allowed by default, to clone only explicitly allowed components make sure to call
681    /// [`deny_all`](`Self::deny_all`) before calling any of the `allow` methods.
682    pub fn allow_by_ids(&mut self, ids: impl IntoIterator<Item = ComponentId>) -> &mut Self {
683        for id in ids {
684            self.filter_allow(id);
685        }
686        self
687    }
688
689    /// Extends the list of components to clone using [`TypeId`]s.
690    ///
691    /// Note that all components are allowed by default, to clone only explicitly allowed components make sure to call
692    /// [`deny_all`](`Self::deny_all`) before calling any of the `allow` methods.
693    pub fn allow_by_type_ids(&mut self, ids: impl IntoIterator<Item = TypeId>) -> &mut Self {
694        for type_id in ids {
695            if let Some(id) = self.world.components().get_id(type_id) {
696                self.filter_allow(id);
697            }
698        }
699        self
700    }
701
702    /// Resets the filter to allow all components to be cloned.
703    pub fn allow_all(&mut self) -> &mut Self {
704        self.entity_cloner.filter_allows_components = false;
705        self.entity_cloner.filter.clear();
706        self
707    }
708
709    /// Disallows all components of the bundle from being cloned.
710    pub fn deny<T: Bundle>(&mut self) -> &mut Self {
711        let bundle = self.world.register_bundle::<T>();
712        let ids = bundle.explicit_components().to_owned();
713        for id in ids {
714            self.filter_deny(id);
715        }
716        self
717    }
718
719    /// Extends the list of components that shouldn't be cloned.
720    pub fn deny_by_ids(&mut self, ids: impl IntoIterator<Item = ComponentId>) -> &mut Self {
721        for id in ids {
722            self.filter_deny(id);
723        }
724        self
725    }
726
727    /// Extends the list of components that shouldn't be cloned by type ids.
728    pub fn deny_by_type_ids(&mut self, ids: impl IntoIterator<Item = TypeId>) -> &mut Self {
729        for type_id in ids {
730            if let Some(id) = self.world.components().get_id(type_id) {
731                self.filter_deny(id);
732            }
733        }
734        self
735    }
736
737    /// Sets the filter to deny all components.
738    pub fn deny_all(&mut self) -> &mut Self {
739        self.entity_cloner.filter_allows_components = true;
740        self.entity_cloner.filter.clear();
741        self
742    }
743
744    /// Overrides the [`ComponentCloneBehavior`] for a component in this builder.
745    /// This handler will be used to clone the component instead of the global one defined by the [`EntityCloner`].
746    ///
747    /// See [Handlers section of `EntityClonerBuilder`](EntityClonerBuilder#handlers) to understand how this affects handler priority.
748    pub fn override_clone_behavior<T: Component>(
749        &mut self,
750        clone_behavior: ComponentCloneBehavior,
751    ) -> &mut Self {
752        if let Some(id) = self.world.components().component_id::<T>() {
753            self.entity_cloner
754                .clone_behavior_overrides
755                .insert(id, clone_behavior);
756        }
757        self
758    }
759
760    /// Overrides the [`ComponentCloneBehavior`] for a component with the given `component_id` in this builder.
761    /// This handler will be used to clone the component instead of the global one defined by the [`EntityCloner`].
762    ///
763    /// See [Handlers section of `EntityClonerBuilder`](EntityClonerBuilder#handlers) to understand how this affects handler priority.
764    pub fn override_clone_behavior_with_id(
765        &mut self,
766        component_id: ComponentId,
767        clone_behavior: ComponentCloneBehavior,
768    ) -> &mut Self {
769        self.entity_cloner
770            .clone_behavior_overrides
771            .insert(component_id, clone_behavior);
772        self
773    }
774
775    /// Removes a previously set override of [`ComponentCloneBehavior`] for a component in this builder.
776    pub fn remove_clone_behavior_override<T: Component>(&mut self) -> &mut Self {
777        if let Some(id) = self.world.components().component_id::<T>() {
778            self.entity_cloner.clone_behavior_overrides.remove(&id);
779        }
780        self
781    }
782
783    /// Removes a previously set override of [`ComponentCloneBehavior`] for a given `component_id` in this builder.
784    pub fn remove_clone_behavior_override_with_id(
785        &mut self,
786        component_id: ComponentId,
787    ) -> &mut Self {
788        self.entity_cloner
789            .clone_behavior_overrides
790            .remove(&component_id);
791        self
792    }
793
794    /// When true this cloner will be configured to clone entities referenced in cloned components via [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN).
795    /// This will produce "deep" / recursive clones of relationship trees that have "linked spawn".
796    pub fn linked_cloning(&mut self, linked_cloning: bool) -> &mut Self {
797        self.entity_cloner.linked_cloning = linked_cloning;
798        self
799    }
800
801    /// Helper function that allows a component through the filter.
802    fn filter_allow(&mut self, id: ComponentId) {
803        if self.entity_cloner.filter_allows_components {
804            self.entity_cloner.filter.insert(id);
805        } else {
806            self.entity_cloner.filter.remove(&id);
807        }
808        if self.attach_required_components {
809            if let Some(info) = self.world.components().get_info(id) {
810                for required_id in info.required_components().iter_ids() {
811                    if self.entity_cloner.filter_allows_components {
812                        self.entity_cloner.filter.insert(required_id);
813                    } else {
814                        self.entity_cloner.filter.remove(&required_id);
815                    }
816                }
817            }
818        }
819    }
820
821    /// Helper function that disallows a component through the filter.
822    fn filter_deny(&mut self, id: ComponentId) {
823        if self.entity_cloner.filter_allows_components {
824            self.entity_cloner.filter.remove(&id);
825        } else {
826            self.entity_cloner.filter.insert(id);
827        }
828        if self.attach_required_components {
829            if let Some(info) = self.world.components().get_info(id) {
830                for required_id in info.required_components().iter_ids() {
831                    if self.entity_cloner.filter_allows_components {
832                        self.entity_cloner.filter.remove(&required_id);
833                    } else {
834                        self.entity_cloner.filter.insert(required_id);
835                    }
836                }
837            }
838        }
839    }
840}
841
842#[cfg(test)]
843mod tests {
844    use super::ComponentCloneCtx;
845    use crate::{
846        component::{Component, ComponentCloneBehavior, ComponentDescriptor, StorageType},
847        entity::{Entity, EntityCloner, EntityHashMap, SourceComponent},
848        prelude::{ChildOf, Children, Resource},
849        reflect::{AppTypeRegistry, ReflectComponent, ReflectFromWorld},
850        world::{FromWorld, World},
851    };
852    use alloc::vec::Vec;
853    use bevy_ptr::OwningPtr;
854    use bevy_reflect::Reflect;
855    use core::marker::PhantomData;
856    use core::{alloc::Layout, ops::Deref};
857
858    #[cfg(feature = "bevy_reflect")]
859    mod reflect {
860        use super::*;
861        use crate::{
862            component::{Component, ComponentCloneBehavior},
863            entity::{EntityCloner, SourceComponent},
864            reflect::{AppTypeRegistry, ReflectComponent, ReflectFromWorld},
865        };
866        use alloc::vec;
867        use bevy_reflect::{std_traits::ReflectDefault, FromType, Reflect, ReflectFromPtr};
868
869        #[test]
870        fn clone_entity_using_reflect() {
871            #[derive(Component, Reflect, Clone, PartialEq, Eq)]
872            #[reflect(Component)]
873            struct A {
874                field: usize,
875            }
876
877            let mut world = World::default();
878            world.init_resource::<AppTypeRegistry>();
879            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
880            registry.write().register::<A>();
881
882            world.register_component::<A>();
883            let component = A { field: 5 };
884
885            let e = world.spawn(component.clone()).id();
886            let e_clone = world.spawn_empty().id();
887
888            EntityCloner::build(&mut world)
889                .override_clone_behavior::<A>(ComponentCloneBehavior::reflect())
890                .clone_entity(e, e_clone);
891
892            assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
893        }
894
895        #[test]
896        fn clone_entity_using_reflect_all_paths() {
897            #[derive(PartialEq, Eq, Default, Debug)]
898            struct NotClone;
899
900            // `reflect_clone`-based fast path
901            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
902            #[reflect(from_reflect = false)]
903            struct A {
904                field: usize,
905                field2: Vec<usize>,
906            }
907
908            // `ReflectDefault`-based fast path
909            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
910            #[reflect(Default)]
911            #[reflect(from_reflect = false)]
912            struct B {
913                field: usize,
914                field2: Vec<usize>,
915                #[reflect(ignore)]
916                ignored: NotClone,
917            }
918
919            // `ReflectFromReflect`-based fast path
920            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
921            struct C {
922                field: usize,
923                field2: Vec<usize>,
924                #[reflect(ignore)]
925                ignored: NotClone,
926            }
927
928            // `ReflectFromWorld`-based fast path
929            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
930            #[reflect(FromWorld)]
931            #[reflect(from_reflect = false)]
932            struct D {
933                field: usize,
934                field2: Vec<usize>,
935                #[reflect(ignore)]
936                ignored: NotClone,
937            }
938
939            let mut world = World::default();
940            world.init_resource::<AppTypeRegistry>();
941            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
942            registry.write().register::<(A, B, C, D)>();
943
944            let a_id = world.register_component::<A>();
945            let b_id = world.register_component::<B>();
946            let c_id = world.register_component::<C>();
947            let d_id = world.register_component::<D>();
948            let component_a = A {
949                field: 5,
950                field2: vec![1, 2, 3, 4, 5],
951            };
952            let component_b = B {
953                field: 5,
954                field2: vec![1, 2, 3, 4, 5],
955                ignored: NotClone,
956            };
957            let component_c = C {
958                field: 6,
959                field2: vec![1, 2, 3, 4, 5],
960                ignored: NotClone,
961            };
962            let component_d = D {
963                field: 7,
964                field2: vec![1, 2, 3, 4, 5],
965                ignored: NotClone,
966            };
967
968            let e = world
969                .spawn((component_a, component_b, component_c, component_d))
970                .id();
971            let e_clone = world.spawn_empty().id();
972
973            EntityCloner::build(&mut world)
974                .override_clone_behavior_with_id(a_id, ComponentCloneBehavior::reflect())
975                .override_clone_behavior_with_id(b_id, ComponentCloneBehavior::reflect())
976                .override_clone_behavior_with_id(c_id, ComponentCloneBehavior::reflect())
977                .override_clone_behavior_with_id(d_id, ComponentCloneBehavior::reflect())
978                .clone_entity(e, e_clone);
979
980            assert_eq!(world.get::<A>(e_clone), Some(world.get::<A>(e).unwrap()));
981            assert_eq!(world.get::<B>(e_clone), Some(world.get::<B>(e).unwrap()));
982            assert_eq!(world.get::<C>(e_clone), Some(world.get::<C>(e).unwrap()));
983            assert_eq!(world.get::<D>(e_clone), Some(world.get::<D>(e).unwrap()));
984        }
985
986        #[test]
987        fn read_source_component_reflect_should_return_none_on_invalid_reflect_from_ptr() {
988            #[derive(Component, Reflect)]
989            struct A;
990
991            #[derive(Component, Reflect)]
992            struct B;
993
994            fn test_handler(source: &SourceComponent, ctx: &mut ComponentCloneCtx) {
995                let registry = ctx.type_registry().unwrap();
996                assert!(source.read_reflect(&registry.read()).is_none());
997            }
998
999            let mut world = World::default();
1000            world.init_resource::<AppTypeRegistry>();
1001            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1002            {
1003                let mut registry = registry.write();
1004                registry.register::<A>();
1005                registry
1006                    .get_mut(core::any::TypeId::of::<A>())
1007                    .unwrap()
1008                    .insert(<ReflectFromPtr as FromType<B>>::from_type());
1009            }
1010
1011            let e = world.spawn(A).id();
1012            let e_clone = world.spawn_empty().id();
1013
1014            EntityCloner::build(&mut world)
1015                .override_clone_behavior::<A>(ComponentCloneBehavior::Custom(test_handler))
1016                .clone_entity(e, e_clone);
1017        }
1018
1019        #[test]
1020        fn clone_entity_specialization() {
1021            #[derive(Component, Reflect, PartialEq, Eq)]
1022            #[reflect(Component)]
1023            struct A {
1024                field: usize,
1025            }
1026
1027            impl Clone for A {
1028                fn clone(&self) -> Self {
1029                    Self { field: 10 }
1030                }
1031            }
1032
1033            let mut world = World::default();
1034            world.init_resource::<AppTypeRegistry>();
1035            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1036            registry.write().register::<A>();
1037
1038            let component = A { field: 5 };
1039
1040            let e = world.spawn(component.clone()).id();
1041            let e_clone = world.spawn_empty().id();
1042
1043            EntityCloner::build(&mut world).clone_entity(e, e_clone);
1044
1045            assert!(world
1046                .get::<A>(e_clone)
1047                .is_some_and(|comp| *comp == A { field: 10 }));
1048        }
1049
1050        #[test]
1051        fn clone_entity_using_reflect_should_skip_without_panic() {
1052            // Not reflected
1053            #[derive(Component, PartialEq, Eq, Default, Debug)]
1054            struct A;
1055
1056            // No valid type data and not `reflect_clone`-able
1057            #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1058            #[reflect(Component)]
1059            #[reflect(from_reflect = false)]
1060            struct B(#[reflect(ignore)] PhantomData<()>);
1061
1062            let mut world = World::default();
1063
1064            // No AppTypeRegistry
1065            let e = world.spawn((A, B(Default::default()))).id();
1066            let e_clone = world.spawn_empty().id();
1067            EntityCloner::build(&mut world)
1068                .override_clone_behavior::<A>(ComponentCloneBehavior::reflect())
1069                .override_clone_behavior::<B>(ComponentCloneBehavior::reflect())
1070                .clone_entity(e, e_clone);
1071            assert_eq!(world.get::<A>(e_clone), None);
1072            assert_eq!(world.get::<B>(e_clone), None);
1073
1074            // With AppTypeRegistry
1075            world.init_resource::<AppTypeRegistry>();
1076            let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1077            registry.write().register::<B>();
1078
1079            let e = world.spawn((A, B(Default::default()))).id();
1080            let e_clone = world.spawn_empty().id();
1081            EntityCloner::build(&mut world).clone_entity(e, e_clone);
1082            assert_eq!(world.get::<A>(e_clone), None);
1083            assert_eq!(world.get::<B>(e_clone), None);
1084        }
1085    }
1086
1087    #[test]
1088    fn clone_entity_using_clone() {
1089        #[derive(Component, Clone, PartialEq, Eq)]
1090        struct A {
1091            field: usize,
1092        }
1093
1094        let mut world = World::default();
1095
1096        let component = A { field: 5 };
1097
1098        let e = world.spawn(component.clone()).id();
1099        let e_clone = world.spawn_empty().id();
1100
1101        EntityCloner::build(&mut world).clone_entity(e, e_clone);
1102
1103        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1104    }
1105
1106    #[test]
1107    fn clone_entity_with_allow_filter() {
1108        #[derive(Component, Clone, PartialEq, Eq)]
1109        struct A {
1110            field: usize,
1111        }
1112
1113        #[derive(Component, Clone)]
1114        struct B;
1115
1116        let mut world = World::default();
1117
1118        let component = A { field: 5 };
1119
1120        let e = world.spawn((component.clone(), B)).id();
1121        let e_clone = world.spawn_empty().id();
1122
1123        EntityCloner::build(&mut world)
1124            .deny_all()
1125            .allow::<A>()
1126            .clone_entity(e, e_clone);
1127
1128        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1129        assert!(world.get::<B>(e_clone).is_none());
1130    }
1131
1132    #[test]
1133    fn clone_entity_with_deny_filter() {
1134        #[derive(Component, Clone, PartialEq, Eq)]
1135        struct A {
1136            field: usize,
1137        }
1138
1139        #[derive(Component, Clone)]
1140        struct B;
1141
1142        #[derive(Component, Clone)]
1143        struct C;
1144
1145        let mut world = World::default();
1146
1147        let component = A { field: 5 };
1148
1149        let e = world.spawn((component.clone(), B, C)).id();
1150        let e_clone = world.spawn_empty().id();
1151
1152        EntityCloner::build(&mut world)
1153            .deny::<B>()
1154            .clone_entity(e, e_clone);
1155
1156        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1157        assert!(world.get::<B>(e_clone).is_none());
1158        assert!(world.get::<C>(e_clone).is_some());
1159    }
1160
1161    #[test]
1162    fn clone_entity_with_override_allow_filter() {
1163        #[derive(Component, Clone, PartialEq, Eq)]
1164        struct A {
1165            field: usize,
1166        }
1167
1168        #[derive(Component, Clone)]
1169        struct B;
1170
1171        #[derive(Component, Clone)]
1172        struct C;
1173
1174        let mut world = World::default();
1175
1176        let component = A { field: 5 };
1177
1178        let e = world.spawn((component.clone(), B, C)).id();
1179        let e_clone = world.spawn_empty().id();
1180
1181        EntityCloner::build(&mut world)
1182            .deny_all()
1183            .allow::<A>()
1184            .allow::<B>()
1185            .allow::<C>()
1186            .deny::<B>()
1187            .clone_entity(e, e_clone);
1188
1189        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1190        assert!(world.get::<B>(e_clone).is_none());
1191        assert!(world.get::<C>(e_clone).is_some());
1192    }
1193
1194    #[test]
1195    fn clone_entity_with_override_bundle() {
1196        #[derive(Component, Clone, PartialEq, Eq)]
1197        struct A {
1198            field: usize,
1199        }
1200
1201        #[derive(Component, Clone)]
1202        struct B;
1203
1204        #[derive(Component, Clone)]
1205        struct C;
1206
1207        let mut world = World::default();
1208
1209        let component = A { field: 5 };
1210
1211        let e = world.spawn((component.clone(), B, C)).id();
1212        let e_clone = world.spawn_empty().id();
1213
1214        EntityCloner::build(&mut world)
1215            .deny_all()
1216            .allow::<(A, B, C)>()
1217            .deny::<(B, C)>()
1218            .clone_entity(e, e_clone);
1219
1220        assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1221        assert!(world.get::<B>(e_clone).is_none());
1222        assert!(world.get::<C>(e_clone).is_none());
1223    }
1224
1225    #[test]
1226    fn clone_entity_with_required_components() {
1227        #[derive(Component, Clone, PartialEq, Debug)]
1228        #[require(B)]
1229        struct A;
1230
1231        #[derive(Component, Clone, PartialEq, Debug, Default)]
1232        #[require(C(5))]
1233        struct B;
1234
1235        #[derive(Component, Clone, PartialEq, Debug)]
1236        struct C(u32);
1237
1238        let mut world = World::default();
1239
1240        let e = world.spawn(A).id();
1241        let e_clone = world.spawn_empty().id();
1242
1243        EntityCloner::build(&mut world)
1244            .deny_all()
1245            .allow::<B>()
1246            .clone_entity(e, e_clone);
1247
1248        assert_eq!(world.entity(e_clone).get::<A>(), None);
1249        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
1250        assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
1251    }
1252
1253    #[test]
1254    fn clone_entity_with_default_required_components() {
1255        #[derive(Component, Clone, PartialEq, Debug)]
1256        #[require(B)]
1257        struct A;
1258
1259        #[derive(Component, Clone, PartialEq, Debug, Default)]
1260        #[require(C(5))]
1261        struct B;
1262
1263        #[derive(Component, Clone, PartialEq, Debug)]
1264        struct C(u32);
1265
1266        let mut world = World::default();
1267
1268        let e = world.spawn((A, C(0))).id();
1269        let e_clone = world.spawn_empty().id();
1270
1271        EntityCloner::build(&mut world)
1272            .deny_all()
1273            .without_required_components(|builder| {
1274                builder.allow::<A>();
1275            })
1276            .clone_entity(e, e_clone);
1277
1278        assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
1279        assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
1280        assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
1281    }
1282
1283    #[test]
1284    fn clone_entity_with_dynamic_components() {
1285        const COMPONENT_SIZE: usize = 10;
1286        fn test_handler(source: &SourceComponent, ctx: &mut ComponentCloneCtx) {
1287            // SAFETY: the passed in ptr corresponds to copy-able data that matches the type of the source / target component
1288            unsafe {
1289                ctx.write_target_component_ptr(source.ptr());
1290            }
1291        }
1292
1293        let mut world = World::default();
1294
1295        let layout = Layout::array::<u8>(COMPONENT_SIZE).unwrap();
1296        // SAFETY:
1297        // - No drop command is required
1298        // - The component will store [u8; COMPONENT_SIZE], which is Send + Sync
1299        let descriptor = unsafe {
1300            ComponentDescriptor::new_with_layout(
1301                "DynamicComp",
1302                StorageType::Table,
1303                layout,
1304                None,
1305                true,
1306                ComponentCloneBehavior::Custom(test_handler),
1307            )
1308        };
1309        let component_id = world.register_component_with_descriptor(descriptor);
1310
1311        let mut entity = world.spawn_empty();
1312        let data = [5u8; COMPONENT_SIZE];
1313
1314        // SAFETY:
1315        // - ptr points to data represented by component_id ([u8; COMPONENT_SIZE])
1316        // - component_id is from the same world as entity
1317        OwningPtr::make(data, |ptr| unsafe {
1318            entity.insert_by_id(component_id, ptr);
1319        });
1320        let entity = entity.id();
1321
1322        let entity_clone = world.spawn_empty().id();
1323        EntityCloner::build(&mut world).clone_entity(entity, entity_clone);
1324
1325        let ptr = world.get_by_id(entity, component_id).unwrap();
1326        let clone_ptr = world.get_by_id(entity_clone, component_id).unwrap();
1327        // SAFETY: ptr and clone_ptr store component represented by [u8; COMPONENT_SIZE]
1328        unsafe {
1329            assert_eq!(
1330                core::slice::from_raw_parts(ptr.as_ptr(), COMPONENT_SIZE),
1331                core::slice::from_raw_parts(clone_ptr.as_ptr(), COMPONENT_SIZE),
1332            );
1333        }
1334    }
1335
1336    #[test]
1337    fn recursive_clone() {
1338        let mut world = World::new();
1339        let root = world.spawn_empty().id();
1340        let child1 = world.spawn(ChildOf(root)).id();
1341        let grandchild = world.spawn(ChildOf(child1)).id();
1342        let child2 = world.spawn(ChildOf(root)).id();
1343
1344        let clone_root = world.spawn_empty().id();
1345        EntityCloner::build(&mut world)
1346            .linked_cloning(true)
1347            .clone_entity(root, clone_root);
1348
1349        let root_children = world
1350            .entity(clone_root)
1351            .get::<Children>()
1352            .unwrap()
1353            .iter()
1354            .cloned()
1355            .collect::<Vec<_>>();
1356
1357        assert!(root_children.iter().all(|e| *e != child1 && *e != child2));
1358        assert_eq!(root_children.len(), 2);
1359        let child1_children = world.entity(root_children[0]).get::<Children>().unwrap();
1360        assert_eq!(child1_children.len(), 1);
1361        assert_ne!(child1_children[0], grandchild);
1362        assert!(world.entity(root_children[1]).get::<Children>().is_none());
1363
1364        assert_eq!(
1365            world.entity(root).get::<Children>().unwrap().deref(),
1366            &[child1, child2]
1367        );
1368    }
1369
1370    #[test]
1371    fn clone_with_reflect_from_world() {
1372        #[derive(Component, Reflect, PartialEq, Eq, Debug)]
1373        #[reflect(Component, FromWorld, from_reflect = false)]
1374        struct SomeRef(
1375            #[entities] Entity,
1376            // We add an ignored field here to ensure `reflect_clone` fails and `FromWorld` is used
1377            #[reflect(ignore)] PhantomData<()>,
1378        );
1379
1380        #[derive(Resource)]
1381        struct FromWorldCalled(bool);
1382
1383        impl FromWorld for SomeRef {
1384            fn from_world(world: &mut World) -> Self {
1385                world.insert_resource(FromWorldCalled(true));
1386                SomeRef(Entity::PLACEHOLDER, Default::default())
1387            }
1388        }
1389        let mut world = World::new();
1390        let registry = AppTypeRegistry::default();
1391        registry.write().register::<SomeRef>();
1392        world.insert_resource(registry);
1393
1394        let a = world.spawn_empty().id();
1395        let b = world.spawn_empty().id();
1396        let c = world.spawn(SomeRef(a, Default::default())).id();
1397        let d = world.spawn_empty().id();
1398        let mut map = EntityHashMap::<Entity>::new();
1399        map.insert(a, b);
1400        map.insert(c, d);
1401
1402        let cloned = EntityCloner::default().clone_entity_mapped(&mut world, c, &mut map);
1403        assert_eq!(
1404            *world.entity(cloned).get::<SomeRef>().unwrap(),
1405            SomeRef(b, Default::default())
1406        );
1407        assert!(world.resource::<FromWorldCalled>().0);
1408    }
1409}