Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/entity/clone_entities.rs
6849 views
1
use alloc::{boxed::Box, collections::VecDeque, vec::Vec};
2
use bevy_platform::collections::{hash_map::Entry, HashMap, HashSet};
3
use bevy_ptr::{Ptr, PtrMut};
4
use bevy_utils::prelude::DebugName;
5
use bumpalo::Bump;
6
use core::{any::TypeId, cell::LazyCell, ops::Range};
7
use derive_more::derive::From;
8
9
use 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
20
/// Provides read access to the source component (the component being cloned) in a [`ComponentCloneFn`].
21
pub struct SourceComponent<'a> {
22
ptr: Ptr<'a>,
23
info: &'a ComponentInfo,
24
}
25
26
impl<'a> SourceComponent<'a> {
27
/// Returns a reference to the component on the source entity.
28
///
29
/// Will return `None` if `ComponentId` of requested component does not match `ComponentId` of source component
30
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
// SAFETY:
37
// - Components and ComponentId are from the same world
38
// - source_component_ptr holds valid data of the type referenced by ComponentId
39
unsafe { Some(self.ptr.deref::<C>()) }
40
} else {
41
None
42
}
43
}
44
45
/// Returns the "raw" pointer to the source component.
46
pub fn ptr(&self) -> Ptr<'a> {
47
self.ptr
48
}
49
50
/// Returns a reference to the component on the source entity as [`&dyn Reflect`](bevy_reflect::Reflect).
51
///
52
/// Will return `None` if:
53
/// - World does not have [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`).
54
/// - Component does not implement [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr).
55
/// - Component is not registered.
56
/// - Component does not have [`TypeId`]
57
/// - Registered [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr)'s [`TypeId`] does not match component's [`TypeId`]
58
#[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
// SAFETY: `source_component_ptr` stores data represented by `component_id`, which we used to get `ReflectFromPtr`.
69
unsafe { Some(reflect_from_ptr.as_reflect(self.ptr)) }
70
}
71
}
72
73
/// Context for component clone handlers.
74
///
75
/// Provides fast access to useful resources like [`AppTypeRegistry`](crate::reflect::AppTypeRegistry)
76
/// and allows component clone handler to get information about component being cloned.
77
pub 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
96
impl<'a, 'b> ComponentCloneCtx<'a, 'b> {
97
/// Create a new instance of `ComponentCloneCtx` that can be passed to component clone handlers.
98
///
99
/// # Safety
100
/// Caller must ensure that:
101
/// - `component_info` corresponds to the `component_id` in the same world,.
102
/// - `source_component_ptr` points to a valid component of type represented by `component_id`.
103
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
/// Returns true if [`write_target_component`](`Self::write_target_component`) was called before.
133
pub fn target_component_written(&self) -> bool {
134
self.target_component_written
135
}
136
137
/// Returns `true` if used in moving context
138
pub fn moving(&self) -> bool {
139
self.state.move_components
140
}
141
142
/// Returns the current source entity.
143
pub fn source(&self) -> Entity {
144
self.source
145
}
146
147
/// Returns the current target entity.
148
pub fn target(&self) -> Entity {
149
self.target
150
}
151
152
/// Returns the [`ComponentId`] of the component being cloned.
153
pub fn component_id(&self) -> ComponentId {
154
self.component_id
155
}
156
157
/// Returns the [`ComponentInfo`] of the component being cloned.
158
pub fn component_info(&self) -> &ComponentInfo {
159
self.component_info
160
}
161
162
/// Returns true if the [`EntityCloner`] is configured to recursively clone entities. When this is enabled,
163
/// entities stored in a cloned entity's [`RelationshipTarget`](crate::relationship::RelationshipTarget) component with
164
/// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN) will also be cloned.
165
#[inline]
166
pub fn linked_cloning(&self) -> bool {
167
self.state.linked_cloning
168
}
169
170
/// Returns this context's [`EntityMapper`].
171
pub fn entity_mapper(&mut self) -> &mut dyn EntityMapper {
172
self.mapper
173
}
174
175
/// Writes component data to target entity.
176
///
177
/// # Panics
178
/// This will panic if:
179
/// - Component has already been written once.
180
/// - Component being written is not registered in the world.
181
/// - `ComponentId` of component being written does not match expected `ComponentId`.
182
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
// SAFETY: the TypeId of self.component_id has been checked to ensure it matches `C`
197
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
/// Writes component data to target entity by providing a pointer to source component data.
205
///
206
/// # Safety
207
/// Caller must ensure that the passed in `ptr` references data that corresponds to the type of the source / target [`ComponentId`].
208
/// `ptr` must also contain data that the written component can "own" (for example, this should not directly copy non-Copy data).
209
///
210
/// # Panics
211
/// This will panic if component has already been written once.
212
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
/// Writes component data to target entity.
225
///
226
/// # Panics
227
/// This will panic if:
228
/// - World does not have [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`).
229
/// - Component does not implement [`ReflectFromPtr`](bevy_reflect::ReflectFromPtr).
230
/// - Source component does not have [`TypeId`].
231
/// - Passed component's [`TypeId`] does not match source component [`TypeId`].
232
/// - Component has already been written once.
233
#[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
// SAFETY:
252
// - target_component_data_ptr and component_data have the same data type.
253
// - component_data_ptr has layout of component_layout
254
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
// Ensure we don't attempt to deallocate zero-sized components
265
alloc::alloc::dealloc(component_data_ptr, component_layout);
266
}
267
}
268
269
self.target_component_written = true;
270
}
271
272
/// Returns [`AppTypeRegistry`](`crate::reflect::AppTypeRegistry`) if it exists in the world.
273
///
274
/// NOTE: Prefer this method instead of manually reading the resource from the world.
275
#[cfg(feature = "bevy_reflect")]
276
pub fn type_registry(&self) -> Option<&crate::reflect::AppTypeRegistry> {
277
self.type_registry
278
}
279
280
/// Queues the `entity` to be cloned by the current [`EntityCloner`]
281
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
/// Queues a deferred clone operation, which will run with exclusive [`World`] access immediately after calling the clone handler for each component on an entity.
288
/// This exists, despite its similarity to [`Commands`](crate::system::Commands), to provide access to the entity mapper in the current context.
289
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
/// Marks component as moved and it's `drop` won't run.
297
fn move_component(&mut self) {
298
self.target_component_moved = true;
299
self.target_component_written = true;
300
}
301
}
302
303
/// A configuration determining how to clone entities. This can be built using [`EntityCloner::build_opt_out`]/
304
/// [`opt_in`](EntityCloner::build_opt_in), which
305
/// returns an [`EntityClonerBuilder`].
306
///
307
/// After configuration is complete an entity can be cloned using [`Self::clone_entity`].
308
///
309
///```
310
/// use bevy_ecs::prelude::*;
311
/// use bevy_ecs::entity::EntityCloner;
312
///
313
/// #[derive(Component, Clone, PartialEq, Eq)]
314
/// struct A {
315
/// field: usize,
316
/// }
317
///
318
/// let mut world = World::default();
319
///
320
/// let component = A { field: 5 };
321
///
322
/// let entity = world.spawn(component.clone()).id();
323
/// let entity_clone = world.spawn_empty().id();
324
///
325
/// EntityCloner::build_opt_out(&mut world).clone_entity(entity, entity_clone);
326
///
327
/// assert!(world.get::<A>(entity_clone).is_some_and(|c| *c == component));
328
///```
329
///
330
/// # Default cloning strategy
331
/// By default, all types that derive [`Component`] and implement either [`Clone`] or `Reflect` (with `ReflectComponent`) will be cloned
332
/// (with `Clone`-based implementation preferred in case component implements both).
333
///
334
/// It should be noted that if `Component` is implemented manually or if `Clone` implementation is conditional
335
/// (like when deriving `Clone` for a type with a generic parameter without `Clone` bound),
336
/// the component will be cloned using the [default cloning strategy](crate::component::ComponentCloneBehavior::global_default_fn).
337
/// To use `Clone`-based handler ([`ComponentCloneBehavior::clone`]) in this case it should be set manually using one
338
/// of the methods mentioned in the [Clone Behaviors](#Clone-Behaviors) section
339
///
340
/// Here's an example of how to do it using [`clone_behavior`](Component::clone_behavior):
341
/// ```
342
/// # use bevy_ecs::prelude::*;
343
/// # use bevy_ecs::component::{StorageType, ComponentCloneBehavior, Mutable};
344
/// #[derive(Clone, Component)]
345
/// #[component(clone_behavior = clone::<Self>())]
346
/// struct SomeComponent;
347
///
348
/// ```
349
///
350
/// # Clone Behaviors
351
/// [`EntityCloner`] clones entities by cloning components using [`ComponentCloneBehavior`], and there are multiple layers
352
/// to decide which handler to use for which component. The overall hierarchy looks like this (priority from most to least):
353
/// 1. local overrides using [`EntityClonerBuilder::override_clone_behavior`]
354
/// 2. component-defined handler using [`Component::clone_behavior`]
355
/// 3. default handler override using [`EntityClonerBuilder::with_default_clone_fn`].
356
/// 4. reflect-based or noop default clone handler depending on if `bevy_reflect` feature is enabled or not.
357
///
358
/// # Moving components
359
/// [`EntityCloner`] can be configured to move components instead of cloning them by using [`EntityClonerBuilder::move_components`].
360
/// In this mode components will be moved - removed from source entity and added to the target entity.
361
///
362
/// Components with [`ComponentCloneBehavior::Ignore`] clone behavior will not be moved, while components that
363
/// have a [`ComponentCloneBehavior::Custom`] clone behavior will be cloned using it and then removed from the source entity.
364
/// All other components will be bitwise copied from the source entity onto the target entity and then removed without dropping.
365
///
366
/// Choosing to move components instead of cloning makes [`EntityClonerBuilder::with_default_clone_fn`] ineffective since it's replaced by
367
/// move handler for components that have [`ComponentCloneBehavior::Default`] clone behavior.
368
///
369
/// Note that moving components still triggers `on_remove` hooks/observers on source entity and `on_insert`/`on_add` hooks/observers on the target entity.
370
#[derive(Default)]
371
pub struct EntityCloner {
372
filter: EntityClonerFilter,
373
state: EntityClonerState,
374
}
375
376
/// An expandable scratch space for defining a dynamic bundle.
377
struct BundleScratch<'a> {
378
component_ids: Vec<ComponentId>,
379
component_ptrs: Vec<PtrMut<'a>>,
380
}
381
382
impl<'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
/// Pushes the `ptr` component onto this storage with the given `id` [`ComponentId`].
391
///
392
/// # Safety
393
/// The `id` [`ComponentId`] must match the component `ptr` for whatever [`World`] this scratch will
394
/// be written to. `ptr` must contain valid uniquely-owned data that matches the type of component referenced
395
/// in `id`.
396
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
/// Pushes the `C` component onto this storage with the given `id` [`ComponentId`], using the given `bump` allocator.
402
///
403
/// # Safety
404
/// The `id` [`ComponentId`] must match the component `C` for whatever [`World`] this scratch will
405
/// be written to.
406
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
/// Writes the scratch components to the given entity in the given world.
418
///
419
/// # Safety
420
/// All [`ComponentId`] values in this instance must come from `world`.
421
#[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
// SAFETY:
429
// - All `component_ids` are from the same world as `entity`
430
// - All `component_data_ptrs` are valid types represented by `component_ids`
431
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
441
impl EntityCloner {
442
/// Returns a new [`EntityClonerBuilder`] using the given `world` with the [`OptOut`] configuration.
443
///
444
/// This builder tries to clone every component from the source entity except for components that were
445
/// explicitly denied, for example by using the [`deny`](EntityClonerBuilder<OptOut>::deny) method.
446
///
447
/// Required components are not considered by denied components and must be explicitly denied as well if desired.
448
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
/// Returns a new [`EntityClonerBuilder`] using the given `world` with the [`OptIn`] configuration.
457
///
458
/// This builder tries to clone every component that was explicitly allowed from the source entity,
459
/// for example by using the [`allow`](EntityClonerBuilder<OptIn>::allow) method.
460
///
461
/// Components allowed to be cloned through this builder would also allow their required components,
462
/// which will be cloned from the source entity only if the target entity does not contain them already.
463
/// To skip adding required components see [`without_required_components`](EntityClonerBuilder<OptIn>::without_required_components).
464
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
/// Returns `true` if this cloner is configured to clone entities referenced in cloned components via [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN).
473
/// This will produce "deep" / recursive clones of relationship trees that have "linked spawn".
474
#[inline]
475
pub fn linked_cloning(&self) -> bool {
476
self.state.linked_cloning
477
}
478
479
/// Clones and inserts components from the `source` entity into `target` entity using the stored configuration.
480
/// If this [`EntityCloner`] has [`EntityCloner::linked_cloning`], then it will recursively spawn entities as defined
481
/// by [`RelationshipTarget`](crate::relationship::RelationshipTarget) components with
482
/// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN)
483
#[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
/// Clones and inserts components from the `source` entity into a newly spawned entity using the stored configuration.
491
/// If this [`EntityCloner`] has [`EntityCloner::linked_cloning`], then it will recursively spawn entities as defined
492
/// by [`RelationshipTarget`](crate::relationship::RelationshipTarget) components with
493
/// [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN)
494
#[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
/// Clones the entity into whatever entity `mapper` chooses for it.
502
#[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
// All relationships on the root should have their hooks run
522
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
// When spawning "linked relationships", we want to ignore hooks for relationships we are spawning, while
532
// still registering with original relationship targets that are "not linked" to the current recursive spawn.
533
RelationshipHookMode::RunIfNotLinked
534
} else {
535
// If we are not cloning "linked relationships" recursively, then we want any cloned relationship components to
536
// register themselves with their original relationship target.
537
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
/// Clones and inserts components from the `source` entity into the entity mapped by `mapper` from `source` using the stored configuration.
558
#[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
// PERF: reusing allocated space across clones would be more efficient. Consider an allocation model similar to `Commands`.
569
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
// SAFETY: we have unique access to `world`, nothing else accesses the registry at this moment, and we clone
579
// the registry, which prevents future conflicts.
580
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
// Replace default handler with special handler which would track if component was moved instead of cloned.
601
// This is later used to determine whether we need to run component's drop function when removing it from the source entity or not.
602
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
// SAFETY: This component exists because it is present on the archetype.
621
let info = unsafe { world.components().get_info_unchecked(component) };
622
623
// SAFETY:
624
// - There are no other mutable references to source entity.
625
// - `component` is from `source_entity`'s archetype
626
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
// SAFETY:
635
// - `components` and `component` are from the same world
636
// - `source_component_ptr` is valid and points to the same type as represented by `component`
637
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
// Component wasn't written by the clone handler, so assume it's going to be
659
// cloned/processed using deferred_commands instead.
660
// This means that it's ComponentId won't be present in BundleScratch's component_ids,
661
// but it should still be removed when move_components is true.
662
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
// Remove all cloned components with drop by concatenating both vectors
686
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
// Copy moved components and then forget them without calling drop
699
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
// SAFETY: table_row is within this table because we just got it from entity's current location
710
table.as_mut().and_then(|table| unsafe {
711
table.get_component(component_id, table_row)
712
})
713
})
714
else {
715
// Component was removed by some other component's clone side effect before we got to it.
716
continue;
717
};
718
719
// SAFETY: component_id is valid because remove_by_ids_with_caller checked it before calling this closure
720
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
// SAFETY:
724
// - component_ptr points to data with component layout
725
// - target_ptr was just allocated with component layout
726
// - component_ptr and target_ptr don't overlap
727
// - component_ptr matches component_id
728
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
(/* should drop? */ false, ())
739
},
740
);
741
}
742
743
// SAFETY:
744
// - All `component_ids` are from the same world as `target` entity
745
// - All `component_data_ptrs` are valid types represented by `component_ids`
746
unsafe { bundle_scratch.write(world, target, relationship_hook_insert_mode) };
747
target
748
}
749
}
750
751
/// Part of the [`EntityCloner`], see there for more information.
752
struct 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
761
impl 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
774
/// A builder for configuring [`EntityCloner`]. See [`EntityCloner`] for more information.
775
pub struct EntityClonerBuilder<'w, Filter> {
776
world: &'w mut World,
777
filter: Filter,
778
state: EntityClonerState,
779
}
780
781
impl<'w, Filter: CloneByFilter> EntityClonerBuilder<'w, Filter> {
782
/// Internally calls [`EntityCloner::clone_entity`] on the builder's [`World`].
783
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
/// Finishes configuring [`EntityCloner`] returns it.
797
pub fn finish(self) -> EntityCloner {
798
EntityCloner {
799
filter: self.filter.into(),
800
state: self.state,
801
}
802
}
803
804
/// Sets the default clone function to use.
805
///
806
/// Will be overridden if [`EntityClonerBuilder::move_components`] is enabled.
807
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
/// Sets whether the cloner should remove any components that were cloned,
813
/// effectively moving them from the source entity to the target.
814
///
815
/// This is disabled by default.
816
///
817
/// The setting only applies to components that are allowed through the filter
818
/// at the time [`EntityClonerBuilder::clone_entity`] is called.
819
///
820
/// Enabling this overrides any custom function set with [`EntityClonerBuilder::with_default_clone_fn`].
821
pub fn move_components(&mut self, enable: bool) -> &mut Self {
822
self.state.move_components = enable;
823
self
824
}
825
826
/// Overrides the [`ComponentCloneBehavior`] for a component in this builder.
827
/// This handler will be used to clone the component instead of the global one defined by the [`EntityCloner`].
828
///
829
/// See [Handlers section of `EntityClonerBuilder`](EntityClonerBuilder#handlers) to understand how this affects handler priority.
830
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
/// Overrides the [`ComponentCloneBehavior`] for a component with the given `component_id` in this builder.
843
/// This handler will be used to clone the component instead of the global one defined by the [`EntityCloner`].
844
///
845
/// See [Handlers section of `EntityClonerBuilder`](EntityClonerBuilder#handlers) to understand how this affects handler priority.
846
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
/// Removes a previously set override of [`ComponentCloneBehavior`] for a component in this builder.
858
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
/// Removes a previously set override of [`ComponentCloneBehavior`] for a given `component_id` in this builder.
866
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
/// When true this cloner will be configured to clone entities referenced in cloned components via [`RelationshipTarget::LINKED_SPAWN`](crate::relationship::RelationshipTarget::LINKED_SPAWN).
875
/// This will produce "deep" / recursive clones of relationship trees that have "linked spawn".
876
pub fn linked_cloning(&mut self, linked_cloning: bool) -> &mut Self {
877
self.state.linked_cloning = linked_cloning;
878
self
879
}
880
}
881
882
impl<'w> EntityClonerBuilder<'w, OptOut> {
883
/// By default, any components denied through the filter will automatically
884
/// deny all of components they are required by too.
885
///
886
/// This method allows for a scoped mode where any changes to the filter
887
/// will not involve these requiring components.
888
///
889
/// If component `A` is denied in the `builder` closure here and component `B`
890
/// requires `A`, then `A` will be inserted with the value defined in `B`'s
891
/// [`Component` derive](https://docs.rs/bevy/latest/bevy/ecs/component/trait.Component.html#required-components).
892
/// This assumes `A` is missing yet at the target entity.
893
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
/// Sets whether components are always cloned ([`InsertMode::Replace`], the default) or only if it is missing
901
/// ([`InsertMode::Keep`]) at the target entity.
902
///
903
/// This makes no difference if the target is spawned by the cloner.
904
pub fn insert_mode(&mut self, insert_mode: InsertMode) -> &mut Self {
905
self.filter.insert_mode = insert_mode;
906
self
907
}
908
909
/// Disallows all components of the bundle from being cloned.
910
///
911
/// If component `A` is denied here and component `B` requires `A`, then `A`
912
/// is denied as well. See [`Self::without_required_by_components`] to alter
913
/// this behavior.
914
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
/// Extends the list of components that shouldn't be cloned.
920
/// Supports filtering by [`TypeId`], [`ComponentId`], [`BundleId`](`crate::bundle::BundleId`), and [`IntoIterator`] yielding one of these.
921
///
922
/// If component `A` is denied here and component `B` requires `A`, then `A`
923
/// is denied as well. See [`Self::without_required_by_components`] to alter
924
/// this behavior.
925
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
948
impl<'w> EntityClonerBuilder<'w, OptIn> {
949
/// By default, any components allowed through the filter will automatically
950
/// allow all of their required components.
951
///
952
/// This method allows for a scoped mode where any changes to the filter
953
/// will not involve required components.
954
///
955
/// If component `A` is allowed in the `builder` closure here and requires
956
/// component `B`, then `B` will be inserted with the value defined in `A`'s
957
/// [`Component` derive](https://docs.rs/bevy/latest/bevy/ecs/component/trait.Component.html#required-components).
958
/// This assumes `B` is missing yet at the target entity.
959
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
/// Adds all components of the bundle to the list of components to clone.
967
///
968
/// If component `A` is allowed here and requires component `B`, then `B`
969
/// is allowed as well. See [`Self::without_required_components`]
970
/// to alter this behavior.
971
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
/// Adds all components of the bundle to the list of components to clone if
977
/// the target does not contain them.
978
///
979
/// If component `A` is allowed here and requires component `B`, then `B`
980
/// is allowed as well. See [`Self::without_required_components`]
981
/// to alter this behavior.
982
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
/// Extends the list of components to clone.
988
/// Supports filtering by [`TypeId`], [`ComponentId`], [`BundleId`](`crate::bundle::BundleId`), and [`IntoIterator`] yielding one of these.
989
///
990
/// If component `A` is allowed here and requires component `B`, then `B`
991
/// is allowed as well. See [`Self::without_required_components`]
992
/// to alter this behavior.
993
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
/// Extends the list of components to clone if the target does not contain them.
999
/// Supports filtering by [`TypeId`], [`ComponentId`], [`BundleId`](`crate::bundle::BundleId`), and [`IntoIterator`] yielding one of these.
1000
///
1001
/// If component `A` is allowed here and requires component `B`, then `B`
1002
/// is allowed as well. See [`Self::without_required_components`]
1003
/// to alter this behavior.
1004
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
/// Filters that can selectively clone components depending on its inner configuration are unified with this trait.
1037
#[doc(hidden)]
1038
pub trait CloneByFilter: Into<EntityClonerFilter> {
1039
/// The filter will call `clone_component` for every [`ComponentId`] that passes it.
1040
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
/// Part of the [`EntityCloner`], see there for more information.
1049
#[doc(hidden)]
1050
#[derive(From)]
1051
pub enum EntityClonerFilter {
1052
OptOut(OptOut),
1053
OptIn(OptIn),
1054
}
1055
1056
impl Default for EntityClonerFilter {
1057
fn default() -> Self {
1058
Self::OptOut(Default::default())
1059
}
1060
}
1061
1062
impl 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
1081
/// Generic for [`EntityClonerBuilder`] that makes the cloner try to clone every component from the source entity
1082
/// except for components that were explicitly denied, for example by using the
1083
/// [`deny`](EntityClonerBuilder::deny) method.
1084
///
1085
/// Required components are not considered by denied components and must be explicitly denied as well if desired.
1086
pub struct OptOut {
1087
/// Contains the components that should not be cloned.
1088
deny: HashSet<ComponentId>,
1089
1090
/// Determines if a component is inserted when it is existing already.
1091
insert_mode: InsertMode,
1092
1093
/// Is `true` unless during [`EntityClonerBuilder::without_required_by_components`] which will suppress
1094
/// components that require denied components to be denied as well, causing them to be created independent
1095
/// from the value at the source entity if needed.
1096
attach_required_by_components: bool,
1097
}
1098
1099
impl 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
1109
impl 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
1136
impl OptOut {
1137
/// Denies a component through the filter, also deny components that require `id` if
1138
/// [`Self::attach_required_by_components`] is true.
1139
#[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
1150
/// Generic for [`EntityClonerBuilder`] that makes the cloner try to clone every component that was explicitly
1151
/// allowed from the source entity, for example by using the [`allow`](EntityClonerBuilder::allow) method.
1152
///
1153
/// Required components are also cloned when the target entity does not contain them.
1154
pub struct OptIn {
1155
/// Contains the components explicitly allowed to be cloned.
1156
allow: HashMap<ComponentId, Explicit>,
1157
1158
/// Lists of required components, [`Explicit`] refers to a range in it.
1159
required_of_allow: Vec<ComponentId>,
1160
1161
/// Contains the components required by those in [`Self::allow`].
1162
/// Also contains the number of components in [`Self::allow`] each is required by to track
1163
/// when to skip cloning a required component after skipping explicit components that require it.
1164
required: HashMap<ComponentId, Required>,
1165
1166
/// Is `true` unless during [`EntityClonerBuilder::without_required_components`] which will suppress
1167
/// evaluating required components to clone, causing them to be created independent from the value at
1168
/// the source entity if needed.
1169
attach_required_components: bool,
1170
}
1171
1172
impl 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
1183
impl 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
// track the amount of components left not being cloned yet to exit this method early
1192
let mut uncloned_components = source_archetype.component_count();
1193
1194
// track if any `Required::required_by_reduced` has been reduced so they are reset
1195
let mut reduced_any = false;
1196
1197
// clone explicit components
1198
for (&component, explicit) in self.allow.iter() {
1199
if uncloned_components == 0 {
1200
// exhausted all source components, reset changed `Required::required_by_reduced`
1201
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
// may be None if required component was also added as explicit later
1218
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
// clone required components
1229
let required_components = required_iter
1230
.by_ref()
1231
.filter_map(|(&component, required)| {
1232
let do_clone = required.required_by_reduced > 0 // required by a cloned component
1233
&& source_archetype.contains(component) // must exist to clone, may miss if removed
1234
&& !target_archetype.contains(component); // do not overwrite existing values
1235
1236
// reset changed `Required::required_by_reduced` as this is done being checked here
1237
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 the `required_components` iterator has not been exhausted yet because the source has no more
1248
// components to clone, iterate the rest to reset changed `Required::required_by_reduced` for the
1249
// next clone
1250
if reduced_any {
1251
required_iter.for_each(|(_, required)| required.reset());
1252
}
1253
}
1254
}
1255
1256
impl OptIn {
1257
/// Allows a component through the filter, also allow required components if
1258
/// [`Self::attach_required_components`] is true.
1259
#[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
// explicit components should not appear in the required map
1264
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
// set required component range if it was inserted with `None` earlier
1279
if self.attach_required_components && explicit.required_range.is_none() {
1280
if explicit.insert_mode == InsertMode::Replace {
1281
// do not overwrite with Keep if component was allowed as Replace earlier
1282
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
// potentially overwrite Keep with Replace
1288
explicit.insert_mode = insert_mode;
1289
}
1290
}
1291
};
1292
}
1293
1294
// Allow a component through the filter and include required components.
1295
#[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
// set or increase the number of components this `id` is required by
1312
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
1338
/// Contains the components explicitly allowed to be cloned.
1339
struct Explicit {
1340
/// If component was added via [`allow`](EntityClonerBuilder::allow) etc, this is `Overwrite`.
1341
///
1342
/// If component was added via [`allow_if_new`](EntityClonerBuilder::allow_if_new) etc, this is `Keep`.
1343
insert_mode: InsertMode,
1344
1345
/// Contains the range in [`OptIn::required_of_allow`] for this component containing its
1346
/// required components.
1347
///
1348
/// Is `None` if [`OptIn::attach_required_components`] was `false` when added.
1349
/// It may be set to `Some` later if the component is later added explicitly again with
1350
/// [`OptIn::attach_required_components`] being `true`.
1351
///
1352
/// Range is empty if this component has no required components that are not also explicitly allowed.
1353
required_range: Option<Range<usize>>,
1354
}
1355
1356
struct Required {
1357
/// Amount of explicit components this component is required by.
1358
required_by: u32,
1359
1360
/// As [`Self::required_by`] but is reduced during cloning when an explicit component is not cloned,
1361
/// either because [`Explicit::insert_mode`] is `Keep` or the source entity does not contain it.
1362
///
1363
/// If this is zero, the required component is not cloned.
1364
///
1365
/// The counter is reset to `required_by` when the cloning is over in case another entity needs to be
1366
/// cloned by the same [`EntityCloner`].
1367
required_by_reduced: u32,
1368
}
1369
1370
impl Required {
1371
// Revert reductions for the next entity to clone with this EntityCloner
1372
#[inline]
1373
fn reset(&mut self) {
1374
self.required_by_reduced = self.required_by;
1375
}
1376
}
1377
1378
mod private {
1379
use crate::{bundle::BundleId, component::ComponentId};
1380
use core::any::TypeId;
1381
use derive_more::From;
1382
1383
/// Marker trait to allow multiple blanket implementations for [`FilterableIds`].
1384
pub trait Marker {}
1385
/// Marker struct for [`FilterableIds`] implementation for single-value types.
1386
pub struct ScalarType {}
1387
impl Marker for ScalarType {}
1388
/// Marker struct for [`FilterableIds`] implementation for [`IntoIterator`] types.
1389
pub struct VectorType {}
1390
impl Marker for VectorType {}
1391
1392
/// Defines types of ids that [`EntityClonerBuilder`](`super::EntityClonerBuilder`) can filter components by.
1393
#[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
/// A trait to allow [`EntityClonerBuilder`](`super::EntityClonerBuilder`) filter by any supported id type and their iterators,
1411
/// reducing the number of method permutations required for all id types.
1412
///
1413
/// The supported id types that can be used to filter components are defined by [`FilterableId`], which allows following types: [`TypeId`], [`ComponentId`] and [`BundleId`].
1414
///
1415
/// `M` is a generic marker to allow multiple blanket implementations of this trait.
1416
/// This works because `FilterableId<M1>` is a different trait from `FilterableId<M2>`, so multiple blanket implementations for different `M` are allowed.
1417
/// The reason this is required is because supporting `IntoIterator` requires blanket implementation, but that will conflict with implementation for `TypeId`
1418
/// since `IntoIterator` can technically be implemented for `TypeId` in the future.
1419
/// Functions like `allow_by_ids` rely on type inference to automatically select proper type for `M` at call site.
1420
pub trait FilterableIds<M: Marker> {
1421
/// Takes in a function that processes all types of [`FilterableId`] one-by-one.
1422
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
1449
use private::{FilterableId, FilterableIds, Marker};
1450
1451
#[cfg(test)]
1452
mod 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
// `reflect_clone`-based fast path
1503
#[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
// `ReflectDefault`-based fast path
1511
#[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
// `ReflectFromReflect`-based fast path
1522
#[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
// `ReflectFromWorld`-based fast path
1531
#[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(&registry.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
// Not reflected
1655
#[derive(Component, PartialEq, Eq, Default, Debug)]
1656
struct A;
1657
1658
// No valid type data and not `reflect_clone`-able
1659
#[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
// No AppTypeRegistry
1667
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
// With AppTypeRegistry
1677
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
// We add an ignored field here to ensure `reflect_clone` fails and `FromWorld` is used
1695
#[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
// SAFETY: the passed in ptr corresponds to copy-able data that matches the type of the source / target component
2083
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
// SAFETY:
2092
// - No drop command is required
2093
// - The component will store [u8; COMPONENT_SIZE], which is Send + Sync
2094
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
// SAFETY:
2110
// - ptr points to data represented by component_id ([u8; COMPONENT_SIZE])
2111
// - component_id is from the same world as entity
2112
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
// SAFETY: ptr and clone_ptr store component represented by [u8; COMPONENT_SIZE]
2123
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
// Clone using deferred
2257
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
// Original: E1 Target{target: [E2], data: [4,5,6]}
2379
// | E2 Source{target: E1, data: [1,2,3]}
2380
//
2381
// Cloned: E3 Target{target: [], data: [4,5,6]}
2382
#[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
// Original: E1 Target{target: [E2], data: [4,5,6]}
2429
// | E2 Source{target: E1, data: [1,2,3]}
2430
//
2431
// Cloned: E3 Target{target: [E4], data: [4,5,6]}
2432
// | E4 Source{target: E3, data: [1,2,3]}
2433
#[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
// Original: E1
2484
// E2
2485
//
2486
// Moved: E3 Target{target: [], data: [4,5,6]}
2487
#[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
// Original: E1
2543
// E2
2544
//
2545
// Moved: E3 Target{target: [E4], data: [4,5,6]}
2546
// | E4 Source{target: E3, data: [1,2,3]}
2547
#[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
}
2597
2598