86 lines
2.7 KiB
Rust
86 lines
2.7 KiB
Rust
//! Standalone project-scene bootstrap.
|
|
|
|
use bevy::prelude::*;
|
|
use bevy::world_serialization::DynamicWorld;
|
|
use settings::ProjectSettings;
|
|
|
|
/// Runtime root for the standalone project's configured default level.
|
|
#[derive(Component, Debug)]
|
|
pub struct ProjectDefaultLevelRoot;
|
|
|
|
pub(crate) fn spawn_project_default_level(
|
|
mut commands: Commands,
|
|
asset_server: Res<AssetServer>,
|
|
settings: Res<ProjectSettings>,
|
|
existing: Query<(), With<ProjectDefaultLevelRoot>>,
|
|
) {
|
|
if !existing.is_empty() {
|
|
return;
|
|
}
|
|
|
|
let configured_path = settings.default_level.trim();
|
|
if configured_path.is_empty() {
|
|
error!("Project default_level is empty; standalone scene startup was skipped");
|
|
return;
|
|
}
|
|
|
|
let asset_path = shared::asset_server_path(configured_path);
|
|
let handle: Handle<DynamicWorld> = asset_server.load(asset_path.clone());
|
|
commands.spawn((
|
|
Name::new(format!("Project Default Level ({configured_path})")),
|
|
ProjectDefaultLevelRoot,
|
|
DynamicWorldRoot(handle),
|
|
));
|
|
info!("Loading project default level {configured_path} ({asset_path})");
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use bevy::asset::AssetPlugin;
|
|
use bevy::world_serialization::WorldSerializationPlugin;
|
|
|
|
fn test_app(default_level: &str) -> App {
|
|
let mut app = App::new();
|
|
app.add_plugins((
|
|
MinimalPlugins,
|
|
AssetPlugin::default(),
|
|
WorldSerializationPlugin,
|
|
));
|
|
app.insert_resource(ProjectSettings {
|
|
default_level: default_level.to_string(),
|
|
..Default::default()
|
|
});
|
|
app
|
|
}
|
|
|
|
#[test]
|
|
fn standalone_bootstrap_uses_the_project_default_level() {
|
|
let mut app = test_app("assets/levels/editor_scene.scn.ron");
|
|
app.add_systems(Startup, spawn_project_default_level);
|
|
|
|
app.update();
|
|
|
|
let world = app.world_mut();
|
|
let mut roots = world.query_filtered::<&DynamicWorldRoot, With<ProjectDefaultLevelRoot>>();
|
|
let root = roots.single(world).expect("one standalone scene root");
|
|
let path = world
|
|
.resource::<AssetServer>()
|
|
.get_path(root.0.id())
|
|
.expect("default level handle retains its asset path");
|
|
assert_eq!(path.to_string(), "levels/editor_scene.scn.ron");
|
|
}
|
|
|
|
#[test]
|
|
fn empty_default_level_does_not_create_a_runtime_root() {
|
|
let mut app = test_app(" ");
|
|
app.add_systems(Startup, spawn_project_default_level);
|
|
|
|
app.update();
|
|
|
|
let world = app.world_mut();
|
|
let mut roots = world.query_filtered::<Entity, With<ProjectDefaultLevelRoot>>();
|
|
assert_eq!(roots.iter(world).count(), 0);
|
|
}
|
|
}
|