Skip to content

Commit bf53cf3

Browse files
authored
Align Scene::write_to_world_with to match DynamicScene::write_to_world_with (#13855)
# Objective Fixes a regression in [previously merged but then reverted pr](#13714) that aligns lower-level `Scene` API with that in `DynamicScene`. Please look at the original pr for more details. The problem was `spawn_sync_internal` is used in `spawn_queued_scenes`. Since instance creation was moved up a level we need to make sure we add a specific instance to `SceneSpawner::spawned_instances` when using `spawn_sync_internal` (just like we do for `DynamicScene`). Please look at the last commit when reviewing. ## Testing `alien_cake_addict` and `deferred_rendering` examples look as expected. ## Changelog Changed `Scene::write_to_world_with` to take `entity_map` as an argument and no longer return an `InstanceInfo` ## Migration Guide `Scene::write_to_world_with` no longer returns an `InstanceInfo`. Before ```rust scene.write_to_world_with(world, &registry) ``` After ```rust let mut entity_map = EntityHashMap::default(); scene.write_to_world_with(world, &mut entity_map, &registry) ```
1 parent 4340f7b commit bf53cf3

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

crates/bevy_scene/src/scene.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use crate::{DynamicScene, InstanceInfo, SceneSpawnError};
1+
use crate::{DynamicScene, SceneSpawnError};
22
use bevy_asset::Asset;
3-
use bevy_ecs::entity::EntityHashMap;
3+
use bevy_ecs::entity::{Entity, EntityHashMap};
44
use bevy_ecs::{
55
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
66
world::World,
@@ -43,7 +43,8 @@ impl Scene {
4343
/// provided [`AppTypeRegistry`] or doesn't reflect the [`Component`](bevy_ecs::component::Component) trait.
4444
pub fn clone_with(&self, type_registry: &AppTypeRegistry) -> Result<Scene, SceneSpawnError> {
4545
let mut new_world = World::new();
46-
self.write_to_world_with(&mut new_world, type_registry)?;
46+
let mut entity_map = EntityHashMap::default();
47+
self.write_to_world_with(&mut new_world, &mut entity_map, type_registry)?;
4748
Ok(Self { world: new_world })
4849
}
4950

@@ -54,12 +55,9 @@ impl Scene {
5455
pub fn write_to_world_with(
5556
&self,
5657
world: &mut World,
58+
entity_map: &mut EntityHashMap<Entity>,
5759
type_registry: &AppTypeRegistry,
58-
) -> Result<InstanceInfo, SceneSpawnError> {
59-
let mut instance_info = InstanceInfo {
60-
entity_map: EntityHashMap::default(),
61-
};
62-
60+
) -> Result<(), SceneSpawnError> {
6361
let type_registry = type_registry.read();
6462

6563
// Resources archetype
@@ -94,8 +92,7 @@ impl Scene {
9492

9593
for archetype in self.world.archetypes().iter() {
9694
for scene_entity in archetype.entities() {
97-
let entity = *instance_info
98-
.entity_map
95+
let entity = entity_map
9996
.entry(scene_entity.id())
10097
.or_insert_with(|| world.spawn_empty().id());
10198
for component_id in archetype.components() {
@@ -121,7 +118,7 @@ impl Scene {
121118
&self.world,
122119
world,
123120
scene_entity.id(),
124-
entity,
121+
*entity,
125122
&type_registry,
126123
);
127124
}
@@ -130,10 +127,10 @@ impl Scene {
130127

131128
for registration in type_registry.iter() {
132129
if let Some(map_entities_reflect) = registration.data::<ReflectMapEntities>() {
133-
map_entities_reflect.map_all_entities(world, &mut instance_info.entity_map);
130+
map_entities_reflect.map_all_entities(world, entity_map);
134131
}
135132
}
136133

137-
Ok(instance_info)
134+
Ok(())
138135
}
139136
}

crates/bevy_scene/src/scene_spawner.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ impl SceneSpawner {
226226
let scene = scenes
227227
.get(id)
228228
.ok_or(SceneSpawnError::NonExistentScene { id })?;
229+
229230
scene.write_to_world(world, entity_map)
230231
})
231232
}
@@ -234,27 +235,32 @@ impl SceneSpawner {
234235
pub fn spawn_sync(
235236
&mut self,
236237
world: &mut World,
237-
id: AssetId<Scene>,
238+
id: impl Into<AssetId<Scene>>,
238239
) -> Result<InstanceId, SceneSpawnError> {
239-
self.spawn_sync_internal(world, id, InstanceId::new())
240+
let mut entity_map = EntityHashMap::default();
241+
let id = id.into();
242+
Self::spawn_sync_internal(world, id, &mut entity_map)?;
243+
let instance_id = InstanceId::new();
244+
self.spawned_instances
245+
.insert(instance_id, InstanceInfo { entity_map });
246+
Ok(instance_id)
240247
}
241248

242249
fn spawn_sync_internal(
243-
&mut self,
244250
world: &mut World,
245251
id: AssetId<Scene>,
246-
instance_id: InstanceId,
247-
) -> Result<InstanceId, SceneSpawnError> {
252+
entity_map: &mut EntityHashMap<Entity>,
253+
) -> Result<(), SceneSpawnError> {
248254
world.resource_scope(|world, scenes: Mut<Assets<Scene>>| {
249255
let scene = scenes
250256
.get(id)
251257
.ok_or(SceneSpawnError::NonExistentRealScene { id })?;
252258

253-
let instance_info =
254-
scene.write_to_world_with(world, &world.resource::<AppTypeRegistry>().clone())?;
255-
256-
self.spawned_instances.insert(instance_id, instance_info);
257-
Ok(instance_id)
259+
scene.write_to_world_with(
260+
world,
261+
entity_map,
262+
&world.resource::<AppTypeRegistry>().clone(),
263+
)
258264
})
259265
}
260266

@@ -334,8 +340,13 @@ impl SceneSpawner {
334340
let scenes_to_spawn = std::mem::take(&mut self.scenes_to_spawn);
335341

336342
for (scene_handle, instance_id, parent) in scenes_to_spawn {
337-
match self.spawn_sync_internal(world, scene_handle.id(), instance_id) {
343+
let mut entity_map = EntityHashMap::default();
344+
345+
match Self::spawn_sync_internal(world, scene_handle.id(), &mut entity_map) {
338346
Ok(_) => {
347+
self.spawned_instances
348+
.insert(instance_id, InstanceInfo { entity_map });
349+
339350
// Scenes with parents need more setup before they are ready.
340351
// See `set_scene_instance_parent_sync()`.
341352
if parent.is_none() {

0 commit comments

Comments
 (0)