Change SceneSpawner::spawn_dynamic_sync to return InstanceID (#11239)
# Objective `SceneSpawner::spawn_dynamic_sync` currently returns `()` on success, which is inconsistent with the other `SceneSpawner::spawn_` methods that all return an `InstanceId`. We need this ID to do useful work with the newly-created data. ## Solution Updated `SceneSpawner::spawn_dynamic_sync` to return `Result<InstanceId, SceneSpawnError>` instead of `Result<(), SceneSpawnError>`
This commit is contained in:
parent
0349809420
commit
cfcb6885e3
@ -198,7 +198,7 @@ impl SceneSpawner {
|
||||
&mut self,
|
||||
world: &mut World,
|
||||
id: impl Into<AssetId<DynamicScene>>,
|
||||
) -> Result<(), SceneSpawnError> {
|
||||
) -> Result<InstanceId, SceneSpawnError> {
|
||||
let mut entity_map = EntityHashMap::default();
|
||||
let id = id.into();
|
||||
Self::spawn_dynamic_internal(world, id, &mut entity_map)?;
|
||||
@ -207,7 +207,7 @@ impl SceneSpawner {
|
||||
.insert(instance_id, InstanceInfo { entity_map });
|
||||
let spawned = self.spawned_dynamic_scenes.entry(id).or_default();
|
||||
spawned.push(instance_id);
|
||||
Ok(())
|
||||
Ok(instance_id)
|
||||
}
|
||||
|
||||
fn spawn_dynamic_internal(
|
||||
@ -434,3 +434,67 @@ pub fn scene_spawner_system(world: &mut World) {
|
||||
scene_spawner.set_scene_instance_parent_sync(world);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use bevy_ecs::component::Component;
|
||||
use bevy_ecs::entity::Entity;
|
||||
use bevy_ecs::prelude::ReflectComponent;
|
||||
use bevy_ecs::query::With;
|
||||
use bevy_ecs::{reflect::AppTypeRegistry, world::World};
|
||||
|
||||
use crate::DynamicSceneBuilder;
|
||||
use bevy_reflect::Reflect;
|
||||
|
||||
#[derive(Reflect, Component, Debug, PartialEq, Eq, Clone, Copy, Default)]
|
||||
#[reflect(Component)]
|
||||
struct A(usize);
|
||||
|
||||
#[test]
|
||||
fn clone_dynamic_entities() {
|
||||
let mut world = World::default();
|
||||
|
||||
// setup
|
||||
let atr = AppTypeRegistry::default();
|
||||
atr.write().register::<A>();
|
||||
world.insert_resource(atr);
|
||||
world.insert_resource(Assets::<DynamicScene>::default());
|
||||
|
||||
// start test
|
||||
world.spawn(A(42));
|
||||
|
||||
assert_eq!(world.query::<&A>().iter(&world).len(), 1);
|
||||
|
||||
// clone only existing entity
|
||||
let mut scene_spawner = SceneSpawner::default();
|
||||
let entity = world.query_filtered::<Entity, With<A>>().single(&world);
|
||||
let scene = DynamicSceneBuilder::from_world(&world)
|
||||
.extract_entity(entity)
|
||||
.build();
|
||||
|
||||
let scene_id = world.resource_mut::<Assets<DynamicScene>>().add(scene);
|
||||
let instance_id = scene_spawner
|
||||
.spawn_dynamic_sync(&mut world, scene_id)
|
||||
.unwrap();
|
||||
|
||||
// verify we spawned exactly one new entity with our expected component
|
||||
assert_eq!(world.query::<&A>().iter(&world).len(), 2);
|
||||
|
||||
// verify that we can get this newly-spawned entity by the instance ID
|
||||
let new_entity = scene_spawner
|
||||
.iter_instance_entities(instance_id)
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
// verify this is not the original entity
|
||||
assert_ne!(entity, new_entity);
|
||||
|
||||
// verify this new entity contains the same data as the original entity
|
||||
let [old_a, new_a] = world
|
||||
.query::<&A>()
|
||||
.get_many(&world, [entity, new_entity])
|
||||
.unwrap();
|
||||
assert_eq!(old_a, new_a);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user