Compare commits

..

No commits in common. '780e3aa52094aa099aa4251eafc576814a44cda9' and 'd8f67c2cef7c47968899c9287e87e18ff758e38e' have entirely different histories.

@ -8,14 +8,14 @@ pub(crate) mod conditions;
pub(crate) mod editor; pub(crate) mod editor;
/// Menu: Main and otherwise /// Menu: Main and otherwise
pub(crate) mod menu; pub(crate) mod menu;
/// Save file parsing
pub(crate) mod parser;
/// Helper module containing common imports across the project /// Helper module containing common imports across the project
pub(crate) mod prelude; pub(crate) mod prelude;
/// Level saving/loading logic /// Level saving/loading logic
pub(crate) mod save; pub(crate) mod save;
/// Window handling /// Window handling
pub(crate) mod window; pub(crate) mod window;
/// Save file parsing
pub(crate) mod parser;
use crate::prelude::*; use crate::prelude::*;
@ -27,12 +27,10 @@ fn main() {
exit_condition: bevy::window::ExitCondition::OnPrimaryClosed, exit_condition: bevy::window::ExitCondition::OnPrimaryClosed,
..default() ..default()
})) }))
.add_plugins(camera::CameraPlugin) // .add_plugins(camera::CameraPlugin)
// .add_plugins(editor::EditorPlugin) // .add_plugins(editor::EditorPlugin)
// .add_plugins(menu::MenuPlugin) // .add_plugins(menu::MenuPlugin)
// .add_plugins(window::WindowPlugin) // .add_plugins(window::WindowPlugin)
.add_plugins(save::SavePlugin { .add_plugins(save::SavePlugin)
fns: vec![parse_save_name],
})
.run(); .run();
} }

@ -16,6 +16,7 @@ impl From<nom::Err<nom::error::Error<&str>>> for SaveEntityParseError {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub(crate) enum Token { pub(crate) enum Token {
Tag(String), Tag(String),
@ -32,12 +33,7 @@ pub(crate) fn tokenize(line: &str) -> Vec<Token> {
while l.len() > 0 { while l.len() > 0 {
debug!("Line: {:?}", l); debug!("Line: {:?}", l);
if let Ok((rem, (_, s, _))) = tuple(( if let Ok((rem, (_, s, _))) = tuple((char::<&str, ()>('"'), take_until("\""), char::<&str, ()>('"')))(l) {
char::<&str, ()>('"'),
take_until("\""),
char::<&str, ()>('"'),
))(l)
{
debug!("Parsed string {:?}", s); debug!("Parsed string {:?}", s);
tokens.push(Token::Str(s.into())); tokens.push(Token::Str(s.into()));
l = rem; l = rem;
@ -45,14 +41,13 @@ pub(crate) fn tokenize(line: &str) -> Vec<Token> {
debug!("Parsed float {:?}", num); debug!("Parsed float {:?}", num);
tokens.push(Token::Num(num.into())); tokens.push(Token::Num(num.into()));
l = rem; l = rem;
} else if let Ok((rem, (_, tag, _))) = tuple((space0, alphanumeric1::<&str, ()>, space0))(l) } else if let Ok((rem, (_, tag, _))) = tuple((space0, alphanumeric1::<&str, ()>, space0))(l) {
{
debug!("Parsed tag {:?}", tag); debug!("Parsed tag {:?}", tag);
tokens.push(Token::Tag(tag.into())); tokens.push(Token::Tag(tag.into()));
l = rem; l = rem;
} else { } else {
debug!("Breaking loop"); debug!("Breaking loop");
break; break
} }
} }
@ -77,12 +72,11 @@ fn test_tokenize() {
); );
} }
/// ///
/// Returns reflected `Transform` /// Returns reflected `Transform`
/// ///
pub(crate) fn parse_save_transform( pub(crate) fn parse_save_transform(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>,
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
// Tag(Transform), // Tag(Transform),
// Tag(Translation), Number, Number, Number // Tag(Translation), Number, Number, Number
// Tag(Rotation), Number, Number, Number, Number // Tag(Rotation), Number, Number, Number, Number
@ -113,12 +107,8 @@ fn test_parse_transform() {
/// ///
/// Returns a reflected `Name` /// Returns a reflected `Name`
/// ///
pub(crate) fn parse_save_name( pub(crate) fn parse_save_name(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>, if let Some((Token::Tag(t), &[Token::Str(ref s)])) = tokens.split_first() && *t == String::from("name") {
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
if let Some((Token::Tag(t), &[Token::Str(ref s)])) = tokens.split_first()
&& *t == String::from("name")
{
Ok(Name::new(s.clone()).clone_value()) Ok(Name::new(s.clone()).clone_value())
} else { } else {
Err(SaveEntityParseError::Component("Name".into())) Err(SaveEntityParseError::Component("Name".into()))
@ -169,9 +159,7 @@ impl Component for SaveModel {
/// ///
/// Returns a reflected `SaveModel` /// Returns a reflected `SaveModel`
/// ///
pub(crate) fn parse_save_model( pub(crate) fn parse_save_model(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>,
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
todo!("parse_save_model"); todo!("parse_save_model");
/* /*
@ -218,9 +206,7 @@ impl Component for SaveCameraRenderTarget {
/// ///
/// Returns a reflected `SaveCameraRenderTarget /// Returns a reflected `SaveCameraRenderTarget
/// ///
pub(crate) fn parse_save_camera( pub(crate) fn parse_save_camera(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>,
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
todo!("parse_save_camera"); todo!("parse_save_camera");
// Nothing parsed well // Nothing parsed well
@ -295,9 +281,7 @@ impl Component for SaveParent {
/// ///
/// Returns a reflected `SaveParent` /// Returns a reflected `SaveParent`
/// ///
pub(crate) fn parse_save_parent( pub(crate) fn parse_save_parent(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>,
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
todo!("parse_save_parent"); todo!("parse_save_parent");
// Ok(SaveParent(parent_file.into()).clone_value()) // Ok(SaveParent(parent_file.into()).clone_value())
@ -321,9 +305,7 @@ fn test_parse_parent() {
/// ///
/// Returns a reflected `Window` /// Returns a reflected `Window`
/// ///
pub(crate) fn parse_save_window( pub(crate) fn parse_save_window(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>,
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
todo!("parse_save_window"); todo!("parse_save_window");
/* /*
@ -360,9 +342,7 @@ fn test_parse_window() {
/// ///
/// Returns a reflected `Text` /// Returns a reflected `Text`
/// ///
pub(crate) fn parse_save_ui_text( pub(crate) fn parse_save_ui_text(tokens: &Vec<Token>) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
tokens: &Vec<Token>,
) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
todo!("parse_save_ui_text"); todo!("parse_save_ui_text");
/* /*

@ -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();
});
}

Loading…
Cancel
Save