|
|
|
@ -1,12 +1,7 @@
|
|
|
|
use crate::prelude::*;
|
|
|
|
use crate::prelude::*;
|
|
|
|
|
|
|
|
|
|
|
|
type ParseFn =
|
|
|
|
/// Menu Plugin; empty struct for Plugin impl
|
|
|
|
for<'a> fn(&'a Vec<Token>) -> Result<Box<(dyn Reflect + 'static)>, SaveEntityParseError>;
|
|
|
|
pub(crate) struct SavePlugin;
|
|
|
|
|
|
|
|
|
|
|
|
/// Menu Plugin; contains parser functions
|
|
|
|
|
|
|
|
pub(crate) struct SavePlugin {
|
|
|
|
|
|
|
|
pub fns: Vec<ParseFn>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Plugin for SavePlugin {
|
|
|
|
impl Plugin for SavePlugin {
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
@ -14,29 +9,12 @@ impl Plugin for SavePlugin {
|
|
|
|
.register_type::<GltfScene>()
|
|
|
|
.register_type::<GltfScene>()
|
|
|
|
.register_type::<SaveModel>()
|
|
|
|
.register_type::<SaveModel>()
|
|
|
|
.init_asset::<SaveEntity>()
|
|
|
|
.init_asset::<SaveEntity>()
|
|
|
|
.register_asset_loader(SaveEntityLoader {
|
|
|
|
.init_asset_loader::<SaveEntityLoader>()
|
|
|
|
fns: self.fns.clone(),
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.init_asset::<SaveScene>()
|
|
|
|
.init_asset::<SaveScene>()
|
|
|
|
.init_asset_loader::<SaveSceneLoader>()
|
|
|
|
.init_asset_loader::<SaveSceneLoader>()
|
|
|
|
.add_systems(Startup, load_scenes)
|
|
|
|
.add_systems(Startup, load_scenes)
|
|
|
|
.add_systems(
|
|
|
|
.add_systems(Update, spawn_scenes.run_if(on_event::<AssetEvent<SaveEntity>>()))
|
|
|
|
Update,
|
|
|
|
.add_systems(Update, spawn_entities.run_if(any_component_added::<Handle<SaveEntity>>));
|
|
|
|
spawn_scenes.run_if(on_event::<AssetEvent<SaveScene>>()),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.add_systems(
|
|
|
|
|
|
|
|
Update,
|
|
|
|
|
|
|
|
sync_entities
|
|
|
|
|
|
|
|
.run_if(on_event::<AssetEvent<SaveEntity>>())
|
|
|
|
|
|
|
|
.after(spawn_scenes),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.add_systems(
|
|
|
|
|
|
|
|
Update,
|
|
|
|
|
|
|
|
spawn_entities
|
|
|
|
|
|
|
|
.run_if(any_component_added::<Handle<SaveEntity>>)
|
|
|
|
|
|
|
|
.after(sync_entities),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.add_systems(Update, debug_entities);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -58,10 +36,20 @@ impl SaveEntity {
|
|
|
|
fn parse(
|
|
|
|
fn parse(
|
|
|
|
text: &str,
|
|
|
|
text: &str,
|
|
|
|
load_context: &mut LoadContext,
|
|
|
|
load_context: &mut LoadContext,
|
|
|
|
fns: &Vec<ParseFn>,
|
|
|
|
|
|
|
|
) -> Result<SaveEntity, SaveEntityParseError> {
|
|
|
|
) -> Result<SaveEntity, SaveEntityParseError> {
|
|
|
|
let lines = text.split('\n');
|
|
|
|
let lines = text.split('\n');
|
|
|
|
let mut entity = SaveEntity { ..default() };
|
|
|
|
let mut entity = SaveEntity { ..default() };
|
|
|
|
|
|
|
|
let fns = [
|
|
|
|
|
|
|
|
parse_save_name,
|
|
|
|
|
|
|
|
// parse_save_transform,
|
|
|
|
|
|
|
|
// parse_save_model,
|
|
|
|
|
|
|
|
// parse_save_camera,
|
|
|
|
|
|
|
|
// parse_save_parent,
|
|
|
|
|
|
|
|
// parse_save_window,
|
|
|
|
|
|
|
|
// parse_save_target_camera,
|
|
|
|
|
|
|
|
// parse_save_ui_text,
|
|
|
|
|
|
|
|
// parse_save_tag::<EditorTag>("editor_tag"),
|
|
|
|
|
|
|
|
];
|
|
|
|
lines
|
|
|
|
lines
|
|
|
|
.into_iter()
|
|
|
|
.into_iter()
|
|
|
|
.filter(|line| !line.is_empty())
|
|
|
|
.filter(|line| !line.is_empty())
|
|
|
|
@ -100,9 +88,7 @@ struct GltfScene {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
#[derive(Default)]
|
|
|
|
struct SaveEntityLoader {
|
|
|
|
struct SaveEntityLoader;
|
|
|
|
fns: Vec<ParseFn>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
#[derive(Error, Debug)]
|
|
|
|
enum SaveEntityLoaderError {
|
|
|
|
enum SaveEntityLoaderError {
|
|
|
|
@ -127,7 +113,7 @@ impl AssetLoader for SaveEntityLoader {
|
|
|
|
reader.read_to_end(&mut bytes).await?;
|
|
|
|
reader.read_to_end(&mut bytes).await?;
|
|
|
|
|
|
|
|
|
|
|
|
let s = std::str::from_utf8(bytes.as_slice()).unwrap();
|
|
|
|
let s = std::str::from_utf8(bytes.as_slice()).unwrap();
|
|
|
|
let save_entity = SaveEntity::parse(s, load_context, &self.fns)?;
|
|
|
|
let save_entity = SaveEntity::parse(s, load_context)?;
|
|
|
|
Ok(save_entity)
|
|
|
|
Ok(save_entity)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -162,6 +148,7 @@ impl AssetLoader for SaveSceneLoader {
|
|
|
|
.map(|line| parent_dir.join(line))
|
|
|
|
.map(|line| parent_dir.join(line))
|
|
|
|
.map(|path| load_context.load(path))
|
|
|
|
.map(|path| load_context.load(path))
|
|
|
|
.collect();
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
info!("Entities: {:?}", entities);
|
|
|
|
|
|
|
|
|
|
|
|
Ok(SaveScene { entities })
|
|
|
|
Ok(SaveScene { entities })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -183,26 +170,22 @@ fn spawn_scenes(
|
|
|
|
query: Query<(Entity, &Handle<SaveScene>)>,
|
|
|
|
query: Query<(Entity, &Handle<SaveScene>)>,
|
|
|
|
mut events: EventReader<AssetEvent<SaveScene>>,
|
|
|
|
mut events: EventReader<AssetEvent<SaveScene>>,
|
|
|
|
save_scenes: Res<Assets<SaveScene>>,
|
|
|
|
save_scenes: Res<Assets<SaveScene>>,
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
|
|
|
|
mut commands: Commands,
|
|
|
|
mut commands: Commands,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
events.read().for_each(|event| {
|
|
|
|
events.read().for_each(|event| {
|
|
|
|
if let AssetEvent::LoadedWithDependencies { id } = event {
|
|
|
|
if let AssetEvent::LoadedWithDependencies { id } = event {
|
|
|
|
debug!("Spawning scene {:?}", server.get_id_handle(*id).unwrap());
|
|
|
|
|
|
|
|
query
|
|
|
|
query
|
|
|
|
.iter()
|
|
|
|
.iter()
|
|
|
|
.filter(|(_, handle)| handle.id() == *id)
|
|
|
|
.filter(|(_, handle)| handle.id() == *id)
|
|
|
|
.for_each(|(entity, handle)| {
|
|
|
|
.for_each(|(entity, handle)| {
|
|
|
|
|
|
|
|
debug!("Spawning scene {:?} on {:?}", handle, entity);
|
|
|
|
|
|
|
|
|
|
|
|
let scene = save_scenes.get(handle).unwrap();
|
|
|
|
let scene = save_scenes.get(handle).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
// Get entity with SaveEntity handle
|
|
|
|
// Get entity with SaveEntity handle
|
|
|
|
let mut e = commands.entity(entity);
|
|
|
|
let mut e = commands.entity(entity);
|
|
|
|
|
|
|
|
|
|
|
|
// Clear the entity of descendants
|
|
|
|
// Clear the entity of descendants
|
|
|
|
debug!("Despawning scene descendants");
|
|
|
|
|
|
|
|
e.despawn_descendants();
|
|
|
|
e.despawn_descendants();
|
|
|
|
|
|
|
|
|
|
|
|
debug!("Populating children in scene");
|
|
|
|
|
|
|
|
// Populate with entities
|
|
|
|
// Populate with entities
|
|
|
|
e.with_children(|parent| {
|
|
|
|
e.with_children(|parent| {
|
|
|
|
scene.entities.iter().for_each(|this| {
|
|
|
|
scene.entities.iter().for_each(|this| {
|
|
|
|
@ -216,75 +199,22 @@ fn spawn_scenes(
|
|
|
|
|
|
|
|
|
|
|
|
/// Spawns entities with the Handle<SaveEntity> component
|
|
|
|
/// Spawns entities with the Handle<SaveEntity> component
|
|
|
|
fn spawn_entities(
|
|
|
|
fn spawn_entities(
|
|
|
|
events: Query<
|
|
|
|
events: Query<(Entity, &Handle<SaveEntity>), Added<Handle<SaveEntity>>>,
|
|
|
|
(Entity, &Handle<SaveEntity>),
|
|
|
|
|
|
|
|
Or<(Added<Handle<SaveEntity>>, Changed<Handle<SaveEntity>>)>,
|
|
|
|
|
|
|
|
>,
|
|
|
|
|
|
|
|
save_entities: Res<Assets<SaveEntity>>,
|
|
|
|
save_entities: Res<Assets<SaveEntity>>,
|
|
|
|
mut commands: Commands,
|
|
|
|
mut commands: Commands,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
events.iter().for_each(|(entity, handle)| {
|
|
|
|
events.iter().for_each(|(entity, handle)| {
|
|
|
|
|
|
|
|
debug!("Spawning entity {:?} {:?}", entity, handle);
|
|
|
|
|
|
|
|
|
|
|
|
// Get a handle on the
|
|
|
|
// Get a handle on the
|
|
|
|
let mut e = commands.entity(entity);
|
|
|
|
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::<Handle<SaveEntity>>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get the entity asset containing reflected component
|
|
|
|
// Get the entity asset containing reflected component
|
|
|
|
let save_entity = save_entities.get(handle).unwrap();
|
|
|
|
let save_entity = save_entities.get(handle).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
// Add each component to the entity
|
|
|
|
// Add each component to the entity
|
|
|
|
debug!("Populating entity with components {:?}", entity);
|
|
|
|
|
|
|
|
save_entity.components.iter().for_each(|component| {
|
|
|
|
save_entity.components.iter().for_each(|component| {
|
|
|
|
e.insert_reflect(component.clone_value());
|
|
|
|
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<SaveEntity>)>,
|
|
|
|
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
|
|
|
|
mut events: EventReader<AssetEvent<SaveEntity>>,
|
|
|
|
|
|
|
|
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<SaveEntity>
|
|
|
|
|
|
|
|
query
|
|
|
|
|
|
|
|
.iter()
|
|
|
|
|
|
|
|
.filter(|(_entity, handle)| handle.id() == *id)
|
|
|
|
|
|
|
|
.for_each(|(entity, handle)| {
|
|
|
|
|
|
|
|
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::<Handle<SaveEntity>>().insert(handle.clone());
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_ => debug!("Skipping SaveEntity event {:?}", event),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn debug_entities(
|
|
|
|
|
|
|
|
events: Query<Entity, Or<(Changed<Handle<SaveEntity>>, Added<Handle<SaveEntity>>)>>,
|
|
|
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
events.iter().for_each(|e| {
|
|
|
|
|
|
|
|
commands.entity(e).log_components();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|