diff --git a/src/main.rs b/src/main.rs index ffd36ae..20425ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ fn main() { exit_condition: bevy::window::ExitCondition::OnPrimaryClosed, ..default() })) - // .add_plugins(camera::CameraPlugin) + .add_plugins(camera::CameraPlugin) // .add_plugins(editor::EditorPlugin) // .add_plugins(menu::MenuPlugin) // .add_plugins(window::WindowPlugin) diff --git a/src/save.rs b/src/save.rs index 1eb9b34..0e22176 100644 --- a/src/save.rs +++ b/src/save.rs @@ -13,8 +13,23 @@ impl Plugin for SavePlugin { .init_asset::() .init_asset_loader::() .add_systems(Startup, load_scenes) - .add_systems(Update, spawn_scenes.run_if(on_event::>())) - .add_systems(Update, spawn_entities.run_if(any_component_added::>)); + .add_systems( + Update, + spawn_scenes.run_if(on_event::>()), + ) + .add_systems( + Update, + sync_entities + .run_if(on_event::>()) + .after(spawn_scenes), + ) + .add_systems( + Update, + spawn_entities + .run_if(any_component_added::>) + .after(sync_entities), + ) + .add_systems(Update, debug_entities); } } @@ -148,7 +163,6 @@ impl AssetLoader for SaveSceneLoader { .map(|line| parent_dir.join(line)) .map(|path| load_context.load(path)) .collect(); - info!("Entities: {:?}", entities); Ok(SaveScene { entities }) } @@ -170,22 +184,26 @@ fn spawn_scenes( query: Query<(Entity, &Handle)>, mut events: EventReader>, save_scenes: Res>, + server: Res, mut commands: Commands, ) { events.read().for_each(|event| { if let AssetEvent::LoadedWithDependencies { id } = event { + debug!("Spawning scene {:?}", server.get_id_handle(*id).unwrap()); query .iter() .filter(|(_, handle)| handle.id() == *id) .for_each(|(entity, handle)| { - debug!("Spawning scene {:?} on {:?}", handle, entity); - let scene = save_scenes.get(handle).unwrap(); // Get entity with SaveEntity handle let mut e = commands.entity(entity); + // Clear the entity of descendants + debug!("Despawning scene descendants"); e.despawn_descendants(); + + debug!("Populating children in scene"); // Populate with entities e.with_children(|parent| { scene.entities.iter().for_each(|this| { @@ -199,22 +217,74 @@ fn spawn_scenes( /// Spawns entities with the Handle component fn spawn_entities( - events: Query<(Entity, &Handle), Added>>, + events: Query< + (Entity, &Handle), + Or<(Added>, Changed>)>, + >, save_entities: Res>, mut commands: Commands, ) { events.iter().for_each(|(entity, handle)| { - debug!("Spawning entity {:?} {:?}", entity, handle); - // Get a handle on the let mut e = commands.entity(entity); + debug!("Despawning entity descendants {:?}", entity); + e.despawn_descendants(); + + debug!("Clearing components on entity {:?}", entity); + // Clear any existing components on the entity; + e.retain::>(); + // Get the entity asset containing reflected component let save_entity = save_entities.get(handle).unwrap(); // Add each component to the entity + debug!("Populating entity with components {:?}", entity); save_entity.components.iter().for_each(|component| { e.insert_reflect(component.clone_value()); }); }); } + +/// When an entity asset is updated, re-spawn it +/// NOTE: This should only be enabled in development mode(?) +fn sync_entities( + query: Query<(Entity, &Handle)>, + server: Res, + mut events: EventReader>, + mut commands: Commands, +) { + // Any time a SaveEntity asset is updated + events.read().for_each(|event| { + match event { + AssetEvent::LoadedWithDependencies { id } => { + debug!( + "SaveEnity loaded {:?}", + server.get_id_handle(*id).unwrap().path().unwrap() + ); + // Find any entities with this Handle + for (entity, handle) in query.iter() { + if handle.id() == *id { + debug!("Found entity with same ID, updating"); + + // Get this entity with SaveEntity handle + let mut e = commands.entity(entity); + + // Re-Insert the SaveEntity handle + e.remove::>().insert(handle.clone()); + } + } + } + _ => debug!("Skipping SaveEntity event {:?}", event), + } + }) +} + +fn debug_entities( + events: Query>, Added>)>>, + mut commands: Commands, +) { + events.iter().for_each(|e| { + commands.entity(e).log_components(); + }); +}