From 025030559a66f8bfc0114820020a20ff8e6ccc20 Mon Sep 17 00:00:00 2001 From: Robin KAY Date: Sat, 15 Jun 2024 11:25:51 +0100 Subject: [PATCH 1/3] Change `SceneInstanceReady` to trigger an observer. --- crates/bevy_scene/src/scene_spawner.rs | 50 +++++++++++++++++--------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index 8706937f349de..96a1625a5b9fb 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -18,8 +18,8 @@ use uuid::Uuid; /// See also [`SceneSpawner::instance_is_ready`]. #[derive(Clone, Copy, Debug, Eq, PartialEq, Event)] pub struct SceneInstanceReady { - /// Entity to which the scene was spawned as a child. - pub parent: Entity, + /// Instance which has been spawned. + pub instance_id: InstanceId, } /// Information about a scene instance. @@ -356,7 +356,10 @@ impl SceneSpawner { } } - world.send_event(SceneInstanceReady { parent }); + // Defer via commands otherwise SceneSpawner is not available in the observer. + world + .commands() + .trigger_targets(SceneInstanceReady { instance_id }, parent); } else { self.scenes_with_parent.push((instance_id, parent)); } @@ -439,7 +442,7 @@ pub fn scene_spawner_system(world: &mut World) { mod tests { use bevy_app::App; use bevy_asset::{AssetPlugin, AssetServer}; - use bevy_ecs::event::EventReader; + use bevy_ecs::observer::Trigger; use bevy_ecs::prelude::ReflectComponent; use bevy_ecs::query::With; use bevy_ecs::system::{Commands, Res, ResMut, RunSystemOnce}; @@ -505,10 +508,14 @@ mod tests { #[reflect(Component)] struct ComponentA; + #[derive(Resource, Default)] + struct TriggerCount(u32); + #[test] fn event() { let mut app = App::new(); app.add_plugins((AssetPlugin::default(), ScenePlugin)); + app.init_resource::(); app.register_type::(); app.world_mut().spawn(ComponentA); @@ -530,22 +537,33 @@ mod tests { }, ); - // Check for event arrival. - app.update(); - app.world_mut().run_system_once( - move |mut ev_scene: EventReader<'_, '_, SceneInstanceReady>| { - let mut events = ev_scene.read(); - + // Add observer + app.world_mut().observe( + move |trigger: Trigger, + scene_spawner: Res, + mut trigger_count: ResMut| { assert_eq!( - events.next().expect("found no `SceneInstanceReady` event"), - &SceneInstanceReady { - parent: scene_entity - }, - "`SceneInstanceReady` contains the wrong parent entity" + trigger.entity(), + scene_entity, + "`SceneInstanceReady` triggered on the wrong parent entity" + ); + assert!( + scene_spawner.instance_is_ready(trigger.event().instance_id), + "`InstanceId` is not ready" ); - assert!(events.next().is_none(), "found more than one event"); + trigger_count.0 += 1; }, ); + + // Check observer is triggered once. + app.update(); + app.world_mut() + .run_system_once(|trigger_count: Res| { + assert_eq!( + trigger_count.0, 1, + "wrong number of `SceneInstanceReady` triggers" + ); + }); } #[test] From 788abdd116eba1acdea8ca8fd2c364d88d69d2f4 Mon Sep 17 00:00:00 2001 From: Robin KAY Date: Sat, 15 Jun 2024 11:37:40 +0100 Subject: [PATCH 2/3] Remove unnecessary event registration for `SceneInstanceReady`. --- crates/bevy_scene/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index fa00fde5cc510..b7bc473ca06d4 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -56,7 +56,6 @@ impl Plugin for ScenePlugin { app.init_asset::() .init_asset::() .init_asset_loader::() - .add_event::() .init_resource::() .add_systems(SpawnScene, (scene_spawner, scene_spawner_system).chain()); From 76171f52a7df363ebcbc2b23849ad6e3152a8628 Mon Sep 17 00:00:00 2001 From: Robin KAY Date: Wed, 19 Jun 2024 18:36:32 +0100 Subject: [PATCH 3/3] Improve documentation of `SceneInstanceReady`. --- crates/bevy_scene/src/scene_spawner.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index 96a1625a5b9fb..a865798abf2e1 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -13,9 +13,11 @@ use bevy_utils::{tracing::error, HashMap, HashSet}; use thiserror::Error; use uuid::Uuid; -/// Emitted when [`crate::SceneInstance`] becomes ready to use. +/// Triggered on a scene's parent entity when [`crate::SceneInstance`] becomes ready to use. /// -/// See also [`SceneSpawner::instance_is_ready`]. +/// See also [`Trigger`], [`SceneSpawner::instance_is_ready`]. +/// +/// [`Trigger`]: bevy_ecs::observer::Trigger #[derive(Clone, Copy, Debug, Eq, PartialEq, Event)] pub struct SceneInstanceReady { /// Instance which has been spawned.