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