diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index 830e5a870a0a0..898f953134c30 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -509,7 +509,7 @@ pub mod prelude { pub use crate::{ bsn, bsn_list, on, template_value, CommandsSceneExt, EntityCommandsSceneExt, EntityWorldMutSceneExt, PatchFromTemplate, PatchTemplate, Scene, SceneList, - ScenePatchInstance, WorldSceneExt, + ScenePatchInstance, SpawnListSystem, SpawnSystem, WorldSceneExt, }; } @@ -523,6 +523,7 @@ mod scene; mod scene_list; mod scene_patch; mod spawn; +mod spawn_system; pub use bevy_scene_macros::*; pub use resolved_scene::*; @@ -530,6 +531,7 @@ pub use scene::*; pub use scene_list::*; pub use scene_patch::*; pub use spawn::*; +pub use spawn_system::*; use bevy_app::{App, Plugin, SceneSpawnerSystems, SpawnScene}; use bevy_asset::AssetApp; diff --git a/crates/bevy_scene/src/spawn_system.rs b/crates/bevy_scene/src/spawn_system.rs new file mode 100644 index 0000000000000..3f4f396a80c5f --- /dev/null +++ b/crates/bevy_scene/src/spawn_system.rs @@ -0,0 +1,35 @@ +use crate::{Scene, SceneList, WorldSceneExt}; +use bevy_ecs::{error::Result, world::World}; + +/// Returns a system that spawns the given [`Scene`]. This should generally only be added to +/// schedules that run once, such as [`Startup`](bevy_app::Startup). +pub trait SpawnSystem { + /// Returns a system that spawns the given [`Scene`]. This should generally only be added to + /// schedules that run once, such as [`Startup`](bevy_app::Startup). + fn spawn(self) -> impl FnMut(&mut World) -> Result; +} + +impl S + Send + Sync + 'static, S: Scene> SpawnSystem for F { + fn spawn(mut self) -> impl FnMut(&mut World) -> Result { + move |world: &mut World| -> Result { + world.spawn_scene(self())?; + Ok(()) + } + } +} + +/// Returns a system that spawns the given [`SceneList`]. This should generally only be added to +/// schedules that run once, such as [`Startup`](bevy_app::Startup). +pub trait SpawnListSystem { + /// Returns a system that spawns the given [`SceneList`]. This should generally only be added to + /// schedules that run once, such as [`Startup`](bevy_app::Startup). + fn spawn(self) -> impl FnMut(&mut World) -> Result; +} +impl S + Send + Sync + 'static, S: SceneList> SpawnListSystem for F { + fn spawn(mut self) -> impl FnMut(&mut World) -> Result { + move |world: &mut World| -> Result { + world.spawn_scene_list(self())?; + Ok(()) + } + } +} diff --git a/examples/scene/bsn.rs b/examples/scene/bsn.rs index c8356204be41a..0d8475e0b3640 100644 --- a/examples/scene/bsn.rs +++ b/examples/scene/bsn.rs @@ -4,13 +4,12 @@ use bevy::{prelude::*, text::FontSourceTemplate}; fn main() { App::new() .add_plugins(DefaultPlugins) - .add_systems(Startup, setup) + .add_systems(Startup, scene.spawn()) .run(); } -fn setup(world: &mut World) -> Result { - world.spawn_scene_list(bsn_list![Camera2d, ui()])?; - Ok(()) +fn scene() -> impl SceneList { + bsn_list![Camera2d, ui()] } fn ui() -> impl Scene { diff --git a/examples/ui/widgets/feathers_counter.rs b/examples/ui/widgets/feathers_counter.rs index 8e74b9c810265..642f70d84276c 100644 --- a/examples/ui/widgets/feathers_counter.rs +++ b/examples/ui/widgets/feathers_counter.rs @@ -10,7 +10,6 @@ use bevy::{ tokens, FeathersPlugins, }, prelude::*, - scene::prelude::Scene, ui_widgets::Activate, }; @@ -31,7 +30,7 @@ fn main() { // Configure feathers to use the dark theme .insert_resource(UiTheme(create_dark_theme())) .insert_resource(Counter(0)) - .add_systems(Startup, setup) + .add_systems(Startup, scene.spawn()) .add_systems( Update, update_counter_text.run_if(resource_changed::), @@ -39,9 +38,8 @@ fn main() { .run(); } -fn setup(world: &mut World) -> Result { - world.spawn_scene_list(bsn_list![Camera2d, demo_root()])?; - Ok(()) +fn scene() -> impl SceneList { + bsn_list![Camera2d, demo_root()] } fn demo_root() -> impl Scene { diff --git a/examples/ui/widgets/feathers_gallery.rs b/examples/ui/widgets/feathers_gallery.rs index 329c6dc712c14..26b12e2a92df8 100644 --- a/examples/ui/widgets/feathers_gallery.rs +++ b/examples/ui/widgets/feathers_gallery.rs @@ -26,7 +26,6 @@ use bevy::{ }, input_focus::{tab_navigation::TabGroup, AutoFocus, InputFocus}, prelude::*, - scene::prelude::Scene, text::{EditableText, TextEdit, TextEditChange}, ui::{Checked, InteractionDisabled}, ui_widgets::{ @@ -64,14 +63,13 @@ fn main() { rgb_color: palettes::tailwind::EMERALD_800.with_alpha(0.7), hsl_color: palettes::tailwind::AMBER_800.into(), }) - .add_systems(Startup, setup) + .add_systems(Startup, scene.spawn()) .add_systems(Update, update_colors) .run(); } -fn setup(world: &mut World) -> Result { - world.spawn_scene_list(bsn_list![Camera2d, demo_root()])?; - Ok(()) +fn scene() -> impl SceneList { + bsn_list![Camera2d, demo_root()] } fn demo_root() -> impl Scene { diff --git a/examples/ui/widgets/virtual_keyboard.rs b/examples/ui/widgets/virtual_keyboard.rs index ef4cab7221d19..70cde4c057383 100644 --- a/examples/ui/widgets/virtual_keyboard.rs +++ b/examples/ui/widgets/virtual_keyboard.rs @@ -15,7 +15,7 @@ fn main() { App::new() .add_plugins((DefaultPlugins, FeathersPlugins)) .insert_resource(UiTheme(create_dark_theme())) - .add_systems(Startup, setup) + .add_systems(Startup, scene.spawn()) .run(); } @@ -23,9 +23,8 @@ fn on_virtual_key_pressed(virtual_key_pressed: On Result { - world.spawn_scene_list(bsn_list![Camera2d, keyboard()])?; - Ok(()) +fn scene() -> impl SceneList { + bsn_list![Camera2d, keyboard()] } fn keyboard() -> impl Scene {