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