Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/reflect/entity_commands.rs
6600 views
1
use crate::{
2
prelude::Mut,
3
reflect::{AppTypeRegistry, ReflectBundle, ReflectComponent},
4
resource::Resource,
5
system::EntityCommands,
6
world::EntityWorldMut,
7
};
8
use alloc::{borrow::Cow, boxed::Box};
9
use bevy_reflect::{PartialReflect, TypeRegistry};
10
11
/// An extension trait for [`EntityCommands`] for reflection related functions
12
pub trait ReflectCommandExt {
13
/// Adds the given boxed reflect component or bundle to the entity using the reflection data in
14
/// [`AppTypeRegistry`].
15
///
16
/// This will overwrite any previous component(s) of the same type.
17
///
18
/// # Panics
19
///
20
/// - If the entity doesn't exist.
21
/// - If [`AppTypeRegistry`] does not have the reflection data for the given
22
/// [`Component`](crate::component::Component) or [`Bundle`](crate::bundle::Bundle).
23
/// - If the component or bundle data is invalid. See [`PartialReflect::apply`] for further details.
24
/// - If [`AppTypeRegistry`] is not present in the [`World`](crate::world::World).
25
///
26
/// # Note
27
///
28
/// Prefer to use the typed [`EntityCommands::insert`] if possible. Adding a reflected component
29
/// is much slower.
30
///
31
/// # Example
32
///
33
/// ```
34
/// // Note that you need to register the component type in the AppTypeRegistry prior to using
35
/// // reflection. You can use the helpers on the App with `app.register_type::<ComponentA>()`
36
/// // or write to the TypeRegistry directly to register all your components
37
///
38
/// # use bevy_ecs::prelude::*;
39
/// # use bevy_ecs::reflect::{ReflectCommandExt, ReflectBundle};
40
/// # use bevy_reflect::{FromReflect, FromType, Reflect, TypeRegistry};
41
/// // A resource that can hold any component that implements reflect as a boxed reflect component
42
/// #[derive(Resource)]
43
/// struct Prefab {
44
/// data: Box<dyn Reflect>,
45
/// }
46
/// #[derive(Component, Reflect, Default)]
47
/// #[reflect(Component)]
48
/// struct ComponentA(u32);
49
///
50
/// #[derive(Component, Reflect, Default)]
51
/// #[reflect(Component)]
52
/// struct ComponentB(String);
53
///
54
/// #[derive(Bundle, Reflect, Default)]
55
/// #[reflect(Bundle)]
56
/// struct BundleA {
57
/// a: ComponentA,
58
/// b: ComponentB,
59
/// }
60
///
61
/// fn insert_reflect_component(
62
/// mut commands: Commands,
63
/// mut prefab: ResMut<Prefab>
64
/// ) {
65
/// // Create a set of new boxed reflect components to use
66
/// let boxed_reflect_component_a: Box<dyn Reflect> = Box::new(ComponentA(916));
67
/// let boxed_reflect_component_b: Box<dyn Reflect> = Box::new(ComponentB("NineSixteen".to_string()));
68
/// let boxed_reflect_bundle_a: Box<dyn Reflect> = Box::new(BundleA {
69
/// a: ComponentA(24),
70
/// b: ComponentB("Twenty-Four".to_string()),
71
/// });
72
///
73
/// // You can overwrite the component in the resource with either ComponentA or ComponentB
74
/// prefab.data = boxed_reflect_component_a;
75
/// prefab.data = boxed_reflect_component_b;
76
///
77
/// // Or even with BundleA
78
/// prefab.data = boxed_reflect_bundle_a;
79
///
80
/// // No matter which component or bundle is in the resource and without knowing the exact type, you can
81
/// // use the insert_reflect entity command to insert that component/bundle into an entity.
82
/// commands
83
/// .spawn_empty()
84
/// .insert_reflect(prefab.data.reflect_clone().unwrap().into_partial_reflect());
85
/// }
86
/// ```
87
fn insert_reflect(&mut self, component: Box<dyn PartialReflect>) -> &mut Self;
88
89
/// Same as [`insert_reflect`](ReflectCommandExt::insert_reflect), but using the `T` resource as type registry instead of
90
/// `AppTypeRegistry`.
91
///
92
/// # Panics
93
///
94
/// - If the given [`Resource`] is not present in the [`World`](crate::world::World).
95
///
96
/// # Note
97
///
98
/// - The given [`Resource`] is removed from the [`World`](crate::world::World) before the command is applied.
99
fn insert_reflect_with_registry<T: Resource + AsRef<TypeRegistry>>(
100
&mut self,
101
component: Box<dyn PartialReflect>,
102
) -> &mut Self;
103
104
/// Removes from the entity the component or bundle with the given type path registered in [`AppTypeRegistry`].
105
///
106
/// If the type is a bundle, it will remove any components in that bundle regardless if the entity
107
/// contains all the components.
108
///
109
/// Does nothing if the type is a component and the entity does not have a component of the same type,
110
/// if the type is a bundle and the entity does not contain any of the components in the bundle,
111
/// if [`AppTypeRegistry`] does not contain the reflection data for the given component,
112
/// or if the entity does not exist.
113
///
114
/// # Note
115
///
116
/// Prefer to use the typed [`EntityCommands::remove`] if possible. Removing a reflected component
117
/// is much slower.
118
///
119
/// # Example
120
///
121
/// ```
122
/// // Note that you need to register the component/bundle type in the AppTypeRegistry prior to using
123
/// // reflection. You can use the helpers on the App with `app.register_type::<ComponentA>()`
124
/// // or write to the TypeRegistry directly to register all your components and bundles
125
///
126
/// # use bevy_ecs::prelude::*;
127
/// # use bevy_ecs::reflect::{ReflectCommandExt, ReflectBundle};
128
/// # use bevy_reflect::{FromReflect, FromType, Reflect, TypeRegistry};
129
///
130
/// // A resource that can hold any component or bundle that implements reflect as a boxed reflect
131
/// #[derive(Resource)]
132
/// struct Prefab{
133
/// entity: Entity,
134
/// data: Box<dyn Reflect>,
135
/// }
136
/// #[derive(Component, Reflect, Default)]
137
/// #[reflect(Component)]
138
/// struct ComponentA(u32);
139
/// #[derive(Component, Reflect, Default)]
140
/// #[reflect(Component)]
141
/// struct ComponentB(String);
142
/// #[derive(Bundle, Reflect, Default)]
143
/// #[reflect(Bundle)]
144
/// struct BundleA {
145
/// a: ComponentA,
146
/// b: ComponentB,
147
/// }
148
///
149
/// fn remove_reflect_component(
150
/// mut commands: Commands,
151
/// prefab: Res<Prefab>
152
/// ) {
153
/// // Prefab can hold any boxed reflect component or bundle. In this case either
154
/// // ComponentA, ComponentB, or BundleA. No matter which component or bundle is in the resource though,
155
/// // we can attempt to remove any component (or set of components in the case of a bundle)
156
/// // of that same type from an entity.
157
/// commands.entity(prefab.entity)
158
/// .remove_reflect(prefab.data.reflect_type_path().to_owned());
159
/// }
160
/// ```
161
fn remove_reflect(&mut self, component_type_path: impl Into<Cow<'static, str>>) -> &mut Self;
162
/// Same as [`remove_reflect`](ReflectCommandExt::remove_reflect), but using the `T` resource as type registry instead of
163
/// `AppTypeRegistry`.
164
fn remove_reflect_with_registry<T: Resource + AsRef<TypeRegistry>>(
165
&mut self,
166
component_type_path: impl Into<Cow<'static, str>>,
167
) -> &mut Self;
168
}
169
170
impl ReflectCommandExt for EntityCommands<'_> {
171
fn insert_reflect(&mut self, component: Box<dyn PartialReflect>) -> &mut Self {
172
self.queue(move |mut entity: EntityWorldMut| {
173
entity.insert_reflect(component);
174
})
175
}
176
177
fn insert_reflect_with_registry<T: Resource + AsRef<TypeRegistry>>(
178
&mut self,
179
component: Box<dyn PartialReflect>,
180
) -> &mut Self {
181
self.queue(move |mut entity: EntityWorldMut| {
182
entity.insert_reflect_with_registry::<T>(component);
183
})
184
}
185
186
fn remove_reflect(&mut self, component_type_path: impl Into<Cow<'static, str>>) -> &mut Self {
187
let component_type_path: Cow<'static, str> = component_type_path.into();
188
self.queue(move |mut entity: EntityWorldMut| {
189
entity.remove_reflect(component_type_path);
190
})
191
}
192
193
fn remove_reflect_with_registry<T: Resource + AsRef<TypeRegistry>>(
194
&mut self,
195
component_type_path: impl Into<Cow<'static, str>>,
196
) -> &mut Self {
197
let component_type_path: Cow<'static, str> = component_type_path.into();
198
self.queue(move |mut entity: EntityWorldMut| {
199
entity.remove_reflect_with_registry::<T>(component_type_path);
200
})
201
}
202
}
203
204
impl<'w> EntityWorldMut<'w> {
205
/// Adds the given boxed reflect component or bundle to the entity using the reflection data in
206
/// [`AppTypeRegistry`].
207
///
208
/// This will overwrite any previous component(s) of the same type.
209
///
210
/// # Panics
211
///
212
/// - If the entity has been despawned while this `EntityWorldMut` is still alive.
213
/// - If [`AppTypeRegistry`] does not have the reflection data for the given
214
/// [`Component`](crate::component::Component) or [`Bundle`](crate::bundle::Bundle).
215
/// - If the component or bundle data is invalid. See [`PartialReflect::apply`] for further details.
216
/// - If [`AppTypeRegistry`] is not present in the [`World`](crate::world::World).
217
///
218
/// # Note
219
///
220
/// Prefer to use the typed [`EntityWorldMut::insert`] if possible. Adding a reflected component
221
/// is much slower.
222
pub fn insert_reflect(&mut self, component: Box<dyn PartialReflect>) -> &mut Self {
223
self.assert_not_despawned();
224
self.resource_scope(|entity, registry: Mut<AppTypeRegistry>| {
225
let type_registry = &registry.as_ref().read();
226
insert_reflect_with_registry_ref(entity, type_registry, component);
227
});
228
self
229
}
230
231
/// Same as [`insert_reflect`](EntityWorldMut::insert_reflect), but using
232
/// the `T` resource as type registry instead of [`AppTypeRegistry`].
233
///
234
/// This will overwrite any previous component(s) of the same type.
235
///
236
/// # Panics
237
///
238
/// - If the entity has been despawned while this `EntityWorldMut` is still alive.
239
/// - If the given [`Resource`] does not have the reflection data for the given
240
/// [`Component`](crate::component::Component) or [`Bundle`](crate::bundle::Bundle).
241
/// - If the component or bundle data is invalid. See [`PartialReflect::apply`] for further details.
242
/// - If the given [`Resource`] is not present in the [`World`](crate::world::World).
243
pub fn insert_reflect_with_registry<T: Resource + AsRef<TypeRegistry>>(
244
&mut self,
245
component: Box<dyn PartialReflect>,
246
) -> &mut Self {
247
self.assert_not_despawned();
248
self.resource_scope(|entity, registry: Mut<T>| {
249
let type_registry = registry.as_ref().as_ref();
250
insert_reflect_with_registry_ref(entity, type_registry, component);
251
});
252
self
253
}
254
255
/// Removes from the entity the component or bundle with the given type path registered in [`AppTypeRegistry`].
256
///
257
/// If the type is a bundle, it will remove any components in that bundle regardless if the entity
258
/// contains all the components.
259
///
260
/// Does nothing if the type is a component and the entity does not have a component of the same type,
261
/// if the type is a bundle and the entity does not contain any of the components in the bundle,
262
/// or if [`AppTypeRegistry`] does not contain the reflection data for the given component.
263
///
264
/// # Panics
265
///
266
/// - If the entity has been despawned while this `EntityWorldMut` is still alive.
267
/// - If [`AppTypeRegistry`] is not present in the [`World`](crate::world::World).
268
///
269
/// # Note
270
///
271
/// Prefer to use the typed [`EntityCommands::remove`] if possible. Removing a reflected component
272
/// is much slower.
273
pub fn remove_reflect(&mut self, component_type_path: Cow<'static, str>) -> &mut Self {
274
self.assert_not_despawned();
275
self.resource_scope(|entity, registry: Mut<AppTypeRegistry>| {
276
let type_registry = &registry.as_ref().read();
277
remove_reflect_with_registry_ref(entity, type_registry, component_type_path);
278
});
279
self
280
}
281
282
/// Same as [`remove_reflect`](EntityWorldMut::remove_reflect), but using
283
/// the `T` resource as type registry instead of `AppTypeRegistry`.
284
///
285
/// If the given type is a bundle, it will remove any components in that bundle regardless if the entity
286
/// contains all the components.
287
///
288
/// Does nothing if the type is a component and the entity does not have a component of the same type,
289
/// if the type is a bundle and the entity does not contain any of the components in the bundle,
290
/// or if [`AppTypeRegistry`] does not contain the reflection data for the given component.
291
///
292
/// # Panics
293
///
294
/// - If the entity has been despawned while this `EntityWorldMut` is still alive.
295
/// - If [`AppTypeRegistry`] is not present in the [`World`](crate::world::World).
296
pub fn remove_reflect_with_registry<T: Resource + AsRef<TypeRegistry>>(
297
&mut self,
298
component_type_path: Cow<'static, str>,
299
) -> &mut Self {
300
self.assert_not_despawned();
301
self.resource_scope(|entity, registry: Mut<T>| {
302
let type_registry = registry.as_ref().as_ref();
303
remove_reflect_with_registry_ref(entity, type_registry, component_type_path);
304
});
305
self
306
}
307
}
308
309
/// Helper function to add a reflect component or bundle to a given entity
310
fn insert_reflect_with_registry_ref(
311
entity: &mut EntityWorldMut,
312
type_registry: &TypeRegistry,
313
component: Box<dyn PartialReflect>,
314
) {
315
let type_info = component
316
.get_represented_type_info()
317
.expect("component should represent a type.");
318
let type_path = type_info.type_path();
319
let Some(type_registration) = type_registry.get(type_info.type_id()) else {
320
panic!("`{type_path}` should be registered in type registry via `App::register_type<{type_path}>`");
321
};
322
323
if let Some(reflect_component) = type_registration.data::<ReflectComponent>() {
324
reflect_component.insert(entity, component.as_partial_reflect(), type_registry);
325
} else if let Some(reflect_bundle) = type_registration.data::<ReflectBundle>() {
326
reflect_bundle.insert(entity, component.as_partial_reflect(), type_registry);
327
} else {
328
panic!("`{type_path}` should have #[reflect(Component)] or #[reflect(Bundle)]");
329
}
330
}
331
332
/// Helper function to remove a reflect component or bundle from a given entity
333
fn remove_reflect_with_registry_ref(
334
entity: &mut EntityWorldMut,
335
type_registry: &TypeRegistry,
336
component_type_path: Cow<'static, str>,
337
) {
338
let Some(type_registration) = type_registry.get_with_type_path(&component_type_path) else {
339
return;
340
};
341
if let Some(reflect_component) = type_registration.data::<ReflectComponent>() {
342
reflect_component.remove(entity);
343
} else if let Some(reflect_bundle) = type_registration.data::<ReflectBundle>() {
344
reflect_bundle.remove(entity);
345
}
346
}
347
348
#[cfg(test)]
349
mod tests {
350
use crate::{
351
bundle::Bundle,
352
component::Component,
353
prelude::{AppTypeRegistry, ReflectComponent},
354
reflect::{ReflectBundle, ReflectCommandExt},
355
system::{Commands, SystemState},
356
world::World,
357
};
358
use alloc::{borrow::ToOwned, boxed::Box};
359
use bevy_ecs_macros::Resource;
360
use bevy_reflect::{PartialReflect, Reflect, TypeRegistry};
361
362
#[derive(Resource)]
363
struct TypeRegistryResource {
364
type_registry: TypeRegistry,
365
}
366
367
impl AsRef<TypeRegistry> for TypeRegistryResource {
368
fn as_ref(&self) -> &TypeRegistry {
369
&self.type_registry
370
}
371
}
372
373
#[derive(Component, Reflect, Default, PartialEq, Eq, Debug)]
374
#[reflect(Component)]
375
struct ComponentA(u32);
376
377
#[derive(Component, Reflect, Default, PartialEq, Eq, Debug)]
378
#[reflect(Component)]
379
struct ComponentB(u32);
380
381
#[derive(Bundle, Reflect, Default, Debug, PartialEq)]
382
#[reflect(Bundle)]
383
struct BundleA {
384
a: ComponentA,
385
b: ComponentB,
386
}
387
388
#[test]
389
fn insert_reflected() {
390
let mut world = World::new();
391
392
let type_registry = AppTypeRegistry::default();
393
{
394
let mut registry = type_registry.write();
395
registry.register::<ComponentA>();
396
registry.register_type_data::<ComponentA, ReflectComponent>();
397
}
398
world.insert_resource(type_registry);
399
400
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
401
let mut commands = system_state.get_mut(&mut world);
402
403
let entity = commands.spawn_empty().id();
404
let entity2 = commands.spawn_empty().id();
405
let entity3 = commands.spawn_empty().id();
406
407
let boxed_reflect_component_a = Box::new(ComponentA(916)) as Box<dyn PartialReflect>;
408
let boxed_reflect_component_a_clone = boxed_reflect_component_a.reflect_clone().unwrap();
409
let boxed_reflect_component_a_dynamic = boxed_reflect_component_a.to_dynamic();
410
411
commands
412
.entity(entity)
413
.insert_reflect(boxed_reflect_component_a);
414
commands
415
.entity(entity2)
416
.insert_reflect(boxed_reflect_component_a_clone.into_partial_reflect());
417
commands
418
.entity(entity3)
419
.insert_reflect(boxed_reflect_component_a_dynamic);
420
system_state.apply(&mut world);
421
422
assert_eq!(
423
world.entity(entity).get::<ComponentA>(),
424
world.entity(entity2).get::<ComponentA>(),
425
);
426
assert_eq!(
427
world.entity(entity).get::<ComponentA>(),
428
world.entity(entity3).get::<ComponentA>(),
429
);
430
}
431
432
#[test]
433
fn insert_reflected_with_registry() {
434
let mut world = World::new();
435
436
let mut type_registry = TypeRegistryResource {
437
type_registry: TypeRegistry::new(),
438
};
439
440
type_registry.type_registry.register::<ComponentA>();
441
type_registry
442
.type_registry
443
.register_type_data::<ComponentA, ReflectComponent>();
444
world.insert_resource(type_registry);
445
446
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
447
let mut commands = system_state.get_mut(&mut world);
448
449
let entity = commands.spawn_empty().id();
450
451
let boxed_reflect_component_a = Box::new(ComponentA(916)) as Box<dyn PartialReflect>;
452
453
commands
454
.entity(entity)
455
.insert_reflect_with_registry::<TypeRegistryResource>(boxed_reflect_component_a);
456
system_state.apply(&mut world);
457
458
assert_eq!(
459
world.entity(entity).get::<ComponentA>(),
460
Some(&ComponentA(916))
461
);
462
}
463
464
#[test]
465
fn remove_reflected() {
466
let mut world = World::new();
467
468
let type_registry = AppTypeRegistry::default();
469
{
470
let mut registry = type_registry.write();
471
registry.register::<ComponentA>();
472
registry.register_type_data::<ComponentA, ReflectComponent>();
473
}
474
world.insert_resource(type_registry);
475
476
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
477
let mut commands = system_state.get_mut(&mut world);
478
479
let entity = commands.spawn(ComponentA(0)).id();
480
481
let boxed_reflect_component_a = Box::new(ComponentA(916)) as Box<dyn Reflect>;
482
483
commands
484
.entity(entity)
485
.remove_reflect(boxed_reflect_component_a.reflect_type_path().to_owned());
486
system_state.apply(&mut world);
487
488
assert_eq!(world.entity(entity).get::<ComponentA>(), None);
489
}
490
491
#[test]
492
fn remove_reflected_with_registry() {
493
let mut world = World::new();
494
495
let mut type_registry = TypeRegistryResource {
496
type_registry: TypeRegistry::new(),
497
};
498
499
type_registry.type_registry.register::<ComponentA>();
500
type_registry
501
.type_registry
502
.register_type_data::<ComponentA, ReflectComponent>();
503
world.insert_resource(type_registry);
504
505
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
506
let mut commands = system_state.get_mut(&mut world);
507
508
let entity = commands.spawn(ComponentA(0)).id();
509
510
let boxed_reflect_component_a = Box::new(ComponentA(916)) as Box<dyn Reflect>;
511
512
commands
513
.entity(entity)
514
.remove_reflect_with_registry::<TypeRegistryResource>(
515
boxed_reflect_component_a.reflect_type_path().to_owned(),
516
);
517
system_state.apply(&mut world);
518
519
assert_eq!(world.entity(entity).get::<ComponentA>(), None);
520
}
521
522
#[test]
523
fn insert_reflect_bundle() {
524
let mut world = World::new();
525
526
let type_registry = AppTypeRegistry::default();
527
{
528
let mut registry = type_registry.write();
529
registry.register::<BundleA>();
530
registry.register_type_data::<BundleA, ReflectBundle>();
531
}
532
world.insert_resource(type_registry);
533
534
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
535
let mut commands = system_state.get_mut(&mut world);
536
537
let entity = commands.spawn_empty().id();
538
let bundle = Box::new(BundleA {
539
a: ComponentA(31),
540
b: ComponentB(20),
541
}) as Box<dyn PartialReflect>;
542
commands.entity(entity).insert_reflect(bundle);
543
544
system_state.apply(&mut world);
545
546
assert_eq!(world.get::<ComponentA>(entity), Some(&ComponentA(31)));
547
assert_eq!(world.get::<ComponentB>(entity), Some(&ComponentB(20)));
548
}
549
550
#[test]
551
fn insert_reflect_bundle_with_registry() {
552
let mut world = World::new();
553
554
let mut type_registry = TypeRegistryResource {
555
type_registry: TypeRegistry::new(),
556
};
557
558
type_registry.type_registry.register::<BundleA>();
559
type_registry
560
.type_registry
561
.register_type_data::<BundleA, ReflectBundle>();
562
world.insert_resource(type_registry);
563
564
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
565
let mut commands = system_state.get_mut(&mut world);
566
567
let entity = commands.spawn_empty().id();
568
let bundle = Box::new(BundleA {
569
a: ComponentA(31),
570
b: ComponentB(20),
571
}) as Box<dyn PartialReflect>;
572
573
commands
574
.entity(entity)
575
.insert_reflect_with_registry::<TypeRegistryResource>(bundle);
576
system_state.apply(&mut world);
577
578
assert_eq!(world.get::<ComponentA>(entity), Some(&ComponentA(31)));
579
assert_eq!(world.get::<ComponentB>(entity), Some(&ComponentB(20)));
580
}
581
582
#[test]
583
fn remove_reflected_bundle() {
584
let mut world = World::new();
585
586
let type_registry = AppTypeRegistry::default();
587
{
588
let mut registry = type_registry.write();
589
registry.register::<BundleA>();
590
registry.register_type_data::<BundleA, ReflectBundle>();
591
}
592
world.insert_resource(type_registry);
593
594
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
595
let mut commands = system_state.get_mut(&mut world);
596
597
let entity = commands
598
.spawn(BundleA {
599
a: ComponentA(31),
600
b: ComponentB(20),
601
})
602
.id();
603
604
let boxed_reflect_bundle_a = Box::new(BundleA {
605
a: ComponentA(1),
606
b: ComponentB(23),
607
}) as Box<dyn Reflect>;
608
609
commands
610
.entity(entity)
611
.remove_reflect(boxed_reflect_bundle_a.reflect_type_path().to_owned());
612
system_state.apply(&mut world);
613
614
assert_eq!(world.entity(entity).get::<ComponentA>(), None);
615
assert_eq!(world.entity(entity).get::<ComponentB>(), None);
616
}
617
618
#[test]
619
fn remove_reflected_bundle_with_registry() {
620
let mut world = World::new();
621
622
let mut type_registry = TypeRegistryResource {
623
type_registry: TypeRegistry::new(),
624
};
625
626
type_registry.type_registry.register::<BundleA>();
627
type_registry
628
.type_registry
629
.register_type_data::<BundleA, ReflectBundle>();
630
world.insert_resource(type_registry);
631
632
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
633
let mut commands = system_state.get_mut(&mut world);
634
635
let entity = commands
636
.spawn(BundleA {
637
a: ComponentA(31),
638
b: ComponentB(20),
639
})
640
.id();
641
642
let boxed_reflect_bundle_a = Box::new(BundleA {
643
a: ComponentA(1),
644
b: ComponentB(23),
645
}) as Box<dyn Reflect>;
646
647
commands
648
.entity(entity)
649
.remove_reflect_with_registry::<TypeRegistryResource>(
650
boxed_reflect_bundle_a.reflect_type_path().to_owned(),
651
);
652
system_state.apply(&mut world);
653
654
assert_eq!(world.entity(entity).get::<ComponentA>(), None);
655
assert_eq!(world.entity(entity).get::<ComponentB>(), None);
656
}
657
}
658
659