diff --git a/crates/bevy_scene/src/scene.rs b/crates/bevy_scene/src/scene.rs index f44c1d8af7d37..0bbe86732ca5c 100644 --- a/crates/bevy_scene/src/scene.rs +++ b/crates/bevy_scene/src/scene.rs @@ -1,6 +1,6 @@ -use crate::{DynamicScene, SceneSpawnError}; +use crate::{DynamicScene, InstanceInfo, SceneSpawnError}; use bevy_asset::Asset; -use bevy_ecs::entity::{Entity, EntityHashMap}; +use bevy_ecs::entity::EntityHashMap; use bevy_ecs::{ reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource}, world::World, @@ -43,8 +43,7 @@ impl Scene { /// provided [`AppTypeRegistry`] or doesn't reflect the [`Component`](bevy_ecs::component::Component) trait. pub fn clone_with(&self, type_registry: &AppTypeRegistry) -> Result { let mut new_world = World::new(); - let mut entity_map = EntityHashMap::default(); - self.write_to_world_with(&mut new_world, &mut entity_map, type_registry)?; + self.write_to_world_with(&mut new_world, type_registry)?; Ok(Self { world: new_world }) } @@ -55,9 +54,12 @@ impl Scene { pub fn write_to_world_with( &self, world: &mut World, - entity_map: &mut EntityHashMap, type_registry: &AppTypeRegistry, - ) -> Result<(), SceneSpawnError> { + ) -> Result { + let mut instance_info = InstanceInfo { + entity_map: EntityHashMap::default(), + }; + let type_registry = type_registry.read(); // Resources archetype @@ -92,7 +94,8 @@ impl Scene { for archetype in self.world.archetypes().iter() { for scene_entity in archetype.entities() { - let entity = entity_map + let entity = *instance_info + .entity_map .entry(scene_entity.id()) .or_insert_with(|| world.spawn_empty().id()); for component_id in archetype.components() { @@ -118,7 +121,7 @@ impl Scene { &self.world, world, scene_entity.id(), - *entity, + entity, &type_registry, ); } @@ -127,10 +130,10 @@ impl Scene { for registration in type_registry.iter() { if let Some(map_entities_reflect) = registration.data::() { - map_entities_reflect.map_all_entities(world, entity_map); + map_entities_reflect.map_all_entities(world, &mut instance_info.entity_map); } } - Ok(()) + Ok(instance_info) } } diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index c9323465f1b2d..8706937f349de 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -221,7 +221,6 @@ impl SceneSpawner { let scene = scenes .get(id) .ok_or(SceneSpawnError::NonExistentScene { id })?; - scene.write_to_world(world, entity_map) }) } @@ -230,33 +229,27 @@ impl SceneSpawner { pub fn spawn_sync( &mut self, world: &mut World, - id: impl Into>, + id: AssetId, ) -> Result { - let mut entity_map = EntityHashMap::default(); - let id = id.into(); - Self::spawn_sync_internal(world, id, &mut entity_map)?; - let instance_id = InstanceId::new(); - self.spawned_instances - .insert(instance_id, InstanceInfo { entity_map }); - Ok(instance_id) + self.spawn_sync_internal(world, id, InstanceId::new()) } fn spawn_sync_internal( - // &mut self, + &mut self, world: &mut World, id: AssetId, - entity_map: &mut EntityHashMap, - ) -> Result<(), SceneSpawnError> { + instance_id: InstanceId, + ) -> Result { world.resource_scope(|world, scenes: Mut>| { let scene = scenes .get(id) .ok_or(SceneSpawnError::NonExistentRealScene { id })?; - scene.write_to_world_with( - world, - entity_map, - &world.resource::().clone(), - ) + let instance_info = + scene.write_to_world_with(world, &world.resource::().clone())?; + + self.spawned_instances.insert(instance_id, instance_info); + Ok(instance_id) }) } @@ -326,9 +319,7 @@ impl SceneSpawner { let scenes_to_spawn = std::mem::take(&mut self.scenes_to_spawn); for (scene_handle, instance_id) in scenes_to_spawn { - let mut entity_map = EntityHashMap::default(); - - match Self::spawn_sync_internal(world, scene_handle.id(), &mut entity_map) { + match self.spawn_sync_internal(world, scene_handle.id(), instance_id) { Ok(_) => {} Err(SceneSpawnError::NonExistentRealScene { .. }) => { self.scenes_to_spawn.push((scene_handle, instance_id));