1use crate::{
2 archetype::Archetype,
3 bundle::{Bundle, BundleRemover, InsertMode},
4 change_detection::MaybeLocation,
5 component::{Component, ComponentCloneBehavior, ComponentCloneFn, ComponentId, ComponentInfo},
6 entity::{hash_map::EntityHashMap, Entity, EntityAllocator, EntityMapper},
7 query::DebugCheckedUnwrap,
8 relationship::RelationshipHookMode,
9 world::World,
10};
11use alloc::{boxed::Box, collections::VecDeque, vec::Vec};
12use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet};
13use bevy_ptr::{Ptr, PtrMut};
14use bevy_utils::prelude::DebugName;
15use bumpalo::Bump;
16use core::{any::TypeId, cell::LazyCell, ops::Range};
17use derive_more::From;
18
19pub struct SourceComponent<'a> {
21 ptr: Ptr<'a>,
22 id: ComponentId,
23 info: &'a ComponentInfo,
24}
25
26impl<'a> SourceComponent<'a> {
27 pub fn read<C: Component>(&self) -> Option<&C> {
31 if self
32 .info
33 .type_id()
34 .is_some_and(|id| id == TypeId::of::<C>())
35 {
36 unsafe { Some(self.ptr.deref::<C>()) }
40 } else {
41 None
42 }
43 }
44
45 pub fn ptr(&self) -> Ptr<'a> {
47 self.ptr
48 }
49
50 pub fn id(&self) -> ComponentId {
52 self.id
53 }
54
55 #[cfg(feature = "bevy_reflect")]
64 pub fn read_reflect(
65 &self,
66 registry: &bevy_reflect::TypeRegistry,
67 ) -> Option<&dyn bevy_reflect::Reflect> {
68 let type_id = self.info.type_id()?;
69 let reflect_from_ptr = registry.get_type_data::<bevy_reflect::ReflectFromPtr>(type_id)?;
70 if reflect_from_ptr.type_id() != type_id {
71 return None;
72 }
73 unsafe { Some(reflect_from_ptr.ptr_as_reflect(self.ptr)) }
75 }
76}
77
78pub struct ComponentCloneCtx<'a, 'b> {
83 component_id: ComponentId,
84 target_component_written: bool,
85 target_component_moved: bool,
86 bundle_scratch: &'a mut BundleScratchSpace<'b>,
87 bundle_scratch_allocator: &'b Bump,
88 allocator: &'a EntityAllocator,
89 source: Entity,
90 target: Entity,
91 component_info: &'a ComponentInfo,
92 state: &'a mut EntityClonerState,
93 mapper: &'a mut dyn EntityMapper,
94 #[cfg(feature = "bevy_reflect")]
95 type_registry: Option<&'a crate::reflect::AppTypeRegistry>,
96 #[cfg(not(feature = "bevy_reflect"))]
97 #[expect(dead_code, reason = "type_registry is only used with bevy_reflect")]
98 type_registry: Option<&'a ()>,
99}
100
101impl<'a, 'b> ComponentCloneCtx<'a, 'b> {
102 unsafe fn new(
109 component_id: ComponentId,
110 source: Entity,
111 target: Entity,
112 bundle_scratch_allocator: &'b Bump,
113 bundle_scratch: &'a mut BundleScratchSpace<'b>,
114 allocator: &'a EntityAllocator,
115 component_info: &'a ComponentInfo,
116 entity_cloner: &'a mut EntityClonerState,
117 mapper: &'a mut dyn EntityMapper,
118 #[cfg(feature = "bevy_reflect")] type_registry: Option<&'a crate::reflect::AppTypeRegistry>,
119 #[cfg(not(feature = "bevy_reflect"))] type_registry: Option<&'a ()>,
120 ) -> Self {
121 Self {
122 component_id,
123 source,
124 target,
125 bundle_scratch,
126 target_component_written: false,
127 target_component_moved: false,
128 bundle_scratch_allocator,
129 allocator,
130 mapper,
131 component_info,
132 state: entity_cloner,
133 type_registry,
134 }
135 }
136
137 pub fn target_component_written(&self) -> bool {
139 self.target_component_written
140 }
141
142 pub fn moving(&self) -> bool {
144 self.state.move_components
145 }
146
147 pub fn source(&self) -> Entity {
149 self.source
150 }
151
152 pub fn target(&self) -> Entity {
154 self.target
155 }
156
157 pub fn component_id(&self) -> ComponentId {
159 self.component_id
160 }
161
162 pub fn component_info(&self) -> &ComponentInfo {
164 self.component_info
165 }
166
167 #[inline]
171 pub fn linked_cloning(&self) -> bool {
172 self.state.linked_cloning
173 }
174
175 pub fn entity_mapper(&mut self) -> &mut dyn EntityMapper {
177 self.mapper
178 }
179
180 pub fn write_target_component<C: Component>(&mut self, mut component: C) {
188 C::map_entities(&mut component, &mut self.mapper);
189 let debug_name = DebugName::type_name::<C>();
190 let short_name = debug_name.shortname();
191 if self.target_component_written {
192 panic!("Trying to write component '{short_name}' multiple times")
193 }
194 if self
195 .component_info
196 .type_id()
197 .is_none_or(|id| id != TypeId::of::<C>())
198 {
199 panic!("TypeId of component '{short_name}' does not match source component TypeId")
200 };
201 unsafe {
203 self.bundle_scratch
204 .push(self.bundle_scratch_allocator, self.component_id, component);
205 };
206 self.target_component_written = true;
207 }
208
209 pub unsafe fn write_target_component_ptr(&mut self, ptr: Ptr) {
218 if self.target_component_written {
219 panic!("Trying to write component multiple times")
220 }
221 let layout = self.component_info.layout();
222 let target_ptr = self.bundle_scratch_allocator.alloc_layout(layout);
223 unsafe {
227 core::ptr::copy_nonoverlapping(ptr.as_ptr(), target_ptr.as_ptr(), layout.size());
228 self.bundle_scratch
229 .push_ptr(self.component_id, PtrMut::new(target_ptr));
230 }
231 self.target_component_written = true;
232 }
233
234 #[cfg(feature = "bevy_reflect")]
244 pub fn write_target_component_reflect(&mut self, component: Box<dyn bevy_reflect::Reflect>) {
245 if self.target_component_written {
246 panic!("Trying to write component multiple times")
247 }
248 let source_type_id = self
249 .component_info
250 .type_id()
251 .expect("Source component must have TypeId");
252 let component_type_id = component.type_id();
253 if source_type_id != component_type_id {
254 panic!("Passed component TypeId does not match source component TypeId")
255 }
256 let component_layout = self.component_info.layout();
257
258 let component_data_ptr = Box::into_raw(component).cast::<u8>();
259 let target_component_data_ptr =
260 self.bundle_scratch_allocator.alloc_layout(component_layout);
261 unsafe {
265 core::ptr::copy_nonoverlapping(
266 component_data_ptr,
267 target_component_data_ptr.as_ptr(),
268 component_layout.size(),
269 );
270 self.bundle_scratch
271 .push_ptr(self.component_id, PtrMut::new(target_component_data_ptr));
272
273 if component_layout.size() > 0 {
274 alloc::alloc::dealloc(component_data_ptr, component_layout);
276 }
277 }
278
279 self.target_component_written = true;
280 }
281
282 #[cfg(feature = "bevy_reflect")]
286 pub fn type_registry(&self) -> Option<&crate::reflect::AppTypeRegistry> {
287 self.type_registry
288 }
289
290 pub fn queue_entity_clone(&mut self, entity: Entity) {
292 let target = self.allocator.alloc();
293 self.mapper.set_mapped(entity, target);
294 self.state.clone_queue.push_back(entity);
295 }
296
297 pub fn queue_deferred(
300 &mut self,
301 deferred: impl FnOnce(&mut World, &mut dyn EntityMapper) + 'static,
302 ) {
303 self.state.deferred_commands.push_back(Box::new(deferred));
304 }
305
306 fn move_component(&mut self) {
308 self.target_component_moved = true;
309 self.target_component_written = true;
310 }
311}
312
313#[derive(Default)]
381pub struct EntityCloner {
382 filter: EntityClonerFilter,
383 state: EntityClonerState,
384}
385
386struct BundleScratchSpace<'a> {
388 component_ids: Vec<ComponentId>,
389 component_ptrs: Vec<PtrMut<'a>>,
390}
391
392impl<'a> BundleScratchSpace<'a> {
393 pub(crate) fn with_capacity(capacity: usize) -> Self {
394 Self {
395 component_ids: Vec::with_capacity(capacity),
396 component_ptrs: Vec::with_capacity(capacity),
397 }
398 }
399
400 pub(crate) unsafe fn push_ptr(&mut self, id: ComponentId, ptr: PtrMut<'a>) {
407 self.component_ids.push(id);
408 self.component_ptrs.push(ptr);
409 }
410
411 pub(crate) unsafe fn push<C: Component>(
417 &mut self,
418 allocator: &'a Bump,
419 id: ComponentId,
420 component: C,
421 ) {
422 let component_ref = allocator.alloc(component);
423 self.component_ids.push(id);
424 self.component_ptrs.push(PtrMut::from(component_ref));
425 }
426
427 #[track_caller]
432 pub(crate) unsafe fn write(
433 self,
434 world: &mut World,
435 entity: Entity,
436 relationship_hook_insert_mode: RelationshipHookMode,
437 ) {
438 unsafe {
442 world.entity_mut(entity).insert_by_ids_internal(
443 &self.component_ids,
444 self.component_ptrs.into_iter().map(|ptr| ptr.promote()),
445 relationship_hook_insert_mode,
446 );
447 }
448 }
449}
450
451impl EntityCloner {
452 pub fn build_opt_out(world: &mut World) -> EntityClonerBuilder<'_, OptOut> {
459 EntityClonerBuilder {
460 world,
461 filter: Default::default(),
462 state: Default::default(),
463 }
464 }
465
466 pub fn build_opt_in(world: &mut World) -> EntityClonerBuilder<'_, OptIn> {
475 EntityClonerBuilder {
476 world,
477 filter: Default::default(),
478 state: Default::default(),
479 }
480 }
481
482 #[inline]
485 pub fn linked_cloning(&self) -> bool {
486 self.state.linked_cloning
487 }
488
489 #[track_caller]
494 pub fn clone_entity(&mut self, world: &mut World, source: Entity, target: Entity) {
495 let mut map = EntityHashMap::<Entity>::new();
496 map.set_mapped(source, target);
497 self.clone_entity_mapped(world, source, &mut map);
498 }
499
500 #[track_caller]
505 pub fn spawn_clone(&mut self, world: &mut World, source: Entity) -> Entity {
506 let target = world.spawn_empty().id();
507 self.clone_entity(world, source, target);
508 target
509 }
510
511 #[track_caller]
513 pub fn clone_entity_mapped(
514 &mut self,
515 world: &mut World,
516 source: Entity,
517 mapper: &mut dyn EntityMapper,
518 ) -> Entity {
519 Self::clone_entity_mapped_internal(&mut self.state, &mut self.filter, world, source, mapper)
520 }
521
522 #[track_caller]
523 #[inline]
524 fn clone_entity_mapped_internal(
525 state: &mut EntityClonerState,
526 filter: &mut impl CloneByFilter,
527 world: &mut World,
528 source: Entity,
529 mapper: &mut dyn EntityMapper,
530 ) -> Entity {
531 let target = Self::clone_entity_internal(
533 state,
534 filter,
535 world,
536 source,
537 mapper,
538 RelationshipHookMode::Run,
539 );
540 let child_hook_insert_mode = if state.linked_cloning {
541 RelationshipHookMode::RunIfNotLinked
544 } else {
545 RelationshipHookMode::Run
548 };
549 loop {
550 let queued = state.clone_queue.pop_front();
551 if let Some(queued) = queued {
552 Self::clone_entity_internal(
553 state,
554 filter,
555 world,
556 queued,
557 mapper,
558 child_hook_insert_mode,
559 );
560 } else {
561 break;
562 }
563 }
564 target
565 }
566
567 #[track_caller]
569 fn clone_entity_internal(
570 state: &mut EntityClonerState,
571 filter: &mut impl CloneByFilter,
572 world: &mut World,
573 source: Entity,
574 mapper: &mut dyn EntityMapper,
575 relationship_hook_insert_mode: RelationshipHookMode,
576 ) -> Entity {
577 let target = mapper.get_mapped(source);
578 let _ = world.spawn_empty_at(target);
581
582 let bundle_scratch_allocator = Bump::new();
584 let mut bundle_scratch: BundleScratchSpace;
585 let mut moved_components: Vec<ComponentId> = Vec::new();
586 let mut deferred_cloned_component_ids: Vec<ComponentId> = Vec::new();
587 {
588 let world = world.as_unsafe_world_cell();
589 let source_entity = world
590 .get_entity(source)
591 .expect("Source entity must be valid and spawned.");
592 let source_archetype = source_entity.archetype();
593
594 #[cfg(feature = "bevy_reflect")]
595 let app_registry = unsafe {
598 world
599 .get_resource::<crate::reflect::AppTypeRegistry>()
600 .cloned()
601 };
602 #[cfg(not(feature = "bevy_reflect"))]
603 let app_registry = Option::<()>::None;
604
605 bundle_scratch = BundleScratchSpace::with_capacity(source_archetype.component_count());
606
607 let target_archetype = LazyCell::new(|| {
608 world
609 .get_entity(target)
610 .expect("Target entity must be valid and spawned.")
611 .archetype()
612 });
613
614 if state.move_components {
615 moved_components.reserve(source_archetype.component_count());
616 state.default_clone_fn = |_, ctx| ctx.move_component();
619 }
620
621 filter.clone_components(source_archetype, target_archetype, |component| {
622 let handler = match state.clone_behavior_overrides.get(&component).or_else(|| {
623 world
624 .components()
625 .get_info(component)
626 .map(ComponentInfo::clone_behavior)
627 }) {
628 Some(behavior) => match behavior {
629 ComponentCloneBehavior::Default => state.default_clone_fn,
630 ComponentCloneBehavior::Ignore => return,
631 ComponentCloneBehavior::Custom(custom) => *custom,
632 },
633 None => state.default_clone_fn,
634 };
635
636 let info = unsafe { world.components().get_info_unchecked(component) };
638
639 let source_component_ptr =
643 unsafe { source_entity.get_by_id(component).debug_checked_unwrap() };
644
645 let source_component = SourceComponent {
646 id: component,
647 info,
648 ptr: source_component_ptr,
649 };
650
651 let mut ctx = unsafe {
655 ComponentCloneCtx::new(
656 component,
657 source,
658 target,
659 &bundle_scratch_allocator,
660 &mut bundle_scratch,
661 world.entity_allocator(),
662 info,
663 state,
664 mapper,
665 app_registry.as_ref(),
666 )
667 };
668
669 (handler)(&source_component, &mut ctx);
670
671 if ctx.state.move_components {
672 if ctx.target_component_moved {
673 moved_components.push(component);
674 }
675 else if !ctx.target_component_written() {
680 deferred_cloned_component_ids.push(component);
681 }
682 }
683 });
684 }
685
686 world.flush();
687
688 for deferred in state.deferred_commands.drain(..) {
689 (deferred)(world, mapper);
690 }
691
692 if !world.entities.contains(target) {
693 panic!("Target entity does not exist");
694 }
695
696 if state.move_components {
697 let mut source_entity = world.entity_mut(source);
698
699 let cloned_components = if deferred_cloned_component_ids.is_empty() {
700 &bundle_scratch.component_ids
701 } else {
702 deferred_cloned_component_ids.extend(&bundle_scratch.component_ids);
704 &deferred_cloned_component_ids
705 };
706 source_entity.remove_by_ids_with_caller(
707 cloned_components,
708 MaybeLocation::caller(),
709 RelationshipHookMode::RunIfNotLinked,
710 BundleRemover::empty_pre_remove,
711 );
712
713 let table_row = source_entity.location().table_row;
714
715 source_entity.remove_by_ids_with_caller(
717 &moved_components,
718 MaybeLocation::caller(),
719 RelationshipHookMode::RunIfNotLinked,
720 |sparse_sets, mut table, components, bundle| {
721 for &component_id in bundle {
722 let Some(component_ptr) = sparse_sets
723 .get(component_id)
724 .and_then(|component| component.get(source))
725 .or_else(|| {
726 table.as_mut().and_then(|table| unsafe {
728 table.get_component(component_id, table_row)
729 })
730 })
731 else {
732 continue;
734 };
735
736 let info = unsafe { components.get_info_unchecked(component_id) };
738 let layout = info.layout();
739 let target_ptr = bundle_scratch_allocator.alloc_layout(layout);
740 unsafe {
746 core::ptr::copy_nonoverlapping(
747 component_ptr.as_ptr(),
748 target_ptr.as_ptr(),
749 layout.size(),
750 );
751 bundle_scratch.push_ptr(component_id, PtrMut::new(target_ptr));
752 }
753 }
754
755 (false, ())
756 },
757 );
758 }
759
760 unsafe { bundle_scratch.write(world, target, relationship_hook_insert_mode) };
764 target
765 }
766}
767
768struct EntityClonerState {
770 clone_behavior_overrides: HashMap<ComponentId, ComponentCloneBehavior>,
771 move_components: bool,
772 linked_cloning: bool,
773 default_clone_fn: ComponentCloneFn,
774 clone_queue: VecDeque<Entity>,
775 deferred_commands: VecDeque<Box<dyn FnOnce(&mut World, &mut dyn EntityMapper)>>,
776}
777
778impl Default for EntityClonerState {
779 fn default() -> Self {
780 Self {
781 move_components: false,
782 linked_cloning: false,
783 default_clone_fn: ComponentCloneBehavior::global_default_fn(),
784 clone_behavior_overrides: Default::default(),
785 clone_queue: Default::default(),
786 deferred_commands: Default::default(),
787 }
788 }
789}
790
791pub struct EntityClonerBuilder<'w, Filter> {
793 world: &'w mut World,
794 filter: Filter,
795 state: EntityClonerState,
796}
797
798impl<'w, Filter: CloneByFilter> EntityClonerBuilder<'w, Filter> {
799 pub fn clone_entity(&mut self, source: Entity, target: Entity) -> &mut Self {
801 let mut mapper = EntityHashMap::<Entity>::new();
802 mapper.set_mapped(source, target);
803 EntityCloner::clone_entity_mapped_internal(
804 &mut self.state,
805 &mut self.filter,
806 self.world,
807 source,
808 &mut mapper,
809 );
810 self
811 }
812
813 pub fn finish(self) -> EntityCloner {
815 EntityCloner {
816 filter: self.filter.into(),
817 state: self.state,
818 }
819 }
820
821 pub fn with_default_clone_fn(&mut self, clone_fn: ComponentCloneFn) -> &mut Self {
825 self.state.default_clone_fn = clone_fn;
826 self
827 }
828
829 pub fn move_components(&mut self, enable: bool) -> &mut Self {
839 self.state.move_components = enable;
840 self
841 }
842
843 pub fn override_clone_behavior<T: Component>(
848 &mut self,
849 clone_behavior: ComponentCloneBehavior,
850 ) -> &mut Self {
851 if let Some(id) = self.world.components().valid_component_id::<T>() {
852 self.state
853 .clone_behavior_overrides
854 .insert(id, clone_behavior);
855 }
856 self
857 }
858
859 pub fn override_clone_behavior_with_id(
864 &mut self,
865 component_id: ComponentId,
866 clone_behavior: ComponentCloneBehavior,
867 ) -> &mut Self {
868 self.state
869 .clone_behavior_overrides
870 .insert(component_id, clone_behavior);
871 self
872 }
873
874 pub fn remove_clone_behavior_override<T: Component>(&mut self) -> &mut Self {
876 if let Some(id) = self.world.components().valid_component_id::<T>() {
877 self.state.clone_behavior_overrides.remove(&id);
878 }
879 self
880 }
881
882 pub fn remove_clone_behavior_override_with_id(
884 &mut self,
885 component_id: ComponentId,
886 ) -> &mut Self {
887 self.state.clone_behavior_overrides.remove(&component_id);
888 self
889 }
890
891 pub fn linked_cloning(&mut self, linked_cloning: bool) -> &mut Self {
894 self.state.linked_cloning = linked_cloning;
895 self
896 }
897}
898
899impl<'w> EntityClonerBuilder<'w, OptOut> {
900 pub fn without_required_by_components(&mut self, builder: impl FnOnce(&mut Self)) -> &mut Self {
911 self.filter.attach_required_by_components = false;
912 builder(self);
913 self.filter.attach_required_by_components = true;
914 self
915 }
916
917 pub fn insert_mode(&mut self, insert_mode: InsertMode) -> &mut Self {
922 self.filter.insert_mode = insert_mode;
923 self
924 }
925
926 pub fn deny<T: Bundle>(&mut self) -> &mut Self {
932 let bundle_id = self.world.register_bundle::<T>().id();
933 self.deny_by_ids(bundle_id)
934 }
935
936 pub fn deny_by_ids<M: Marker>(&mut self, ids: impl FilterableIds<M>) -> &mut Self {
943 ids.filter_ids(&mut |ids| match ids {
944 FilterableId::Type(type_id) => {
945 if let Some(id) = self.world.components().get_valid_id(type_id) {
946 self.filter.filter_deny(id, self.world);
947 }
948 }
949 FilterableId::Component(component_id) => {
950 self.filter.filter_deny(component_id, self.world);
951 }
952 FilterableId::Bundle(bundle_id) => {
953 if let Some(bundle) = self.world.bundles().get(bundle_id) {
954 let ids = bundle.explicit_components().iter();
955 for &id in ids {
956 self.filter.filter_deny(id, self.world);
957 }
958 }
959 }
960 });
961 self
962 }
963}
964
965impl<'w> EntityClonerBuilder<'w, OptIn> {
966 pub fn without_required_components(&mut self, builder: impl FnOnce(&mut Self)) -> &mut Self {
977 self.filter.attach_required_components = false;
978 builder(self);
979 self.filter.attach_required_components = true;
980 self
981 }
982
983 pub fn allow<T: Bundle>(&mut self) -> &mut Self {
989 let bundle_id = self.world.register_bundle::<T>().id();
990 self.allow_by_ids(bundle_id)
991 }
992
993 pub fn allow_if_new<T: Bundle>(&mut self) -> &mut Self {
1000 let bundle_id = self.world.register_bundle::<T>().id();
1001 self.allow_by_ids_if_new(bundle_id)
1002 }
1003
1004 pub fn allow_by_ids<M: Marker>(&mut self, ids: impl FilterableIds<M>) -> &mut Self {
1011 self.allow_by_ids_inner(ids, InsertMode::Replace);
1012 self
1013 }
1014
1015 pub fn allow_by_ids_if_new<M: Marker>(&mut self, ids: impl FilterableIds<M>) -> &mut Self {
1022 self.allow_by_ids_inner(ids, InsertMode::Keep);
1023 self
1024 }
1025
1026 fn allow_by_ids_inner<M: Marker>(
1027 &mut self,
1028 ids: impl FilterableIds<M>,
1029 insert_mode: InsertMode,
1030 ) {
1031 ids.filter_ids(&mut |id| match id {
1032 FilterableId::Type(type_id) => {
1033 if let Some(id) = self.world.components().get_valid_id(type_id) {
1034 self.filter.filter_allow(id, self.world, insert_mode);
1035 }
1036 }
1037 FilterableId::Component(component_id) => {
1038 self.filter
1039 .filter_allow(component_id, self.world, insert_mode);
1040 }
1041 FilterableId::Bundle(bundle_id) => {
1042 if let Some(bundle) = self.world.bundles().get(bundle_id) {
1043 let ids = bundle.explicit_components().iter();
1044 for &id in ids {
1045 self.filter.filter_allow(id, self.world, insert_mode);
1046 }
1047 }
1048 }
1049 });
1050 }
1051}
1052
1053#[doc(hidden)]
1055pub trait CloneByFilter: Into<EntityClonerFilter> {
1056 fn clone_components<'a>(
1058 &mut self,
1059 source_archetype: &Archetype,
1060 target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1061 clone_component: impl FnMut(ComponentId),
1062 );
1063}
1064
1065#[doc(hidden)]
1067#[derive(From)]
1068pub enum EntityClonerFilter {
1069 OptOut(OptOut),
1070 OptIn(OptIn),
1071}
1072
1073impl Default for EntityClonerFilter {
1074 fn default() -> Self {
1075 Self::OptOut(Default::default())
1076 }
1077}
1078
1079impl CloneByFilter for EntityClonerFilter {
1080 #[inline]
1081 fn clone_components<'a>(
1082 &mut self,
1083 source_archetype: &Archetype,
1084 target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1085 clone_component: impl FnMut(ComponentId),
1086 ) {
1087 match self {
1088 Self::OptOut(filter) => {
1089 filter.clone_components(source_archetype, target_archetype, clone_component);
1090 }
1091 Self::OptIn(filter) => {
1092 filter.clone_components(source_archetype, target_archetype, clone_component);
1093 }
1094 }
1095 }
1096}
1097
1098pub struct OptOut {
1104 deny: HashSet<ComponentId>,
1106
1107 insert_mode: InsertMode,
1109
1110 attach_required_by_components: bool,
1114}
1115
1116impl Default for OptOut {
1117 fn default() -> Self {
1118 Self {
1119 deny: Default::default(),
1120 insert_mode: InsertMode::Replace,
1121 attach_required_by_components: true,
1122 }
1123 }
1124}
1125
1126impl CloneByFilter for OptOut {
1127 #[inline]
1128 fn clone_components<'a>(
1129 &mut self,
1130 source_archetype: &Archetype,
1131 target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1132 mut clone_component: impl FnMut(ComponentId),
1133 ) {
1134 match self.insert_mode {
1135 InsertMode::Replace => {
1136 for component in source_archetype.iter_components() {
1137 if !self.deny.contains(&component) {
1138 clone_component(component);
1139 }
1140 }
1141 }
1142 InsertMode::Keep => {
1143 for component in source_archetype.iter_components() {
1144 if !target_archetype.contains(component) && !self.deny.contains(&component) {
1145 clone_component(component);
1146 }
1147 }
1148 }
1149 }
1150 }
1151}
1152
1153impl OptOut {
1154 #[inline]
1157 fn filter_deny(&mut self, id: ComponentId, world: &World) {
1158 self.deny.insert(id);
1159 if self.attach_required_by_components
1160 && let Some(required_by) = world.components().get_required_by(id)
1161 {
1162 self.deny.extend(required_by.iter());
1163 };
1164 }
1165}
1166
1167pub struct OptIn {
1172 allow: HashMap<ComponentId, Explicit>,
1174
1175 required_of_allow: Vec<ComponentId>,
1177
1178 required: HashMap<ComponentId, Required>,
1182
1183 attach_required_components: bool,
1187}
1188
1189impl Default for OptIn {
1190 fn default() -> Self {
1191 Self {
1192 allow: Default::default(),
1193 required_of_allow: Default::default(),
1194 required: Default::default(),
1195 attach_required_components: true,
1196 }
1197 }
1198}
1199
1200impl CloneByFilter for OptIn {
1201 #[inline]
1202 fn clone_components<'a>(
1203 &mut self,
1204 source_archetype: &Archetype,
1205 target_archetype: LazyCell<&'a Archetype, impl FnOnce() -> &'a Archetype>,
1206 mut clone_component: impl FnMut(ComponentId),
1207 ) {
1208 let mut uncloned_components = source_archetype.component_count();
1210
1211 let mut reduced_any = false;
1213
1214 for (&component, explicit) in self.allow.iter() {
1216 if uncloned_components == 0 {
1217 if reduced_any {
1219 self.required
1220 .iter_mut()
1221 .for_each(|(_, required)| required.reset());
1222 }
1223 return;
1224 }
1225
1226 let do_clone = source_archetype.contains(component)
1227 && (explicit.insert_mode == InsertMode::Replace
1228 || !target_archetype.contains(component));
1229 if do_clone {
1230 clone_component(component);
1231 uncloned_components -= 1;
1232 } else if let Some(range) = explicit.required_range.clone() {
1233 for component in self.required_of_allow[range].iter() {
1234 if let Some(required) = self.required.get_mut(component) {
1236 required.required_by_reduced -= 1;
1237 reduced_any = true;
1238 }
1239 }
1240 }
1241 }
1242
1243 let mut required_iter = self.required.iter_mut();
1244
1245 let required_components = required_iter
1247 .by_ref()
1248 .filter_map(|(&component, required)| {
1249 let do_clone = required.required_by_reduced > 0 && source_archetype.contains(component) && !target_archetype.contains(component); required.reset();
1255
1256 do_clone.then_some(component)
1257 })
1258 .take(uncloned_components);
1259
1260 for required_component in required_components {
1261 clone_component(required_component);
1262 }
1263
1264 if reduced_any {
1268 required_iter.for_each(|(_, required)| required.reset());
1269 }
1270 }
1271}
1272
1273impl OptIn {
1274 #[inline]
1277 fn filter_allow(&mut self, id: ComponentId, world: &World, mut insert_mode: InsertMode) {
1278 match self.allow.entry(id) {
1279 Entry::Vacant(explicit) => {
1280 self.required.remove(&id);
1282
1283 if !self.attach_required_components {
1284 explicit.insert(Explicit {
1285 insert_mode,
1286 required_range: None,
1287 });
1288 } else {
1289 self.filter_allow_with_required(id, world, insert_mode);
1290 }
1291 }
1292 Entry::Occupied(mut explicit) => {
1293 let explicit = explicit.get_mut();
1294
1295 if self.attach_required_components && explicit.required_range.is_none() {
1297 if explicit.insert_mode == InsertMode::Replace {
1298 insert_mode = InsertMode::Replace;
1300 }
1301
1302 self.filter_allow_with_required(id, world, insert_mode);
1303 } else if explicit.insert_mode == InsertMode::Keep {
1304 explicit.insert_mode = insert_mode;
1306 }
1307 }
1308 };
1309 }
1310
1311 #[inline]
1313 fn filter_allow_with_required(
1314 &mut self,
1315 id: ComponentId,
1316 world: &World,
1317 insert_mode: InsertMode,
1318 ) {
1319 let Some(info) = world.components().get_info(id) else {
1320 return;
1321 };
1322
1323 let iter = info
1324 .required_components()
1325 .iter_ids()
1326 .filter(|id| !self.allow.contains_key(id))
1327 .inspect(|id| {
1328 self.required
1330 .entry(*id)
1331 .and_modify(|required| {
1332 required.required_by += 1;
1333 required.required_by_reduced += 1;
1334 })
1335 .or_insert(Required {
1336 required_by: 1,
1337 required_by_reduced: 1,
1338 });
1339 });
1340
1341 let start = self.required_of_allow.len();
1342 self.required_of_allow.extend(iter);
1343 let end = self.required_of_allow.len();
1344
1345 self.allow.insert(
1346 id,
1347 Explicit {
1348 insert_mode,
1349 required_range: Some(start..end),
1350 },
1351 );
1352 }
1353}
1354
1355struct Explicit {
1357 insert_mode: InsertMode,
1361
1362 required_range: Option<Range<usize>>,
1371}
1372
1373struct Required {
1374 required_by: u32,
1376
1377 required_by_reduced: u32,
1385}
1386
1387impl Required {
1388 #[inline]
1390 fn reset(&mut self) {
1391 self.required_by_reduced = self.required_by;
1392 }
1393}
1394
1395mod private {
1396 use crate::{bundle::BundleId, component::ComponentId};
1397 use core::any::TypeId;
1398 use derive_more::From;
1399
1400 pub trait Marker {}
1402 pub struct ScalarType {}
1404 impl Marker for ScalarType {}
1405 pub struct VectorType {}
1407 impl Marker for VectorType {}
1408
1409 #[derive(From)]
1411 pub enum FilterableId {
1412 Type(TypeId),
1413 Component(ComponentId),
1414 Bundle(BundleId),
1415 }
1416
1417 impl<'a, T> From<&'a T> for FilterableId
1418 where
1419 T: Into<FilterableId> + Copy,
1420 {
1421 #[inline]
1422 fn from(value: &'a T) -> Self {
1423 (*value).into()
1424 }
1425 }
1426
1427 pub trait FilterableIds<M: Marker> {
1438 fn filter_ids(self, ids: &mut impl FnMut(FilterableId));
1440 }
1441
1442 impl<I, T> FilterableIds<VectorType> for I
1443 where
1444 I: IntoIterator<Item = T>,
1445 T: Into<FilterableId>,
1446 {
1447 #[inline]
1448 fn filter_ids(self, ids: &mut impl FnMut(FilterableId)) {
1449 for id in self.into_iter() {
1450 ids(id.into());
1451 }
1452 }
1453 }
1454
1455 impl<T> FilterableIds<ScalarType> for T
1456 where
1457 T: Into<FilterableId>,
1458 {
1459 #[inline]
1460 fn filter_ids(self, ids: &mut impl FnMut(FilterableId)) {
1461 ids(self.into());
1462 }
1463 }
1464}
1465
1466use private::{FilterableId, FilterableIds, Marker};
1467
1468#[cfg(test)]
1469mod tests {
1470 use super::*;
1471 use crate::{
1472 component::{ComponentDescriptor, StorageType},
1473 lifecycle::HookContext,
1474 prelude::{ChildOf, Children, Resource},
1475 world::{DeferredWorld, FromWorld, World},
1476 };
1477 use bevy_ptr::OwningPtr;
1478 use core::marker::PhantomData;
1479 use core::{alloc::Layout, ops::Deref};
1480
1481 #[cfg(feature = "bevy_reflect")]
1482 mod reflect {
1483 use super::*;
1484 use crate::reflect::{AppTypeRegistry, ReflectComponent, ReflectFromWorld};
1485 use alloc::vec;
1486 use bevy_reflect::{std_traits::ReflectDefault, CreateTypeData, Reflect, ReflectFromPtr};
1487
1488 #[test]
1489 fn clone_entity_using_reflect() {
1490 #[derive(Component, Reflect, Clone, PartialEq, Eq)]
1491 #[reflect(Component)]
1492 struct A {
1493 field: usize,
1494 }
1495
1496 let mut world = World::default();
1497 world.init_resource::<AppTypeRegistry>();
1498 let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1499 registry.write().register::<A>();
1500
1501 world.register_component::<A>();
1502 let component = A { field: 5 };
1503
1504 let e = world.spawn(component.clone()).id();
1505 let e_clone = world.spawn_empty().id();
1506
1507 EntityCloner::build_opt_out(&mut world)
1508 .override_clone_behavior::<A>(ComponentCloneBehavior::reflect())
1509 .clone_entity(e, e_clone);
1510
1511 assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1512 }
1513
1514 #[test]
1515 fn clone_entity_using_reflect_all_paths() {
1516 #[derive(PartialEq, Eq, Default, Debug)]
1517 struct NotClone;
1518
1519 #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1521 #[reflect(from_reflect = false)]
1522 struct A {
1523 field: usize,
1524 field2: Vec<usize>,
1525 }
1526
1527 #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1529 #[reflect(Default)]
1530 #[reflect(from_reflect = false)]
1531 struct B {
1532 field: usize,
1533 field2: Vec<usize>,
1534 #[reflect(ignore)]
1535 ignored: NotClone,
1536 }
1537
1538 #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1540 struct C {
1541 field: usize,
1542 field2: Vec<usize>,
1543 #[reflect(ignore)]
1544 ignored: NotClone,
1545 }
1546
1547 #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1549 #[reflect(FromWorld)]
1550 #[reflect(from_reflect = false)]
1551 struct D {
1552 field: usize,
1553 field2: Vec<usize>,
1554 #[reflect(ignore)]
1555 ignored: NotClone,
1556 }
1557
1558 let mut world = World::default();
1559 world.init_resource::<AppTypeRegistry>();
1560 let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1561 registry.write().register::<(A, B, C, D)>();
1562
1563 let a_id = world.register_component::<A>();
1564 let b_id = world.register_component::<B>();
1565 let c_id = world.register_component::<C>();
1566 let d_id = world.register_component::<D>();
1567 let component_a = A {
1568 field: 5,
1569 field2: vec![1, 2, 3, 4, 5],
1570 };
1571 let component_b = B {
1572 field: 5,
1573 field2: vec![1, 2, 3, 4, 5],
1574 ignored: NotClone,
1575 };
1576 let component_c = C {
1577 field: 6,
1578 field2: vec![1, 2, 3, 4, 5],
1579 ignored: NotClone,
1580 };
1581 let component_d = D {
1582 field: 7,
1583 field2: vec![1, 2, 3, 4, 5],
1584 ignored: NotClone,
1585 };
1586
1587 let e = world
1588 .spawn((component_a, component_b, component_c, component_d))
1589 .id();
1590 let e_clone = world.spawn_empty().id();
1591
1592 EntityCloner::build_opt_out(&mut world)
1593 .override_clone_behavior_with_id(a_id, ComponentCloneBehavior::reflect())
1594 .override_clone_behavior_with_id(b_id, ComponentCloneBehavior::reflect())
1595 .override_clone_behavior_with_id(c_id, ComponentCloneBehavior::reflect())
1596 .override_clone_behavior_with_id(d_id, ComponentCloneBehavior::reflect())
1597 .clone_entity(e, e_clone);
1598
1599 assert_eq!(world.get::<A>(e_clone), Some(world.get::<A>(e).unwrap()));
1600 assert_eq!(world.get::<B>(e_clone), Some(world.get::<B>(e).unwrap()));
1601 assert_eq!(world.get::<C>(e_clone), Some(world.get::<C>(e).unwrap()));
1602 assert_eq!(world.get::<D>(e_clone), Some(world.get::<D>(e).unwrap()));
1603 }
1604
1605 #[test]
1606 fn read_source_component_reflect_should_return_none_on_invalid_reflect_from_ptr() {
1607 #[derive(Component, Reflect)]
1608 struct A;
1609
1610 #[derive(Component, Reflect)]
1611 struct B;
1612
1613 fn test_handler(source: &SourceComponent, ctx: &mut ComponentCloneCtx) {
1614 let registry = ctx.type_registry().unwrap();
1615 assert!(source.read_reflect(®istry.read()).is_none());
1616 }
1617
1618 let mut world = World::default();
1619 world.init_resource::<AppTypeRegistry>();
1620 let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1621 {
1622 let mut registry = registry.write();
1623 registry.register::<A>();
1624 registry
1625 .get_mut(TypeId::of::<A>())
1626 .unwrap()
1627 .insert(<ReflectFromPtr as CreateTypeData<B>>::create_type_data(()));
1628 }
1629
1630 let e = world.spawn(A).id();
1631 let e_clone = world.spawn_empty().id();
1632
1633 EntityCloner::build_opt_out(&mut world)
1634 .override_clone_behavior::<A>(ComponentCloneBehavior::Custom(test_handler))
1635 .clone_entity(e, e_clone);
1636 }
1637
1638 #[test]
1639 fn clone_entity_specialization() {
1640 #[derive(Component, Reflect, PartialEq, Eq)]
1641 #[reflect(Component)]
1642 struct A {
1643 field: usize,
1644 }
1645
1646 impl Clone for A {
1647 fn clone(&self) -> Self {
1648 Self { field: 10 }
1649 }
1650 }
1651
1652 let mut world = World::default();
1653 world.init_resource::<AppTypeRegistry>();
1654 let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1655 registry.write().register::<A>();
1656
1657 let component = A { field: 5 };
1658
1659 let e = world.spawn(component.clone()).id();
1660 let e_clone = world.spawn_empty().id();
1661
1662 EntityCloner::build_opt_out(&mut world).clone_entity(e, e_clone);
1663
1664 assert!(world
1665 .get::<A>(e_clone)
1666 .is_some_and(|comp| *comp == A { field: 10 }));
1667 }
1668
1669 #[test]
1670 fn clone_entity_using_reflect_should_skip_without_panic() {
1671 #[derive(Component, PartialEq, Eq, Default, Debug)]
1673 struct A;
1674
1675 #[derive(Component, Reflect, PartialEq, Eq, Default, Debug)]
1677 #[reflect(Component)]
1678 #[reflect(from_reflect = false)]
1679 struct B(#[reflect(ignore)] PhantomData<()>);
1680
1681 let mut world = World::default();
1682
1683 let e = world.spawn((A, B(Default::default()))).id();
1685 let e_clone = world.spawn_empty().id();
1686 EntityCloner::build_opt_out(&mut world)
1687 .override_clone_behavior::<A>(ComponentCloneBehavior::reflect())
1688 .override_clone_behavior::<B>(ComponentCloneBehavior::reflect())
1689 .clone_entity(e, e_clone);
1690 assert_eq!(world.get::<A>(e_clone), None);
1691 assert_eq!(world.get::<B>(e_clone), None);
1692
1693 world.init_resource::<AppTypeRegistry>();
1695 let registry = world.get_resource::<AppTypeRegistry>().unwrap();
1696 registry.write().register::<B>();
1697
1698 let e = world.spawn((A, B(Default::default()))).id();
1699 let e_clone = world.spawn_empty().id();
1700 EntityCloner::build_opt_out(&mut world).clone_entity(e, e_clone);
1701 assert_eq!(world.get::<A>(e_clone), None);
1702 assert_eq!(world.get::<B>(e_clone), None);
1703 }
1704
1705 #[test]
1706 fn clone_with_reflect_from_world() {
1707 #[derive(Component, Reflect, PartialEq, Eq, Debug)]
1708 #[reflect(Component, FromWorld, from_reflect = false)]
1709 struct SomeRef(
1710 #[entities] Entity,
1711 #[reflect(ignore)] PhantomData<()>,
1713 );
1714
1715 #[derive(Resource)]
1716 struct FromWorldCalled(bool);
1717
1718 impl FromWorld for SomeRef {
1719 fn from_world(world: &mut World) -> Self {
1720 world.insert_resource(FromWorldCalled(true));
1721 SomeRef(world.spawn_empty().id(), Default::default())
1722 }
1723 }
1724 let mut world = World::new();
1725 let registry = AppTypeRegistry::default();
1726 registry.write().register::<SomeRef>();
1727 world.insert_resource(registry);
1728
1729 let a = world.spawn_empty().id();
1730 let b = world.spawn_empty().id();
1731 let c = world.spawn(SomeRef(a, Default::default())).id();
1732 let d = world.spawn_empty().id();
1733 let mut map = EntityHashMap::<Entity>::new();
1734 map.insert(a, b);
1735 map.insert(c, d);
1736
1737 let cloned = EntityCloner::default().clone_entity_mapped(&mut world, c, &mut map);
1738 assert_eq!(
1739 *world.entity(cloned).get::<SomeRef>().unwrap(),
1740 SomeRef(b, Default::default())
1741 );
1742 assert!(world.resource::<FromWorldCalled>().0);
1743 }
1744 }
1745
1746 #[test]
1747 fn clone_entity_using_clone() {
1748 #[derive(Component, Clone, PartialEq, Eq)]
1749 struct A {
1750 field: usize,
1751 }
1752
1753 let mut world = World::default();
1754
1755 let component = A { field: 5 };
1756
1757 let e = world.spawn(component.clone()).id();
1758 let e_clone = world.spawn_empty().id();
1759
1760 EntityCloner::build_opt_out(&mut world).clone_entity(e, e_clone);
1761
1762 assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1763 }
1764
1765 #[test]
1766 fn clone_entity_with_allow_filter() {
1767 #[derive(Component, Clone, PartialEq, Eq)]
1768 struct A {
1769 field: usize,
1770 }
1771
1772 #[derive(Component, Clone)]
1773 struct B;
1774
1775 let mut world = World::default();
1776
1777 let component = A { field: 5 };
1778
1779 let e = world.spawn((component.clone(), B)).id();
1780 let e_clone = world.spawn_empty().id();
1781
1782 EntityCloner::build_opt_in(&mut world)
1783 .allow::<A>()
1784 .clone_entity(e, e_clone);
1785
1786 assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1787 assert!(world.get::<B>(e_clone).is_none());
1788 }
1789
1790 #[test]
1791 fn clone_entity_with_deny_filter() {
1792 #[derive(Component, Clone, PartialEq, Eq)]
1793 struct A {
1794 field: usize,
1795 }
1796
1797 #[derive(Component, Clone)]
1798 #[require(C)]
1799 struct B;
1800
1801 #[derive(Component, Clone, Default)]
1802 struct C;
1803
1804 let mut world = World::default();
1805
1806 let component = A { field: 5 };
1807
1808 let e = world.spawn((component.clone(), B, C)).id();
1809 let e_clone = world.spawn_empty().id();
1810
1811 EntityCloner::build_opt_out(&mut world)
1812 .deny::<C>()
1813 .clone_entity(e, e_clone);
1814
1815 assert!(world.get::<A>(e_clone).is_some_and(|c| *c == component));
1816 assert!(world.get::<B>(e_clone).is_none());
1817 assert!(world.get::<C>(e_clone).is_none());
1818 }
1819
1820 #[test]
1821 fn clone_entity_with_deny_filter_without_required_by() {
1822 #[derive(Component, Clone)]
1823 #[require(B { field: 5 })]
1824 struct A;
1825
1826 #[derive(Component, Clone, PartialEq, Eq)]
1827 struct B {
1828 field: usize,
1829 }
1830
1831 let mut world = World::default();
1832
1833 let e = world.spawn((A, B { field: 10 })).id();
1834 let e_clone = world.spawn_empty().id();
1835
1836 EntityCloner::build_opt_out(&mut world)
1837 .without_required_by_components(|builder| {
1838 builder.deny::<B>();
1839 })
1840 .clone_entity(e, e_clone);
1841
1842 assert!(world.get::<A>(e_clone).is_some());
1843 assert!(world
1844 .get::<B>(e_clone)
1845 .is_some_and(|c| *c == B { field: 5 }));
1846 }
1847
1848 #[test]
1849 fn clone_entity_with_deny_filter_if_new() {
1850 #[derive(Component, Clone, PartialEq, Eq)]
1851 struct A {
1852 field: usize,
1853 }
1854
1855 #[derive(Component, Clone)]
1856 struct B;
1857
1858 #[derive(Component, Clone)]
1859 struct C;
1860
1861 let mut world = World::default();
1862
1863 let e = world.spawn((A { field: 5 }, B, C)).id();
1864 let e_clone = world.spawn(A { field: 8 }).id();
1865
1866 EntityCloner::build_opt_out(&mut world)
1867 .deny::<B>()
1868 .insert_mode(InsertMode::Keep)
1869 .clone_entity(e, e_clone);
1870
1871 assert!(world
1872 .get::<A>(e_clone)
1873 .is_some_and(|c| *c == A { field: 8 }));
1874 assert!(world.get::<B>(e_clone).is_none());
1875 assert!(world.get::<C>(e_clone).is_some());
1876 }
1877
1878 #[test]
1879 fn allow_and_allow_if_new_always_allows() {
1880 #[derive(Component, Clone, PartialEq, Debug)]
1881 struct A(u8);
1882
1883 let mut world = World::default();
1884 let e = world.spawn(A(1)).id();
1885 let e_clone1 = world.spawn(A(2)).id();
1886
1887 EntityCloner::build_opt_in(&mut world)
1888 .allow_if_new::<A>()
1889 .allow::<A>()
1890 .clone_entity(e, e_clone1);
1891
1892 assert_eq!(world.get::<A>(e_clone1), Some(&A(1)));
1893
1894 let e_clone2 = world.spawn(A(2)).id();
1895
1896 EntityCloner::build_opt_in(&mut world)
1897 .allow::<A>()
1898 .allow_if_new::<A>()
1899 .clone_entity(e, e_clone2);
1900
1901 assert_eq!(world.get::<A>(e_clone2), Some(&A(1)));
1902 }
1903
1904 #[test]
1905 fn with_and_without_required_components_include_required() {
1906 #[derive(Component, Clone, PartialEq, Debug)]
1907 #[require(B(5))]
1908 struct A;
1909
1910 #[derive(Component, Clone, PartialEq, Debug)]
1911 struct B(u8);
1912
1913 let mut world = World::default();
1914 let e = world.spawn((A, B(10))).id();
1915 let e_clone1 = world.spawn_empty().id();
1916 EntityCloner::build_opt_in(&mut world)
1917 .without_required_components(|builder| {
1918 builder.allow::<A>();
1919 })
1920 .allow::<A>()
1921 .clone_entity(e, e_clone1);
1922
1923 assert_eq!(world.get::<B>(e_clone1), Some(&B(10)));
1924
1925 let e_clone2 = world.spawn_empty().id();
1926
1927 EntityCloner::build_opt_in(&mut world)
1928 .allow::<A>()
1929 .without_required_components(|builder| {
1930 builder.allow::<A>();
1931 })
1932 .clone_entity(e, e_clone2);
1933
1934 assert_eq!(world.get::<B>(e_clone2), Some(&B(10)));
1935 }
1936
1937 #[test]
1938 fn clone_required_becoming_explicit() {
1939 #[derive(Component, Clone, PartialEq, Debug)]
1940 #[require(B(5))]
1941 struct A;
1942
1943 #[derive(Component, Clone, PartialEq, Debug)]
1944 struct B(u8);
1945
1946 let mut world = World::default();
1947 let e = world.spawn((A, B(10))).id();
1948 let e_clone1 = world.spawn(B(20)).id();
1949 EntityCloner::build_opt_in(&mut world)
1950 .allow::<A>()
1951 .allow::<B>()
1952 .clone_entity(e, e_clone1);
1953
1954 assert_eq!(world.get::<B>(e_clone1), Some(&B(10)));
1955
1956 let e_clone2 = world.spawn(B(20)).id();
1957 EntityCloner::build_opt_in(&mut world)
1958 .allow::<A>()
1959 .allow::<B>()
1960 .clone_entity(e, e_clone2);
1961
1962 assert_eq!(world.get::<B>(e_clone2), Some(&B(10)));
1963 }
1964
1965 #[test]
1966 fn required_not_cloned_because_requiring_missing() {
1967 #[derive(Component, Clone)]
1968 #[require(B)]
1969 struct A;
1970
1971 #[derive(Component, Clone, Default)]
1972 struct B;
1973
1974 let mut world = World::default();
1975 let e = world.spawn(B).id();
1976 let e_clone1 = world.spawn_empty().id();
1977
1978 EntityCloner::build_opt_in(&mut world)
1979 .allow::<A>()
1980 .clone_entity(e, e_clone1);
1981
1982 assert!(world.get::<B>(e_clone1).is_none());
1983 }
1984
1985 #[test]
1986 fn clone_entity_with_required_components() {
1987 #[derive(Component, Clone, PartialEq, Debug)]
1988 #[require(B)]
1989 struct A;
1990
1991 #[derive(Component, Clone, PartialEq, Debug, Default)]
1992 #[require(C(5))]
1993 struct B;
1994
1995 #[derive(Component, Clone, PartialEq, Debug)]
1996 struct C(u32);
1997
1998 let mut world = World::default();
1999
2000 let e = world.spawn(A).id();
2001 let e_clone = world.spawn_empty().id();
2002
2003 EntityCloner::build_opt_in(&mut world)
2004 .allow::<B>()
2005 .clone_entity(e, e_clone);
2006
2007 assert_eq!(world.entity(e_clone).get::<A>(), None);
2008 assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
2009 assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
2010 }
2011
2012 #[test]
2013 fn clone_entity_with_default_required_components() {
2014 #[derive(Component, Clone, PartialEq, Debug)]
2015 #[require(B)]
2016 struct A;
2017
2018 #[derive(Component, Clone, PartialEq, Debug, Default)]
2019 #[require(C(5))]
2020 struct B;
2021
2022 #[derive(Component, Clone, PartialEq, Debug)]
2023 struct C(u32);
2024
2025 let mut world = World::default();
2026
2027 let e = world.spawn((A, C(0))).id();
2028 let e_clone = world.spawn_empty().id();
2029
2030 EntityCloner::build_opt_in(&mut world)
2031 .without_required_components(|builder| {
2032 builder.allow::<A>();
2033 })
2034 .clone_entity(e, e_clone);
2035
2036 assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
2037 assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
2038 assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
2039 }
2040
2041 #[test]
2042 fn clone_entity_with_missing_required_components() {
2043 #[derive(Component, Clone, PartialEq, Debug)]
2044 #[require(B)]
2045 struct A;
2046
2047 #[derive(Component, Clone, PartialEq, Debug, Default)]
2048 #[require(C(5))]
2049 struct B;
2050
2051 #[derive(Component, Clone, PartialEq, Debug)]
2052 struct C(u32);
2053
2054 let mut world = World::default();
2055
2056 let e = world.spawn(A).remove::<C>().id();
2057 let e_clone = world.spawn_empty().id();
2058
2059 EntityCloner::build_opt_in(&mut world)
2060 .allow::<A>()
2061 .clone_entity(e, e_clone);
2062
2063 assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
2064 assert_eq!(world.entity(e_clone).get::<B>(), Some(&B));
2065 assert_eq!(world.entity(e_clone).get::<C>(), Some(&C(5)));
2066 }
2067
2068 #[test]
2069 fn skipped_required_components_counter_is_reset_on_early_return() {
2070 #[derive(Component, Clone, PartialEq, Debug, Default)]
2071 #[require(B(5))]
2072 struct A;
2073
2074 #[derive(Component, Clone, PartialEq, Debug)]
2075 struct B(u32);
2076
2077 #[derive(Component, Clone, PartialEq, Debug, Default)]
2078 struct C;
2079
2080 let mut world = World::default();
2081
2082 let e1 = world.spawn(C).id();
2083 let e2 = world.spawn((A, B(0))).id();
2084 let e_clone = world.spawn_empty().id();
2085
2086 let mut builder = EntityCloner::build_opt_in(&mut world);
2087 builder.allow::<(A, C)>();
2088 let mut cloner = builder.finish();
2089 cloner.clone_entity(&mut world, e1, e_clone);
2090 cloner.clone_entity(&mut world, e2, e_clone);
2091
2092 assert_eq!(world.entity(e_clone).get::<B>(), Some(&B(0)));
2093 }
2094
2095 #[test]
2096 fn clone_entity_with_dynamic_components() {
2097 const COMPONENT_SIZE: usize = 10;
2098 fn test_handler(source: &SourceComponent, ctx: &mut ComponentCloneCtx) {
2099 unsafe {
2101 ctx.write_target_component_ptr(source.ptr());
2102 }
2103 }
2104
2105 let mut world = World::default();
2106
2107 let layout = Layout::array::<u8>(COMPONENT_SIZE).unwrap();
2108 let descriptor = unsafe {
2112 ComponentDescriptor::new_with_layout(
2113 "DynamicComp",
2114 StorageType::Table,
2115 layout,
2116 None,
2117 true,
2118 false,
2119 ComponentCloneBehavior::Custom(test_handler),
2120 None,
2121 )
2122 };
2123 let component_id = world.register_component_with_descriptor(descriptor);
2124
2125 let mut entity = world.spawn_empty();
2126 let data = [5u8; COMPONENT_SIZE];
2127
2128 OwningPtr::make(data, |ptr| unsafe {
2132 entity.insert_by_id(component_id, ptr);
2133 });
2134 let entity = entity.id();
2135
2136 let entity_clone = world.spawn_empty().id();
2137 EntityCloner::build_opt_out(&mut world).clone_entity(entity, entity_clone);
2138
2139 let ptr = world.get_by_id(entity, component_id).unwrap();
2140 let clone_ptr = world.get_by_id(entity_clone, component_id).unwrap();
2141 unsafe {
2143 assert_eq!(
2144 core::slice::from_raw_parts(ptr.as_ptr(), COMPONENT_SIZE),
2145 core::slice::from_raw_parts(clone_ptr.as_ptr(), COMPONENT_SIZE),
2146 );
2147 }
2148 }
2149
2150 #[test]
2151 fn recursive_clone() {
2152 let mut world = World::new();
2153 let root = world.spawn_empty().id();
2154 let child1 = world.spawn(ChildOf(root)).id();
2155 let grandchild = world.spawn(ChildOf(child1)).id();
2156 let child2 = world.spawn(ChildOf(root)).id();
2157
2158 let clone_root = world.spawn_empty().id();
2159 EntityCloner::build_opt_out(&mut world)
2160 .linked_cloning(true)
2161 .clone_entity(root, clone_root);
2162
2163 let root_children = world
2164 .entity(clone_root)
2165 .get::<Children>()
2166 .unwrap()
2167 .iter()
2168 .cloned()
2169 .collect::<Vec<_>>();
2170
2171 assert!(root_children.iter().all(|e| *e != child1 && *e != child2));
2172 assert_eq!(root_children.len(), 2);
2173 assert_eq!(
2174 (
2175 world.get::<ChildOf>(root_children[0]),
2176 world.get::<ChildOf>(root_children[1])
2177 ),
2178 (Some(&ChildOf(clone_root)), Some(&ChildOf(clone_root)))
2179 );
2180 let child1_children = world.entity(root_children[0]).get::<Children>().unwrap();
2181 assert_eq!(child1_children.len(), 1);
2182 assert_ne!(child1_children[0], grandchild);
2183 assert!(world.entity(root_children[1]).get::<Children>().is_none());
2184 assert_eq!(
2185 world.get::<ChildOf>(child1_children[0]),
2186 Some(&ChildOf(root_children[0]))
2187 );
2188
2189 assert_eq!(
2190 world.entity(root).get::<Children>().unwrap().deref(),
2191 &[child1, child2]
2192 );
2193 }
2194
2195 #[test]
2196 fn cloning_with_required_components_preserves_existing() {
2197 #[derive(Component, Clone, PartialEq, Debug, Default)]
2198 #[require(B(5))]
2199 struct A;
2200
2201 #[derive(Component, Clone, PartialEq, Debug)]
2202 struct B(u32);
2203
2204 let mut world = World::default();
2205
2206 let e = world.spawn((A, B(0))).id();
2207 let e_clone = world.spawn(B(1)).id();
2208
2209 EntityCloner::build_opt_in(&mut world)
2210 .allow::<A>()
2211 .clone_entity(e, e_clone);
2212
2213 assert_eq!(world.entity(e_clone).get::<A>(), Some(&A));
2214 assert_eq!(world.entity(e_clone).get::<B>(), Some(&B(1)));
2215 }
2216
2217 #[test]
2218 fn move_without_clone() {
2219 #[derive(Component, PartialEq, Debug)]
2220 #[component(storage = "SparseSet")]
2221 struct A;
2222
2223 #[derive(Component, PartialEq, Debug)]
2224 struct B(Vec<u8>);
2225
2226 let mut world = World::default();
2227 let e = world.spawn((A, B(alloc::vec![1, 2, 3]))).id();
2228 let e_clone = world.spawn_empty().id();
2229 let mut builder = EntityCloner::build_opt_out(&mut world);
2230 builder.move_components(true);
2231 let mut cloner = builder.finish();
2232
2233 cloner.clone_entity(&mut world, e, e_clone);
2234
2235 assert_eq!(world.get::<A>(e), None);
2236 assert_eq!(world.get::<B>(e), None);
2237
2238 assert_eq!(world.get::<A>(e_clone), Some(&A));
2239 assert_eq!(world.get::<B>(e_clone), Some(&B(alloc::vec![1, 2, 3])));
2240 }
2241
2242 #[test]
2243 fn move_with_remove_hook() {
2244 #[derive(Component, PartialEq, Debug)]
2245 #[component(on_remove=remove_hook)]
2246 struct B(Option<Vec<u8>>);
2247
2248 fn remove_hook(mut world: DeferredWorld, ctx: HookContext) {
2249 world.get_mut::<B>(ctx.entity).unwrap().0.take();
2250 }
2251
2252 let mut world = World::default();
2253 let e = world.spawn(B(Some(alloc::vec![1, 2, 3]))).id();
2254 let e_clone = world.spawn_empty().id();
2255 let mut builder = EntityCloner::build_opt_out(&mut world);
2256 builder.move_components(true);
2257 let mut cloner = builder.finish();
2258
2259 cloner.clone_entity(&mut world, e, e_clone);
2260
2261 assert_eq!(world.get::<B>(e), None);
2262 assert_eq!(world.get::<B>(e_clone), Some(&B(None)));
2263 }
2264
2265 #[test]
2266 fn move_with_deferred() {
2267 #[derive(Component, PartialEq, Debug)]
2268 #[component(clone_behavior=Custom(custom))]
2269 struct A(u32);
2270
2271 #[derive(Component, PartialEq, Debug)]
2272 struct B(u32);
2273
2274 fn custom(_src: &SourceComponent, ctx: &mut ComponentCloneCtx) {
2275 let source = ctx.source();
2277 ctx.queue_deferred(move |world, mapper| {
2278 let target = mapper.get_mapped(source);
2279 world.entity_mut(target).insert(A(10));
2280 });
2281 }
2282
2283 let mut world = World::default();
2284 let e = world.spawn((A(0), B(1))).id();
2285 let e_clone = world.spawn_empty().id();
2286 let mut builder = EntityCloner::build_opt_out(&mut world);
2287 builder.move_components(true);
2288 let mut cloner = builder.finish();
2289
2290 cloner.clone_entity(&mut world, e, e_clone);
2291
2292 assert_eq!(world.get::<A>(e), None);
2293 assert_eq!(world.get::<A>(e_clone), Some(&A(10)));
2294 assert_eq!(world.get::<B>(e), None);
2295 assert_eq!(world.get::<B>(e_clone), Some(&B(1)));
2296 }
2297
2298 #[test]
2299 fn move_relationship() {
2300 #[derive(Component, Clone, PartialEq, Eq, Debug)]
2301 #[relationship(relationship_target=Target)]
2302 struct Source(Entity);
2303
2304 #[derive(Component, Clone, PartialEq, Eq, Debug)]
2305 #[relationship_target(relationship=Source)]
2306 struct Target(Vec<Entity>);
2307
2308 #[derive(Component, PartialEq, Debug)]
2309 struct A(u32);
2310
2311 let mut world = World::default();
2312 let e_target = world.spawn(A(1)).id();
2313 let e_source = world.spawn((A(2), Source(e_target))).id();
2314
2315 let mut builder = EntityCloner::build_opt_out(&mut world);
2316 builder.move_components(true);
2317 let mut cloner = builder.finish();
2318
2319 let e_source_moved = world.spawn_empty().id();
2320
2321 cloner.clone_entity(&mut world, e_source, e_source_moved);
2322
2323 assert_eq!(world.get::<A>(e_source), None);
2324 assert_eq!(world.get::<A>(e_source_moved), Some(&A(2)));
2325 assert_eq!(world.get::<Source>(e_source), None);
2326 assert_eq!(world.get::<Source>(e_source_moved), Some(&Source(e_target)));
2327 assert_eq!(
2328 world.get::<Target>(e_target),
2329 Some(&Target(alloc::vec![e_source_moved]))
2330 );
2331
2332 let e_target_moved = world.spawn_empty().id();
2333
2334 cloner.clone_entity(&mut world, e_target, e_target_moved);
2335
2336 assert_eq!(world.get::<A>(e_target), None);
2337 assert_eq!(world.get::<A>(e_target_moved), Some(&A(1)));
2338 assert_eq!(world.get::<Target>(e_target), None);
2339 assert_eq!(
2340 world.get::<Target>(e_target_moved),
2341 Some(&Target(alloc::vec![e_source_moved]))
2342 );
2343 assert_eq!(
2344 world.get::<Source>(e_source_moved),
2345 Some(&Source(e_target_moved))
2346 );
2347 }
2348
2349 #[test]
2350 fn move_hierarchy() {
2351 #[derive(Component, PartialEq, Debug)]
2352 struct A(u32);
2353
2354 let mut world = World::default();
2355 let e_parent = world.spawn(A(1)).id();
2356 let e_child1 = world.spawn((A(2), ChildOf(e_parent))).id();
2357 let e_child2 = world.spawn((A(3), ChildOf(e_parent))).id();
2358 let e_child1_1 = world.spawn((A(4), ChildOf(e_child1))).id();
2359
2360 let e_parent_clone = world.spawn_empty().id();
2361
2362 let mut builder = EntityCloner::build_opt_out(&mut world);
2363 builder.move_components(true).linked_cloning(true);
2364 let mut cloner = builder.finish();
2365
2366 cloner.clone_entity(&mut world, e_parent, e_parent_clone);
2367
2368 assert_eq!(world.get::<A>(e_parent), None);
2369 assert_eq!(world.get::<A>(e_child1), None);
2370 assert_eq!(world.get::<A>(e_child2), None);
2371 assert_eq!(world.get::<A>(e_child1_1), None);
2372
2373 let mut children = world.get::<Children>(e_parent_clone).unwrap().iter();
2374 let e_child1_clone = *children.next().unwrap();
2375 let e_child2_clone = *children.next().unwrap();
2376 let mut children = world.get::<Children>(e_child1_clone).unwrap().iter();
2377 let e_child1_1_clone = *children.next().unwrap();
2378
2379 assert_eq!(world.get::<A>(e_parent_clone), Some(&A(1)));
2380 assert_eq!(world.get::<A>(e_child1_clone), Some(&A(2)));
2381 assert_eq!(
2382 world.get::<ChildOf>(e_child1_clone),
2383 Some(&ChildOf(e_parent_clone))
2384 );
2385 assert_eq!(world.get::<A>(e_child2_clone), Some(&A(3)));
2386 assert_eq!(
2387 world.get::<ChildOf>(e_child2_clone),
2388 Some(&ChildOf(e_parent_clone))
2389 );
2390 assert_eq!(world.get::<A>(e_child1_1_clone), Some(&A(4)));
2391 assert_eq!(
2392 world.get::<ChildOf>(e_child1_1_clone),
2393 Some(&ChildOf(e_child1_clone))
2394 );
2395 }
2396
2397 #[test]
2402 fn clone_relationship_with_data() {
2403 #[derive(Component, Clone)]
2404 #[relationship(relationship_target=Target)]
2405 struct Source {
2406 #[relationship]
2407 target: Entity,
2408 data: Vec<u8>,
2409 }
2410
2411 #[derive(Component, Clone)]
2412 #[relationship_target(relationship=Source)]
2413 struct Target {
2414 #[relationship]
2415 target: Vec<Entity>,
2416 data: Vec<u8>,
2417 }
2418
2419 let mut world = World::default();
2420 let e_target = world.spawn_empty().id();
2421 let e_source = world
2422 .spawn(Source {
2423 target: e_target,
2424 data: alloc::vec![1, 2, 3],
2425 })
2426 .id();
2427 world.get_mut::<Target>(e_target).unwrap().data = alloc::vec![4, 5, 6];
2428
2429 let builder = EntityCloner::build_opt_out(&mut world);
2430 let mut cloner = builder.finish();
2431
2432 let e_target_clone = world.spawn_empty().id();
2433 cloner.clone_entity(&mut world, e_target, e_target_clone);
2434
2435 let target = world.get::<Target>(e_target).unwrap();
2436 let cloned_target = world.get::<Target>(e_target_clone).unwrap();
2437
2438 assert_eq!(cloned_target.data, target.data);
2439 assert_eq!(target.target, alloc::vec![e_source]);
2440 assert_eq!(cloned_target.target.len(), 0);
2441
2442 let source = world.get::<Source>(e_source).unwrap();
2443
2444 assert_eq!(source.data, alloc::vec![1, 2, 3]);
2445 }
2446
2447 #[test]
2453 fn clone_linked_relationship_with_data() {
2454 #[derive(Component, Clone)]
2455 #[relationship(relationship_target=Target)]
2456 struct Source {
2457 #[relationship]
2458 target: Entity,
2459 data: Vec<u8>,
2460 }
2461
2462 #[derive(Component, Clone)]
2463 #[relationship_target(relationship=Source, linked_spawn)]
2464 struct Target {
2465 #[relationship]
2466 target: Vec<Entity>,
2467 data: Vec<u8>,
2468 }
2469
2470 let mut world = World::default();
2471 let e_target = world.spawn_empty().id();
2472 let e_source = world
2473 .spawn(Source {
2474 target: e_target,
2475 data: alloc::vec![1, 2, 3],
2476 })
2477 .id();
2478 world.get_mut::<Target>(e_target).unwrap().data = alloc::vec![4, 5, 6];
2479
2480 let mut builder = EntityCloner::build_opt_out(&mut world);
2481 builder.linked_cloning(true);
2482 let mut cloner = builder.finish();
2483
2484 let e_target_clone = world.spawn_empty().id();
2485 cloner.clone_entity(&mut world, e_target, e_target_clone);
2486
2487 let target = world.get::<Target>(e_target).unwrap();
2488 let cloned_target = world.get::<Target>(e_target_clone).unwrap();
2489
2490 assert_eq!(cloned_target.data, target.data);
2491 assert_eq!(target.target, alloc::vec![e_source]);
2492 assert_eq!(cloned_target.target.len(), 1);
2493
2494 let source = world.get::<Source>(e_source).unwrap();
2495 let cloned_source = world.get::<Source>(cloned_target.target[0]).unwrap();
2496
2497 assert_eq!(cloned_source.data, source.data);
2498 assert_eq!(source.target, e_target);
2499 assert_eq!(cloned_source.target, e_target_clone);
2500 }
2501
2502 #[test]
2507 fn move_relationship_with_data() {
2508 #[derive(Component, Clone, PartialEq, Eq, Debug)]
2509 #[relationship(relationship_target=Target)]
2510 struct Source {
2511 #[relationship]
2512 target: Entity,
2513 data: Vec<u8>,
2514 }
2515
2516 #[derive(Component, Clone, PartialEq, Eq, Debug)]
2517 #[relationship_target(relationship=Source)]
2518 struct Target {
2519 #[relationship]
2520 target: Vec<Entity>,
2521 data: Vec<u8>,
2522 }
2523
2524 let source_data = alloc::vec![1, 2, 3];
2525 let target_data = alloc::vec![4, 5, 6];
2526
2527 let mut world = World::default();
2528 let e_target = world.spawn_empty().id();
2529 let e_source = world
2530 .spawn(Source {
2531 target: e_target,
2532 data: source_data.clone(),
2533 })
2534 .id();
2535 world.get_mut::<Target>(e_target).unwrap().data = target_data.clone();
2536
2537 let mut builder = EntityCloner::build_opt_out(&mut world);
2538 builder.move_components(true);
2539 let mut cloner = builder.finish();
2540
2541 let e_target_moved = world.spawn_empty().id();
2542 cloner.clone_entity(&mut world, e_target, e_target_moved);
2543
2544 assert_eq!(world.get::<Target>(e_target), None);
2545 assert_eq!(
2546 world.get::<Source>(e_source),
2547 Some(&Source {
2548 data: source_data,
2549 target: e_target_moved,
2550 })
2551 );
2552 assert_eq!(
2553 world.get::<Target>(e_target_moved),
2554 Some(&Target {
2555 target: alloc::vec![e_source],
2556 data: target_data
2557 })
2558 );
2559 }
2560
2561 #[test]
2567 fn move_linked_relationship_with_data() {
2568 #[derive(Component, Clone, PartialEq, Eq, Debug)]
2569 #[relationship(relationship_target=Target)]
2570 struct Source {
2571 #[relationship]
2572 target: Entity,
2573 data: Vec<u8>,
2574 }
2575
2576 #[derive(Component, Clone, PartialEq, Eq, Debug)]
2577 #[relationship_target(relationship=Source, linked_spawn)]
2578 struct Target {
2579 #[relationship]
2580 target: Vec<Entity>,
2581 data: Vec<u8>,
2582 }
2583
2584 let source_data = alloc::vec![1, 2, 3];
2585 let target_data = alloc::vec![4, 5, 6];
2586
2587 let mut world = World::default();
2588 let e_target = world.spawn_empty().id();
2589 let e_source = world
2590 .spawn(Source {
2591 target: e_target,
2592 data: source_data.clone(),
2593 })
2594 .id();
2595 world.get_mut::<Target>(e_target).unwrap().data = target_data.clone();
2596
2597 let mut builder = EntityCloner::build_opt_out(&mut world);
2598 builder.move_components(true).linked_cloning(true);
2599 let mut cloner = builder.finish();
2600
2601 let e_target_moved = world.spawn_empty().id();
2602 cloner.clone_entity(&mut world, e_target, e_target_moved);
2603
2604 assert_eq!(world.get::<Target>(e_target), None);
2605 assert_eq!(world.get::<Source>(e_source), None);
2606
2607 let moved_target = world.get::<Target>(e_target_moved).unwrap();
2608 assert_eq!(moved_target.data, target_data);
2609 assert_eq!(moved_target.target.len(), 1);
2610
2611 let moved_source = world.get::<Source>(moved_target.target[0]).unwrap();
2612 assert_eq!(moved_source.data, source_data);
2613 assert_eq!(moved_source.target, e_target_moved);
2614 }
2615}