Skip to content

Commit 0cf276f

Browse files
miniexBluefingerDasLixouShatur
authored
Enhance ReflectCommandExt (#15128)
# Objective - Enhance #15125 ## Solution - Modified `ReflectCommandExt::insert_reflect` to accept and handle both components and bundles. --------- Co-authored-by: Gonçalo Rica Pais da Silva <[email protected]> Co-authored-by: Lixou <[email protected]> Co-authored-by: Hennadii Chernyshchyk <[email protected]>
1 parent 90bb1ad commit 0cf276f

File tree

1 file changed

+55
-8
lines changed

1 file changed

+55
-8
lines changed

crates/bevy_ecs/src/reflect/entity_commands.rs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ use crate::prelude::Mut;
22
use crate::reflect::AppTypeRegistry;
33
use crate::system::{EntityCommands, Resource};
44
use crate::world::Command;
5-
use crate::{entity::Entity, reflect::ReflectComponent, world::World};
5+
use crate::{
6+
entity::Entity,
7+
reflect::{ReflectBundle, ReflectComponent},
8+
world::World,
9+
};
610
use bevy_reflect::{PartialReflect, TypeRegistry};
711
use std::borrow::Cow;
812
use std::marker::PhantomData;
@@ -198,12 +202,16 @@ fn insert_reflect(
198202
panic!("error[B0003]: Could not insert a reflected component (of type {type_path}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003");
199203
};
200204
let Some(type_registration) = type_registry.get(type_info.type_id()) else {
201-
panic!("Could not get type registration (for component type {type_path}) because it doesn't exist in the TypeRegistry.");
205+
panic!("`{type_path}` should be registered in type registry via `App::register_type<{type_path}>`");
202206
};
203-
let Some(reflect_component) = type_registration.data::<ReflectComponent>() else {
204-
panic!("Could not get ReflectComponent data (for component type {type_path}) because it doesn't exist in this TypeRegistration.");
205-
};
206-
reflect_component.insert(&mut entity, component.as_partial_reflect(), type_registry);
207+
208+
if let Some(reflect_component) = type_registration.data::<ReflectComponent>() {
209+
reflect_component.insert(&mut entity, component.as_partial_reflect(), type_registry);
210+
} else if let Some(reflect_bundle) = type_registration.data::<ReflectBundle>() {
211+
reflect_bundle.insert(&mut entity, component.as_partial_reflect(), type_registry);
212+
} else {
213+
panic!("`{type_path}` should have #[reflect(Component)] or #[reflect(Bundle)]");
214+
}
207215
}
208216

209217
/// A [`Command`] that adds the boxed reflect component to an entity using the data in
@@ -313,9 +321,9 @@ impl<T: Resource + AsRef<TypeRegistry>> Command for RemoveReflectWithRegistry<T>
313321
#[cfg(test)]
314322
mod tests {
315323
use crate::prelude::{AppTypeRegistry, ReflectComponent};
316-
use crate::reflect::ReflectCommandExt;
324+
use crate::reflect::{ReflectBundle, ReflectCommandExt};
317325
use crate::system::{Commands, SystemState};
318-
use crate::{self as bevy_ecs, component::Component, world::World};
326+
use crate::{self as bevy_ecs, bundle::Bundle, component::Component, world::World};
319327
use bevy_ecs_macros::Resource;
320328
use bevy_reflect::{PartialReflect, Reflect, TypeRegistry};
321329

@@ -334,6 +342,17 @@ mod tests {
334342
#[reflect(Component)]
335343
struct ComponentA(u32);
336344

345+
#[derive(Component, Reflect, Default, PartialEq, Eq, Debug)]
346+
#[reflect(Component)]
347+
struct ComponentB(u32);
348+
349+
#[derive(Bundle, Reflect, Default, Debug, PartialEq)]
350+
#[reflect(Bundle)]
351+
struct BundleA {
352+
a: ComponentA,
353+
b: ComponentB,
354+
}
355+
337356
#[test]
338357
fn insert_reflected() {
339358
let mut world = World::new();
@@ -458,4 +477,32 @@ mod tests {
458477

459478
assert_eq!(world.entity(entity).get::<ComponentA>(), None);
460479
}
480+
481+
#[test]
482+
fn insert_reflect_bundle() {
483+
let mut world = World::new();
484+
485+
let type_registry = AppTypeRegistry::default();
486+
{
487+
let mut registry = type_registry.write();
488+
registry.register::<BundleA>();
489+
registry.register_type_data::<BundleA, ReflectBundle>();
490+
}
491+
world.insert_resource(type_registry);
492+
493+
let mut system_state: SystemState<Commands> = SystemState::new(&mut world);
494+
let mut commands = system_state.get_mut(&mut world);
495+
496+
let entity = commands.spawn_empty().id();
497+
let bundle = Box::new(BundleA {
498+
a: ComponentA(31),
499+
b: ComponentB(20),
500+
}) as Box<dyn PartialReflect>;
501+
commands.entity(entity).insert_reflect(bundle);
502+
503+
system_state.apply(&mut world);
504+
505+
assert_eq!(world.get::<ComponentA>(entity), Some(&ComponentA(31)));
506+
assert_eq!(world.get::<ComponentB>(entity), Some(&ComponentB(20)));
507+
}
461508
}

0 commit comments

Comments
 (0)