bevy_ecs/reflect/
entity_commands.rs

1use crate::{
2    prelude::Mut,
3    reflect::{AppTypeRegistry, ReflectBundle, ReflectComponent},
4    resource::Resource,
5    system::EntityCommands,
6    world::EntityWorldMut,
7};
8use alloc::{borrow::Cow, boxed::Box};
9use bevy_reflect::{PartialReflect, TypeRegistry};
10
11/// An extension trait for [`EntityCommands`] for reflection related functions
12pub 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
170impl 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
204impl<'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
310fn 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
333fn 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)]
349mod 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}