diff --git a/crates/blenvy/old/README_save_load.md b/crates/blenvy/old/README_save_load.md index ec19e59..b4b9ff0 100644 --- a/crates/blenvy/old/README_save_load.md +++ b/crates/blenvy/old/README_save_load.md @@ -58,12 +58,12 @@ fn main() { // add a system to trigger saving pub fn request_save( - mut save_requests: EventWriter, + mut save_requests: EventWriter, keycode: Res>, ) { if keycode.just_pressed(KeyCode::S) { - save_requests.send(SaveRequest { + save_requests.send(SavingRequest { path: "save.scn.ron".into(), }) } @@ -225,16 +225,16 @@ fn main() { ## Events -- to trigger **saving** use the ```SaveRequest``` event +- to trigger **saving** use the ```SavingRequest``` event ```rust no_run // add a system to trigger saving pub fn request_save( - mut save_requests: EventWriter, + mut save_requests: EventWriter, keycode: Res>, ) { if keycode.just_pressed(KeyCode::S) { - save_requests.send(SaveRequest { + save_requests.send(SavingRequest { path: "save.scn.ron".into(), }) } diff --git a/crates/blenvy/src/save_load/common.rs b/crates/blenvy/src/save_load/common.rs new file mode 100644 index 0000000..1b5f4f4 --- /dev/null +++ b/crates/blenvy/src/save_load/common.rs @@ -0,0 +1,45 @@ +pub use bevy::prelude::*; + +use crate::{BlueprintInfo, GameWorldTag, HideUntilReady, SpawnBlueprint}; + +use super::{BlueprintWorld, Dynamic}; + +pub(crate) fn spawn_from_blueprintworld( + added_blueprint_worlds: Query<(Entity, &BlueprintWorld), Added >, + mut commands: Commands, +){ + for (entity, blueprint_world) in added_blueprint_worlds.iter(){ + println!("added blueprintWorld {:?}", blueprint_world); + + // here we spawn the static part our game world/level, which is also a blueprint ! + let static_world = commands.spawn(( + BlueprintInfo::from_path(blueprint_world.path.as_str()), // all we need is a Blueprint info... + SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now + HideUntilReady, // only reveal the level once it is ready + GameWorldTag, + )).id(); + + // here we spawn the dynamic entities part of our game world/level, which is also a blueprint ! + let dynamic_world = commands.spawn(( + BlueprintInfo::from_path(blueprint_world.path.replace(".glb", "_dynamic.glb").replace(".gltf", "_dynamic.gltf").as_str()), // all we need is a Blueprint info... + SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now + HideUntilReady, // only reveal the level once it is ready + GameWorldTag + )).id(); + + // commands.entity(entity).add_child(static_world); + // commands.entity(entity).add_child(dynamic_world); + } +} + +pub(crate) fn inject_dynamic_into_children( + added_dynamic: Query >, + all_children: Query<&Children>, + mut commands: Commands, +) { + for entity in added_dynamic.iter() { + for child in all_children.iter_descendants(entity) { + commands.entity(child).insert(Dynamic); + } + } +} \ No newline at end of file diff --git a/crates/blenvy/src/save_load/loading.rs b/crates/blenvy/src/save_load/loading.rs new file mode 100644 index 0000000..b98c09d --- /dev/null +++ b/crates/blenvy/src/save_load/loading.rs @@ -0,0 +1,118 @@ +use std::path::Path; + +use bevy::prelude::*; + +use crate::{BlenvyConfig, BlueprintInfo, DynamicEntitiesRoot, GameWorldTag, HideUntilReady, SpawnBlueprint}; + + +#[derive(Event)] +pub struct LoadingRequest { + pub path: String, +} + +#[derive(Event)] +pub struct LoadingFinished; // TODO: merge the two above + +/// resource that keeps track of the current load request +#[derive(Resource, Default)] +pub struct LoadingRequested { + pub path: String, +} + + +/* +- Loading + - load request recieved + - pause things ? + - unload everything + - load static data using blueprintInfo + - load dynamic data from save file + + +General: + * wrap loading a bevy scene as a blueprint ? + * meh, has no assets & co, different logic ? +*/ +pub fn process_load_requests( + mut load_requests: EventReader, + mut commands: Commands +) { + let mut save_path: String = "".into(); + for load_request in load_requests.read() { + if !load_request.path.is_empty() { + save_path.clone_from(&load_request.path); + } + } + if !save_path.is_empty() { + commands.insert_resource(LoadingRequested { path: save_path }); + } +} + +pub fn should_load(loading_requests: Option>) -> bool { + return resource_exists::(loading_requests) +} + +// TODO: replace with generic despawner ? +pub(crate) fn prepare_loading( + mut commands: Commands, + gameworlds: Query>, + +) { + for e in gameworlds.iter() { + info!("--loading: despawn old world/level"); + commands.entity(e).despawn_recursive(); + } +} + + + + +pub(crate) fn load_game( + mut commands: Commands, + asset_server: Res, + load_request: Res, +) { + info!("--loading: load dynamic data"); + + //let save_path = Path::new(load_request.path.clone().as_str()); + + info!("LOADING FROM {:?}", load_request.path.clone()); + + /*let world_root = commands + .spawn(( + bevy::prelude::Name::from("world"), + GameWorldTag, + TransformBundle::default(), + InheritedVisibility::default(), + )) + .id();*/ + + // and we fill it with dynamic data + // let input = std::fs::read(&path)?; + let dynamic_data = commands + .spawn(( + DynamicSceneBundle { + scene: asset_server.load(load_request.path.clone()), + ..default() + }, + bevy::prelude::Name::from("World_dynamic"), + DynamicEntitiesRoot, + GameWorldTag + )) + .id(); + + let static_data = commands.spawn(( + BlueprintInfo::from_path("levels/World.glb"), // all we need is a Blueprint info... + SpawnBlueprint, + HideUntilReady, + GameWorldTag, + )).id(); + + //commands.entity(world_root).add_child(static_data); + //commands.entity(world_root).add_child(dynamic_data); + + // commands.insert_resource(LoadFirstStageDone); + + info!("--loading: loaded dynamic data"); + commands.remove_resource::(); +} \ No newline at end of file diff --git a/crates/blenvy/src/save_load/mod.rs b/crates/blenvy/src/save_load/mod.rs index e88b968..ae982a4 100644 --- a/crates/blenvy/src/save_load/mod.rs +++ b/crates/blenvy/src/save_load/mod.rs @@ -1,5 +1,15 @@ +use std::path::Path; use bevy::prelude::*; +pub mod common; +pub use common::*; + +pub mod saving; +pub use saving::*; + +pub mod loading; +pub use loading::*; + #[derive(Component, Reflect, Debug, Default)] #[reflect(Component)] /// component used to mark any entity as Dynamic: aka add this to make sure your entity is going to be saved @@ -34,8 +44,22 @@ pub struct StaticEntitiesBlueprintInfo { } -pub mod saving; -pub use saving::*; + +#[derive(Component, Debug)] +pub struct BlueprintWorld{ + pub path: String, +} +impl BlueprintWorld { + pub fn from_path(path: &str) -> BlueprintWorld { + let p = Path::new(&path); + return BlueprintWorld { + // name: p.file_stem().unwrap().to_os_string().into_string().unwrap(), // seriously ? , also unwraps !! + path: path.into(), + }; + } +} + + #[derive(Debug, Clone, Default)] /// Plugin for saving & loading @@ -46,13 +70,33 @@ impl Plugin for SaveLoadPlugin { app.register_type::() .register_type::() - .add_event::() + .add_event::() .add_event::() + + // common + .add_systems(Update, (spawn_from_blueprintworld, )) // inject_dynamic_into_children + + // saving + .add_systems(Update, process_save_requests) .add_systems( Update, (prepare_save_game, apply_deferred, save_game, cleanup_save) .chain() .run_if(should_save), + + ) + + .add_event::() + .add_event::() + //loading + .add_systems(Update, process_load_requests) + .add_systems( + Update, + (prepare_loading, apply_deferred, load_game) + .chain() + .run_if(should_load), + //.run_if(not(resource_exists::)) + // .in_set(LoadingSet::Load), ) ; } diff --git a/crates/blenvy/src/save_load/old/loading.rs b/crates/blenvy/src/save_load/old/loading.rs index 9cc7fd8..f9f87ae 100644 --- a/crates/blenvy/src/save_load/old/loading.rs +++ b/crates/blenvy/src/save_load/old/loading.rs @@ -5,7 +5,7 @@ use std::path::Path; use crate::{DynamicEntitiesRoot, SaveLoadConfig, StaticEntitiesRoot, StaticEntitiesStorage}; #[derive(Event)] -pub struct LoadRequest { +pub struct LoadingRequest { pub path: String, } @@ -26,7 +26,7 @@ pub(crate) struct CleanupScene; /// helper system that "converts" loadRequest events to `LoadRequested` resources pub(crate) fn mark_load_requested( - mut load_requests: EventReader, + mut load_requests: EventReader, mut commands: Commands, ) { let mut save_path: String = "".into(); diff --git a/crates/blenvy/src/save_load/old/mod_old.rs b/crates/blenvy/src/save_load/old/mod_old.rs index fb9e2a0..f59111c 100644 --- a/crates/blenvy/src/save_load/old/mod_old.rs +++ b/crates/blenvy/src/save_load/old/mod_old.rs @@ -41,8 +41,8 @@ impl Plugin for SaveLoadPlugin { .register_type::() .register_type::() .register_type::() - .add_event::() - .add_event::() + .add_event::() + .add_event::() .add_event::() .add_event::() .configure_sets( diff --git a/crates/blenvy/src/save_load/old/saving.rs b/crates/blenvy/src/save_load/old/saving.rs index 2c2812d..3156c9b 100644 --- a/crates/blenvy/src/save_load/old/saving.rs +++ b/crates/blenvy/src/save_load/old/saving.rs @@ -9,14 +9,14 @@ use std::path::Path; use crate::{DynamicEntitiesRoot, SaveLoadConfig, StaticEntitiesRoot}; #[derive(Event, Debug)] -pub struct SaveRequest { +pub struct SavingRequest { pub path: String, } #[derive(Event)] pub struct SavingFinished; -pub fn should_save(save_requests: EventReader) -> bool { +pub fn should_save(save_requests: EventReader) -> bool { !save_requests.is_empty() } @@ -77,7 +77,7 @@ pub(crate) fn save_game(world: &mut World) { info!("saving"); let mut save_path: String = "".into(); - let mut events = world.resource_mut::>(); + let mut events = world.resource_mut::>(); for event in events.get_reader().read(&events) { info!("SAVE EVENT !! {:?}", event); diff --git a/crates/blenvy/src/save_load/saving.rs b/crates/blenvy/src/save_load/saving.rs index b94ba43..9971786 100644 --- a/crates/blenvy/src/save_load/saving.rs +++ b/crates/blenvy/src/save_load/saving.rs @@ -11,14 +11,38 @@ use crate::{BlenvyConfig, BlueprintInfo, Dynamic, FromBlueprint, RootEntity, Spa use super::{DynamicEntitiesRoot, OriginalParent, StaticEntitiesRoot}; #[derive(Event, Debug)] -pub struct SaveRequest { +pub struct SavingRequest { pub path: String, } #[derive(Event)] pub struct SaveFinished; // TODO: merge the the events above -pub fn should_save(save_requests: EventReader) -> bool { - !save_requests.is_empty() + +/// resource that keeps track of the current save request +#[derive(Resource, Default)] +pub struct SavingRequested { + pub path: String, +} + + +pub fn process_save_requests( + mut saving_requests: EventReader, + mut commands: Commands +) { + let mut save_path: String = "".into(); + for saving_request in saving_requests.read() { + if !saving_request.path.is_empty() { + save_path.clone_from(&saving_request.path); + } + } + if !save_path.is_empty() { + commands.insert_resource(SavingRequested { path: save_path }); + } +} + + +pub fn should_save(saving_requests: Option>) -> bool { + return resource_exists::(saving_requests) } @@ -31,12 +55,12 @@ pub(crate) fn prepare_save_game( mut commands: Commands, ) { - for entity in saveables.iter() { + for entity in saveables.iter() { // FIXME : not sure about this one commands.entity(entity).insert(SpawnBlueprint); } for (entity, parent, children) in dynamic_entities.iter() { - println!("prepare save game"); + println!("prepare save game for entity"); let parent = parent.get(); if root_entities.contains(parent) { commands.entity(entity).insert(RootEntity); @@ -66,7 +90,7 @@ pub(crate) fn save_game(world: &mut World) { info!("saving"); let mut save_path: String = "".into(); - let mut events = world.resource_mut::>(); + let mut events = world.resource_mut::>(); for event in events.get_reader().read(&events) { info!("SAVE EVENT !! {:?}", event); @@ -75,14 +99,14 @@ pub(crate) fn save_game(world: &mut World) { events.clear(); let saveable_entities: Vec = world - // .query_filtered::, Without, Without)>() .query_filtered::, Without)>() + // .query_filtered::, Without, Without)>() .iter(world) .collect(); let saveable_root_entities: Vec = world - .query_filtered::, With)>() - //.query_filtered::, Without, With)>() + // .query_filtered::, With)>() + .query_filtered::, Without, With)>() .iter(world) .collect(); @@ -97,7 +121,7 @@ pub(crate) fn save_game(world: &mut World) { let filter = config .save_component_filter .clone() - .allow::() + //.allow::() // TODO: add back .allow::() .allow::() .allow::() @@ -115,7 +139,6 @@ pub(crate) fn save_game(world: &mut World) { let filter_resources = config.clone() .save_resource_filter .deny::>() - .clone(); //.allow::(); @@ -150,22 +173,37 @@ pub(crate) fn save_game(world: &mut World) { .serialize(&world.resource::().read()) .expect("filtered scene should serialize correctly"); - let save_path = Path::new("assets") + let save_path_assets = Path::new("assets") //.join(&config.save_path) .join(Path::new(save_path.as_str())); // Path::new(&save_load_config.save_path).join(Path::new(save_path.as_str())); - info!("saving game to {:?}", save_path); + info!("saving game to {:?}", save_path_assets); // world.send_event(SavingFinished); + let bla = save_path_assets.clone().to_string_lossy().into_owned(); #[cfg(not(target_arch = "wasm32"))] IoTaskPool::get() .spawn(async move { // Write the scene RON data to file - File::create(save_path) + File::create(save_path_assets) .and_then(|mut file| file.write(serialized_scene.as_bytes())) .expect("Error while writing save to file"); }) .detach(); + + + let static_world_path = "levels/world.glb"; + let fake_foo = format!("(dynamic: {bla}, static: {static_world_path})"); + let real_save_path = format!("{bla}.save.ron"); + #[cfg(not(target_arch = "wasm32"))] + IoTaskPool::get() + .spawn(async move { + // Write the scene RON data to file + File::create(real_save_path) + .and_then(|mut file| file.write(fake_foo.as_bytes())) + .expect("Error while writing scene to file"); + }) + .detach(); } pub(crate) fn cleanup_save( @@ -178,4 +216,7 @@ pub(crate) fn cleanup_save( } // commands.remove_resource::(); saving_finished.send(SaveFinished); + + commands.remove_resource::(); + } \ No newline at end of file diff --git a/examples/save_load/Cargo.toml b/examples/save_load/Cargo.toml index 55570e6..e2a8f19 100644 --- a/examples/save_load/Cargo.toml +++ b/examples/save_load/Cargo.toml @@ -10,4 +10,9 @@ blenvy = { path = "../../crates/blenvy" } serde_json = "1.0.108" serde = "1.0.193" -rand = "0.8.5" \ No newline at end of file +rand = "0.8.5" + +bevy-inspector-egui = { version = "0.25.1"} + +[dev-dependencies] +bevy-inspector-egui = { version = "0.25.1"} \ No newline at end of file diff --git a/examples/save_load/art/save_load.blend b/examples/save_load/art/save_load.blend index bf68026..a662705 100644 Binary files a/examples/save_load/art/save_load.blend and b/examples/save_load/art/save_load.blend differ diff --git a/examples/save_load/assets/.save.ron b/examples/save_load/assets/.save.ron new file mode 100644 index 0000000..950b750 --- /dev/null +++ b/examples/save_load/assets/.save.ron @@ -0,0 +1 @@ +(dynamic: assets/, static: levels/world.glb) \ No newline at end of file diff --git a/examples/save_load/assets/blueprints/Dynamic_hierarchy.glb b/examples/save_load/assets/blueprints/Dynamic_hierarchy.glb new file mode 100644 index 0000000..f9dc7f1 Binary files /dev/null and b/examples/save_load/assets/blueprints/Dynamic_hierarchy.glb differ diff --git a/examples/save_load/assets/blueprints/Dynamic_hierarchy.meta.ron b/examples/save_load/assets/blueprints/Dynamic_hierarchy.meta.ron new file mode 100644 index 0000000..5097f2f --- /dev/null +++ b/examples/save_load/assets/blueprints/Dynamic_hierarchy.meta.ron @@ -0,0 +1,5 @@ +( + assets: + [ + ] +) \ No newline at end of file diff --git a/examples/save_load/assets/blueprints/Dynamic_inside_static.glb b/examples/save_load/assets/blueprints/Dynamic_inside_static.glb new file mode 100644 index 0000000..925b65f Binary files /dev/null and b/examples/save_load/assets/blueprints/Dynamic_inside_static.glb differ diff --git a/examples/save_load/assets/blueprints/Dynamic_inside_static.meta.ron b/examples/save_load/assets/blueprints/Dynamic_inside_static.meta.ron new file mode 100644 index 0000000..e660f80 --- /dev/null +++ b/examples/save_load/assets/blueprints/Dynamic_inside_static.meta.ron @@ -0,0 +1,7 @@ +( + assets: + [ + ("Mover", File ( path: "blueprints/Mover.glb" )), + ("Material.001", File ( path: "materials/Material.001.glb" )), + ] +) \ No newline at end of file diff --git a/examples/save_load/assets/blueprints/Mover.glb b/examples/save_load/assets/blueprints/Mover.glb index c0c4122..c0169f0 100644 Binary files a/examples/save_load/assets/blueprints/Mover.glb and b/examples/save_load/assets/blueprints/Mover.glb differ diff --git a/examples/save_load/assets/blueprints/Pillar.glb b/examples/save_load/assets/blueprints/Pillar.glb index 389fa88..6135058 100644 Binary files a/examples/save_load/assets/blueprints/Pillar.glb and b/examples/save_load/assets/blueprints/Pillar.glb differ diff --git a/examples/save_load/assets/levels/World.glb b/examples/save_load/assets/levels/World.glb index c7bfe66..67d84ca 100644 Binary files a/examples/save_load/assets/levels/World.glb and b/examples/save_load/assets/levels/World.glb differ diff --git a/examples/save_load/assets/levels/World.meta.ron b/examples/save_load/assets/levels/World.meta.ron index f8e8da4..d8c30be 100644 --- a/examples/save_load/assets/levels/World.meta.ron +++ b/examples/save_load/assets/levels/World.meta.ron @@ -5,5 +5,9 @@ ("Stone", File ( path: "materials/Stone.glb" )), ("Mover", File ( path: "blueprints/Mover.glb" )), ("Material.001", File ( path: "materials/Material.001.glb" )), + ("Dynamic_hierarchy", File ( path: "blueprints/Dynamic_hierarchy.glb" )), + ("Dynamic_inside_static", File ( path: "blueprints/Dynamic_inside_static.glb" )), + ("Mover", File ( path: "blueprints/Mover.glb" )), + ("Material.001", File ( path: "materials/Material.001.glb" )), ] ) \ No newline at end of file diff --git a/examples/save_load/assets/levels/World_dynamic.glb b/examples/save_load/assets/levels/World_dynamic.glb index 350ac4b..e52b007 100644 Binary files a/examples/save_load/assets/levels/World_dynamic.glb and b/examples/save_load/assets/levels/World_dynamic.glb differ diff --git a/examples/save_load/assets/materials/Dots Stroke.glb b/examples/save_load/assets/materials/Dots Stroke.glb new file mode 100644 index 0000000..8d21a66 Binary files /dev/null and b/examples/save_load/assets/materials/Dots Stroke.glb differ diff --git a/examples/save_load/assets/materials/Material.001.glb b/examples/save_load/assets/materials/Material.001.glb new file mode 100644 index 0000000..7f24e7d Binary files /dev/null and b/examples/save_load/assets/materials/Material.001.glb differ diff --git a/examples/save_load/assets/materials/Stone.glb b/examples/save_load/assets/materials/Stone.glb new file mode 100644 index 0000000..702d12e Binary files /dev/null and b/examples/save_load/assets/materials/Stone.glb differ diff --git a/examples/save_load/assets/registry.json b/examples/save_load/assets/registry.json index f4d15a3..037310d 100644 --- a/examples/save_load/assets/registry.json +++ b/examples/save_load/assets/registry.json @@ -3609,6 +3609,30 @@ "type": "object", "typeInfo": "Value" }, + "bevy_egui::EguiSettings": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "bevy_egui::EguiSettings", + "properties": { + "default_open_url_target": { + "type": { + "$ref": "#/$defs/core::option::Option" + } + }, + "scale_factor": { + "type": { + "$ref": "#/$defs/f32" + } + } + }, + "required": [ + "scale_factor" + ], + "short_name": "EguiSettings", + "type": "object", + "typeInfo": "Struct" + }, "bevy_gizmos::aabb::AabbGizmoConfigGroup": { "additionalProperties": false, "isComponent": false, @@ -12947,6 +12971,14 @@ "type": "object", "typeInfo": "Value" }, + "core::ops::Range": { + "isComponent": false, + "isResource": false, + "long_name": "core::ops::Range", + "short_name": "Range", + "type": "object", + "typeInfo": "Value" + }, "core::option::Option<(u8, u8)>": { "isComponent": false, "isResource": false, @@ -13661,6 +13693,295 @@ "type": "object", "typeInfo": "Struct" }, + "glam::BVec2": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::BVec2", + "properties": { + "x": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "y": { + "type": { + "$ref": "#/$defs/bool" + } + } + }, + "required": [ + "x", + "y" + ], + "short_name": "BVec2", + "type": "object", + "typeInfo": "Struct" + }, + "glam::BVec3": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::BVec3", + "properties": { + "x": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "y": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "z": { + "type": { + "$ref": "#/$defs/bool" + } + } + }, + "required": [ + "x", + "y", + "z" + ], + "short_name": "BVec3", + "type": "object", + "typeInfo": "Struct" + }, + "glam::BVec3A": { + "isComponent": false, + "isResource": false, + "long_name": "glam::BVec3A", + "short_name": "BVec3A", + "type": "object", + "typeInfo": "Value" + }, + "glam::BVec4": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::BVec4", + "properties": { + "w": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "x": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "y": { + "type": { + "$ref": "#/$defs/bool" + } + }, + "z": { + "type": { + "$ref": "#/$defs/bool" + } + } + }, + "required": [ + "x", + "y", + "z", + "w" + ], + "short_name": "BVec4", + "type": "object", + "typeInfo": "Struct" + }, + "glam::BVec4A": { + "isComponent": false, + "isResource": false, + "long_name": "glam::BVec4A", + "short_name": "BVec4A", + "type": "object", + "typeInfo": "Value" + }, + "glam::DAffine2": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DAffine2", + "properties": { + "matrix2": { + "type": { + "$ref": "#/$defs/glam::DMat2" + } + }, + "translation": { + "type": { + "$ref": "#/$defs/glam::DVec2" + } + } + }, + "required": [ + "matrix2", + "translation" + ], + "short_name": "DAffine2", + "type": "object", + "typeInfo": "Struct" + }, + "glam::DAffine3": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DAffine3", + "properties": { + "matrix3": { + "type": { + "$ref": "#/$defs/glam::DMat3" + } + }, + "translation": { + "type": { + "$ref": "#/$defs/glam::DVec3" + } + } + }, + "required": [ + "matrix3", + "translation" + ], + "short_name": "DAffine3", + "type": "object", + "typeInfo": "Struct" + }, + "glam::DMat2": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DMat2", + "properties": { + "x_axis": { + "type": { + "$ref": "#/$defs/glam::DVec2" + } + }, + "y_axis": { + "type": { + "$ref": "#/$defs/glam::DVec2" + } + } + }, + "required": [ + "x_axis", + "y_axis" + ], + "short_name": "DMat2", + "type": "object", + "typeInfo": "Struct" + }, + "glam::DMat3": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DMat3", + "properties": { + "x_axis": { + "type": { + "$ref": "#/$defs/glam::DVec3" + } + }, + "y_axis": { + "type": { + "$ref": "#/$defs/glam::DVec3" + } + }, + "z_axis": { + "type": { + "$ref": "#/$defs/glam::DVec3" + } + } + }, + "required": [ + "x_axis", + "y_axis", + "z_axis" + ], + "short_name": "DMat3", + "type": "object", + "typeInfo": "Struct" + }, + "glam::DMat4": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DMat4", + "properties": { + "w_axis": { + "type": { + "$ref": "#/$defs/glam::DVec4" + } + }, + "x_axis": { + "type": { + "$ref": "#/$defs/glam::DVec4" + } + }, + "y_axis": { + "type": { + "$ref": "#/$defs/glam::DVec4" + } + }, + "z_axis": { + "type": { + "$ref": "#/$defs/glam::DVec4" + } + } + }, + "required": [ + "x_axis", + "y_axis", + "z_axis", + "w_axis" + ], + "short_name": "DMat4", + "type": "object", + "typeInfo": "Struct" + }, + "glam::DQuat": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DQuat", + "properties": { + "w": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "x": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "y": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "z": { + "type": { + "$ref": "#/$defs/f64" + } + } + }, + "required": [ + "x", + "y", + "z", + "w" + ], + "short_name": "DQuat", + "type": "object", + "typeInfo": "Struct" + }, "glam::DVec2": { "additionalProperties": false, "isComponent": false, @@ -13686,6 +14007,74 @@ "type": "object", "typeInfo": "Struct" }, + "glam::DVec3": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DVec3", + "properties": { + "x": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "y": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "z": { + "type": { + "$ref": "#/$defs/f64" + } + } + }, + "required": [ + "x", + "y", + "z" + ], + "short_name": "DVec3", + "type": "object", + "typeInfo": "Struct" + }, + "glam::DVec4": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::DVec4", + "properties": { + "w": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "x": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "y": { + "type": { + "$ref": "#/$defs/f64" + } + }, + "z": { + "type": { + "$ref": "#/$defs/f64" + } + } + }, + "required": [ + "x", + "y", + "z", + "w" + ], + "short_name": "DVec4", + "type": "object", + "typeInfo": "Struct" + }, "glam::IVec2": { "additionalProperties": false, "isComponent": false, @@ -13711,6 +14100,74 @@ "type": "object", "typeInfo": "Struct" }, + "glam::IVec3": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::IVec3", + "properties": { + "x": { + "type": { + "$ref": "#/$defs/i32" + } + }, + "y": { + "type": { + "$ref": "#/$defs/i32" + } + }, + "z": { + "type": { + "$ref": "#/$defs/i32" + } + } + }, + "required": [ + "x", + "y", + "z" + ], + "short_name": "IVec3", + "type": "object", + "typeInfo": "Struct" + }, + "glam::IVec4": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::IVec4", + "properties": { + "w": { + "type": { + "$ref": "#/$defs/i32" + } + }, + "x": { + "type": { + "$ref": "#/$defs/i32" + } + }, + "y": { + "type": { + "$ref": "#/$defs/i32" + } + }, + "z": { + "type": { + "$ref": "#/$defs/i32" + } + } + }, + "required": [ + "x", + "y", + "z", + "w" + ], + "short_name": "IVec4", + "type": "object", + "typeInfo": "Struct" + }, "glam::Mat2": { "additionalProperties": false, "isComponent": false, @@ -13736,6 +14193,37 @@ "type": "object", "typeInfo": "Struct" }, + "glam::Mat3": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::Mat3", + "properties": { + "x_axis": { + "type": { + "$ref": "#/$defs/glam::Vec3" + } + }, + "y_axis": { + "type": { + "$ref": "#/$defs/glam::Vec3" + } + }, + "z_axis": { + "type": { + "$ref": "#/$defs/glam::Vec3" + } + } + }, + "required": [ + "x_axis", + "y_axis", + "z_axis" + ], + "short_name": "Mat3", + "type": "object", + "typeInfo": "Struct" + }, "glam::Mat3A": { "additionalProperties": false, "isComponent": false, @@ -13897,6 +14385,43 @@ "type": "object", "typeInfo": "Struct" }, + "glam::UVec4": { + "additionalProperties": false, + "isComponent": false, + "isResource": false, + "long_name": "glam::UVec4", + "properties": { + "w": { + "type": { + "$ref": "#/$defs/u32" + } + }, + "x": { + "type": { + "$ref": "#/$defs/u32" + } + }, + "y": { + "type": { + "$ref": "#/$defs/u32" + } + }, + "z": { + "type": { + "$ref": "#/$defs/u32" + } + } + }, + "required": [ + "x", + "y", + "z", + "w" + ], + "short_name": "UVec4", + "type": "object", + "typeInfo": "Struct" + }, "glam::Vec2": { "additionalProperties": false, "isComponent": false, diff --git a/examples/save_load/assets/scenes/save.scn.ron b/examples/save_load/assets/scenes/save.scn.ron index 3f0b257..b50b1c5 100644 --- a/examples/save_load/assets/scenes/save.scn.ron +++ b/examples/save_load/assets/scenes/save.scn.ron @@ -8,22 +8,22 @@ ), delta: ( secs: 0, - nanos: 19854342, + nanos: 20094396, ), - delta_seconds: 0.019854343, - delta_seconds_f64: 0.019854342, + delta_seconds: 0.020094397, + delta_seconds_f64: 0.020094396, elapsed: ( - secs: 0, - nanos: 579651002, + secs: 1, + nanos: 493224348, ), - elapsed_seconds: 0.579651, - elapsed_seconds_f64: 0.579651002, + elapsed_seconds: 1.4932244, + elapsed_seconds_f64: 1.493224348, elapsed_wrapped: ( - secs: 0, - nanos: 579651002, + secs: 1, + nanos: 493224348, ), - elapsed_seconds_wrapped: 0.579651, - elapsed_seconds_wrapped_f64: 0.579651002, + elapsed_seconds_wrapped: 1.4932244, + elapsed_seconds_wrapped_f64: 1.493224348, ), "bevy_time::time::Time": ( context: ( @@ -41,22 +41,22 @@ ), delta: ( secs: 0, - nanos: 19854342, + nanos: 20094396, ), - delta_seconds: 0.019854343, - delta_seconds_f64: 0.019854342, + delta_seconds: 0.020094397, + delta_seconds_f64: 0.020094396, elapsed: ( - secs: 0, - nanos: 579651002, + secs: 1, + nanos: 493224348, ), - elapsed_seconds: 0.579651, - elapsed_seconds_f64: 0.579651002, + elapsed_seconds: 1.4932244, + elapsed_seconds_f64: 1.493224348, elapsed_wrapped: ( - secs: 0, - nanos: 579651002, + secs: 1, + nanos: 493224348, ), - elapsed_seconds_wrapped: 0.579651, - elapsed_seconds_wrapped_f64: 0.579651002, + elapsed_seconds_wrapped: 1.4932244, + elapsed_seconds_wrapped_f64: 1.493224348, ), "bevy_time::time::Time": ( context: ( @@ -66,7 +66,7 @@ ), overstep: ( secs: 0, - nanos: 1526002, + nanos: 8849348, ), ), wrap_period: ( @@ -80,17 +80,17 @@ delta_seconds: 0.015625, delta_seconds_f64: 0.015625, elapsed: ( - secs: 0, - nanos: 578125000, + secs: 1, + nanos: 484375000, ), - elapsed_seconds: 0.578125, - elapsed_seconds_f64: 0.578125, + elapsed_seconds: 1.484375, + elapsed_seconds_f64: 1.484375, elapsed_wrapped: ( - secs: 0, - nanos: 578125000, + secs: 1, + nanos: 484375000, ), - elapsed_seconds_wrapped: 0.578125, - elapsed_seconds_wrapped_f64: 0.578125, + elapsed_seconds_wrapped: 1.484375, + elapsed_seconds_wrapped_f64: 1.484375, ), "bevy_render::camera::clear_color::ClearColor": (Srgba(( red: 0.16862746, @@ -125,16 +125,68 @@ "bevy_gizmos::config::GizmoConfigStore": (), }, entities: { - 4294967309: ( + 4294967311: ( components: { - "blenvy::blueprints::spawn_from_blueprints::BlueprintInfo": ( - name: "Mover", - path: "blueprints/Mover.glb", - ), - "blenvy::blueprints::spawn_from_blueprints::SpawnBlueprint": (), "bevy_transform::components::transform::Transform": ( translation: ( - x: 0.19871584, + x: -2.217765, + y: 1.2997229, + z: 2.3971958, + ), + rotation: ( + x: 0.10570976, + y: 0.038342018, + z: 0.09289465, + w: 0.9893058, + ), + scale: ( + x: 0.53947395, + y: 0.53947395, + z: 0.5394739, + ), + ), + "bevy_transform::components::global_transform::GlobalTransform": (( + matrix3: ( + x_axis: ( + x: 0.5285771, + y: 0.10352973, + z: -0.030331498, + ), + y_axis: ( + x: -0.094783515, + y: 0.5181065, + z: 0.11667855, + ), + z_axis: ( + x: 0.051521756, + y: -0.10899262, + z: 0.5258309, + ), + ), + translation: ( + x: -2.2227652, + y: 1.2997229, + z: 2.3971958, + ), + )), + "blenvy::blueprints::spawn_from_blueprints::BlueprintInfo": ( + name: "Dynamic_hierarchy", + path: "blueprints/Dynamic_hierarchy.glb", + ), + "bevy_core::name::Name": ( + hash: 1803003925387469959, + name: "Dynamic_hierarchy", + ), + "blenvy::save_load::Dynamic": (), + "blenvy::blueprints::spawn_from_blueprints::SpawnBlueprint": (), + "bevy_render::view::visibility::InheritedVisibility": (true), + }, + ), + 4294967312: ( + components: { + "bevy_transform::components::transform::Transform": ( + translation: ( + x: 0.2887157, y: 1.19514, z: -0.7909124, ), @@ -169,17 +221,78 @@ ), ), translation: ( - x: 0.18871583, + x: 0.2837157, y: 1.19514, z: -0.7909124, ), )), - "bevy_hierarchy::components::parent::Parent": (21474836492), + "blenvy::blueprints::spawn_from_blueprints::BlueprintInfo": ( + name: "Mover", + path: "blueprints/Mover.glb", + ), "bevy_core::name::Name": ( - hash: 10742641839607126956, + hash: 3988719516189002069, name: "Mover", ), "blenvy::save_load::Dynamic": (), + "blenvy::blueprints::spawn_from_blueprints::SpawnBlueprint": (), + "bevy_render::view::visibility::InheritedVisibility": (true), + }, + ), + 21474836498: ( + components: { + "bevy_transform::components::transform::Transform": ( + translation: ( + x: 1.6942285, + y: 0.50783855, + z: -2.0131574, + ), + rotation: ( + x: 0.0, + y: 0.0, + z: 0.0, + w: 1.0, + ), + scale: ( + x: 1.0, + y: 1.0, + z: 1.0, + ), + ), + "bevy_transform::components::global_transform::GlobalTransform": (( + matrix3: ( + x_axis: ( + x: 0.6095814, + y: 0.1066819, + z: -0.10043551, + ), + y_axis: ( + x: -0.08811652, + y: 0.6102711, + z: 0.113412924, + ), + z_axis: ( + x: 0.11706323, + y: -0.096156046, + z: 0.60836506, + ), + ), + translation: ( + x: -1.6649909, + y: 1.184185, + z: 2.0619445, + ), + )), + "blenvy::blueprints::spawn_from_blueprints::BlueprintInfo": ( + name: "Mover", + path: "blueprints/Mover.glb", + ), + "bevy_core::name::Name": ( + hash: 14976337147749212273, + name: "Mover.001", + ), + "blenvy::save_load::Dynamic": (), + "blenvy::blueprints::spawn_from_blueprints::SpawnBlueprint": (), "bevy_render::view::visibility::InheritedVisibility": (true), }, ), diff --git a/examples/save_load/assets/scenes/save.scn.ron.save.ron b/examples/save_load/assets/scenes/save.scn.ron.save.ron new file mode 100644 index 0000000..3636658 --- /dev/null +++ b/examples/save_load/assets/scenes/save.scn.ron.save.ron @@ -0,0 +1 @@ +(dynamic: assets/scenes/save.scn.ron, static: levels/world.glb) \ No newline at end of file diff --git a/examples/save_load/src/game/mod.rs b/examples/save_load/src/game/mod.rs index e9cdf01..55cad51 100644 --- a/examples/save_load/src/game/mod.rs +++ b/examples/save_load/src/game/mod.rs @@ -12,10 +12,10 @@ pub mod in_game_saving; pub use in_game_saving::*; use bevy::prelude::*; -use blenvy::{LoadRequest, LoadingFinished, SaveRequest, SavingFinished}; +use blenvy::{LoadRequest, LoadingFinished, SavingRequest, SavingFinished}; pub fn request_save( - mut save_requests: EventWriter, + mut save_requests: EventWriter, keycode: Res>, current_state: Res>, @@ -26,7 +26,7 @@ pub fn request_save( && (current_state.get() != &GameState::InSaving) { next_game_state.set(GameState::InSaving); - save_requests.send(SaveRequest { + save_requests.send(SavingRequest { path: "save.scn.ron".into(), }); } diff --git a/examples/save_load/src/main.rs b/examples/save_load/src/main.rs index 3b5db72..48918a8 100644 --- a/examples/save_load/src/main.rs +++ b/examples/save_load/src/main.rs @@ -1,7 +1,7 @@ use std::any::TypeId; use bevy::{prelude::*, utils::hashbrown::HashSet}; -use blenvy::{AddToGameWorld, BlenvyPlugin, BluePrintBundle, BlueprintInfo, Dynamic, DynamicBlueprintInstance, GameWorldTag, HideUntilReady, SaveRequest, SpawnBlueprint}; +use blenvy::{AddToGameWorld, BlenvyPlugin, BlueprintInfo, BlueprintWorld, Dynamic, DynamicBlueprintInstance, GameWorldTag, HideUntilReady, LoadingRequest, SavingRequest, SpawnBlueprint}; use rand::Rng; // mod game; @@ -9,11 +9,13 @@ use rand::Rng; mod component_examples; use component_examples::*; +use bevy_inspector_egui::quick::WorldInspectorPlugin; fn main() { App::new() .add_plugins(( DefaultPlugins.set(AssetPlugin::default()), + WorldInspectorPlugin::new(), BlenvyPlugin { save_component_filter: SceneFilter::Allowlist(HashSet::from([ TypeId::of::(), @@ -49,19 +51,10 @@ fn setup_game( mut commands: Commands, ) { - // here we spawn our game world/level, which is also a blueprint ! + + // would be nice: contains both static & dynamic stuff commands.spawn(( - BlueprintInfo::from_path("levels/World.glb"), // all we need is a Blueprint info... - SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now - HideUntilReady, // only reveal the level once it is ready - GameWorldTag, - )); - - // here we spawn our game world/level, which is also a blueprint ! - commands.spawn(( - BlueprintInfo::from_path("levels/World_dynamic.glb"), // all we need is a Blueprint info... - SpawnBlueprint, // and spawnblueprint to tell blenvy to spawn the blueprint now - HideUntilReady, // only reveal the level once it is ready + BlueprintWorld::from_path("levels/World.glb"), // will take care of loading both static & dynamic data )); } @@ -97,47 +90,30 @@ fn move_movers( mut movers: Query<(&mut Transform), With> ) { for mut transform in movers.iter_mut(){ - println!("moving dynamic entity"); - transform.translation.x += 0.01; + // println!("moving dynamic entity"); + transform.translation.x += 0.005; } } fn save_game( keycode: Res>, - mut save_requests: EventWriter, + mut save_requests: EventWriter, ) { if keycode.just_pressed(KeyCode::KeyS) { - save_requests.send(SaveRequest { + save_requests.send(SavingRequest { path: "scenes/save.scn.ron".into(), }); } } -/* -pub fn request_save( - mut save_requests: EventWriter, - keycode: Res>, - - current_state: Res>, - mut next_game_state: ResMut>, -) { - if keycode.just_pressed(KeyCode::KeyS) - && (current_state.get() != &GameState::InLoading) - && (current_state.get() != &GameState::InSaving) - { - next_game_state.set(GameState::InSaving); - save_requests.send(SaveRequest { - path: "save.scn.ron".into(), - }); - } -}*/ - - fn load_game( keycode: Res>, + mut load_requests: EventWriter, ) { if keycode.just_pressed(KeyCode::KeyL) { - + load_requests.send(LoadingRequest { + path: "scenes/save.scn.ron".into(), + }); } } diff --git a/testing/bevy_example/Cargo.toml b/testing/bevy_example/Cargo.toml index 90b258c..9614ad8 100644 --- a/testing/bevy_example/Cargo.toml +++ b/testing/bevy_example/Cargo.toml @@ -9,4 +9,7 @@ bevy = { version = "0.14", features = ["dynamic_linking"] } blenvy = { path = "../../crates/blenvy" } #bevy_editor_pls = { version = "0.8" } rand = "0.8.5" -json-writer ="0.3" \ No newline at end of file +json-writer ="0.3" + +[dev-dependencies] +bevy-inspector-egui = { version = "0.25.1"} \ No newline at end of file