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