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, |         &mut self, | ||||||
|         world: &mut World, |         world: &mut World, | ||||||
|         id: impl Into<AssetId<DynamicScene>>, |         id: impl Into<AssetId<DynamicScene>>, | ||||||
|     ) -> Result<(), SceneSpawnError> { |     ) -> Result<InstanceId, SceneSpawnError> { | ||||||
|         let mut entity_map = EntityHashMap::default(); |         let mut entity_map = EntityHashMap::default(); | ||||||
|         let id = id.into(); |         let id = id.into(); | ||||||
|         Self::spawn_dynamic_internal(world, id, &mut entity_map)?; |         Self::spawn_dynamic_internal(world, id, &mut entity_map)?; | ||||||
| @ -207,7 +207,7 @@ impl SceneSpawner { | |||||||
|             .insert(instance_id, InstanceInfo { entity_map }); |             .insert(instance_id, InstanceInfo { entity_map }); | ||||||
|         let spawned = self.spawned_dynamic_scenes.entry(id).or_default(); |         let spawned = self.spawned_dynamic_scenes.entry(id).or_default(); | ||||||
|         spawned.push(instance_id); |         spawned.push(instance_id); | ||||||
|         Ok(()) |         Ok(instance_id) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn spawn_dynamic_internal( |     fn spawn_dynamic_internal( | ||||||
| @ -434,3 +434,67 @@ pub fn scene_spawner_system(world: &mut World) { | |||||||
|         scene_spawner.set_scene_instance_parent_sync(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
	 thebluefish
						thebluefish