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