Skip to content

Commit 56bdd5c

Browse files
mbrea-cmockersf
authored andcommitted
Fix #19219 by moving observer triggers out of resource_scope (#19221)
# Objective Fixes #19219 ## Solution Instead of calling `world.commands().trigger` and `world.commands().trigger_targets` whenever each scene is spawned, save the `instance_id` and optional parent entity to perform all such calls at the end. This prevents the potential flush of the world command queue that can happen if `add_child` is called from causing the crash. ## Testing - Did you test these changes? If so, how? - Verified that I can no longer reproduce the bug with the instructions at #19219. - Ran `bevy_scene` tests - Visually verified that the following examples still run as expected `many_foxes`, `scene` . (should I test any more?) - Are there any parts that need more testing? - Pending to run `cargo test` at the root to test that all examples still build; I will update the PR when that's done - How can other people (reviewers) test your changes? Is there anything specific they need to know? - Run bevy as usual - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? - N/a (tested on Linux/wayland but it shouldn't be relevant) ---
1 parent bc00178 commit 56bdd5c

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

crates/bevy_scene/src/scene_spawner.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub struct SceneSpawner {
7979
scenes_to_despawn: Vec<AssetId<DynamicScene>>,
8080
instances_to_despawn: Vec<InstanceId>,
8181
scenes_with_parent: Vec<(InstanceId, Entity)>,
82+
instances_ready: Vec<(InstanceId, Option<Entity>)>,
8283
}
8384

8485
/// Errors that can occur when spawning a scene.
@@ -337,8 +338,9 @@ impl SceneSpawner {
337338
// Scenes with parents need more setup before they are ready.
338339
// See `set_scene_instance_parent_sync()`.
339340
if parent.is_none() {
340-
// Defer via commands otherwise SceneSpawner is not available in the observer.
341-
world.commands().trigger(SceneInstanceReady { instance_id });
341+
// We trigger `SceneInstanceReady` events after processing all scenes
342+
// SceneSpawner may not be available in the observer.
343+
self.instances_ready.push((instance_id, None));
342344
}
343345
}
344346
Err(SceneSpawnError::NonExistentScene { .. }) => {
@@ -362,8 +364,9 @@ impl SceneSpawner {
362364
// Scenes with parents need more setup before they are ready.
363365
// See `set_scene_instance_parent_sync()`.
364366
if parent.is_none() {
365-
// Defer via commands otherwise SceneSpawner is not available in the observer.
366-
world.commands().trigger(SceneInstanceReady { instance_id });
367+
// We trigger `SceneInstanceReady` events after processing all scenes
368+
// SceneSpawner may not be available in the observer.
369+
self.instances_ready.push((instance_id, None));
367370
}
368371
}
369372
Err(SceneSpawnError::NonExistentRealScene { .. }) => {
@@ -398,12 +401,25 @@ impl SceneSpawner {
398401
}
399402
}
400403

404+
// We trigger `SceneInstanceReady` events after processing all scenes
405+
// SceneSpawner may not be available in the observer.
406+
self.instances_ready.push((instance_id, Some(parent)));
407+
} else {
408+
self.scenes_with_parent.push((instance_id, parent));
409+
}
410+
}
411+
}
412+
413+
fn trigger_scene_ready_events(&mut self, world: &mut World) {
414+
for (instance_id, parent) in self.instances_ready.drain(..) {
415+
if let Some(parent) = parent {
401416
// Defer via commands otherwise SceneSpawner is not available in the observer.
402417
world
403418
.commands()
404419
.trigger_targets(SceneInstanceReady { instance_id }, parent);
405420
} else {
406-
self.scenes_with_parent.push((instance_id, parent));
421+
// Defer via commands otherwise SceneSpawner is not available in the observer.
422+
world.commands().trigger(SceneInstanceReady { instance_id });
407423
}
408424
}
409425
}
@@ -477,6 +493,7 @@ pub fn scene_spawner_system(world: &mut World) {
477493
.update_spawned_scenes(world, &updated_spawned_scenes)
478494
.unwrap();
479495
scene_spawner.set_scene_instance_parent_sync(world);
496+
scene_spawner.trigger_scene_ready_events(world);
480497
});
481498
}
482499

0 commit comments

Comments
 (0)