Compare commits

..

3 Commits

Author SHA1 Message Date
Elijah Voigt 957ec64ee0 Cleaning up some assets and parsing logic 1 year ago
Elijah Voigt 804021debf Work log, remove one billion row challenge 1 year ago
Elijah Voigt 2f9664940d Converted all functions to return Box<dyn Reflect>
this is nice because it makes things a little more uniform.
1 year ago

@ -1,6 +1,5 @@
uuid 739619d7-b8a1-42b4-8803-2b8cfedeebf1
name "Editor Camera" name "Editor Camera"
editor_tag editorTag
camera render_target window b90f31a2-34d9-42c2-9e53-646d9c9c6c70 camera target window "window.entity"
fly_camera flyCamera
transform transform 10.0 10.0 10.0 transform translation 10.0 10.0 10.0 rotation 0.0 0.0 0.0 1.0 scale 1.0 1.0 1.0

@ -1,4 +1,3 @@
uuid 08e1a4d9-6c76-471d-af02-1aa7db1b435a editorTag
editor_tag uiNode
ui_node targetCamera "camera.entity"
target_camera 739619d7-b8a1-42b4-8803-2b8cfedeebf1

@ -1,4 +1,3 @@
uuid 0088bc7d-851e-402b-9d20-fadfe5cab106 editorTag
editor_tag uiText "Welcome to the editor" color #ffffff size 12.0
ui_text text "Welcome to the editor" color 1.0 1.0 1.0 1.0 parent "ui_container.entity"
parent 08e1a4d9-6c76-471d-af02-1aa7db1b435a

@ -1,4 +1,3 @@
uuid b90f31a2-34d9-42c2-9e53-646d9c9c6c70 editorTag
editor_tag
name "Editor Window" name "Editor Window"
window title "Editor" visible false window "Editor" visible false

@ -1,4 +1,3 @@
name camera name camera
uuid 2e45b7e9-6722-4d50-8ea5-67f25b8b0f62
transform translation 2.0 2.0 0.0 rotation 0.0 0.0 0.0 1.0 scale 1.0 1.0 1.0 transform translation 2.0 2.0 0.0 rotation 0.0 0.0 0.0 1.0 scale 1.0 1.0 1.0
camera camera

@ -1,4 +1,3 @@
name van name van
uuid 5c270e84-814c-4d51-9ccd-ab79d9e01f1d
transform translation 0.0 0.0 0.0 rotation 0.0 0.0 0.0 1.0 scale 1.0 1.0 1.0 transform translation 0.0 0.0 0.0 rotation 0.0 0.0 0.0 1.0 scale 1.0 1.0 1.0
model "models/van.glb" "Scene" model "models/van.glb" "Scene"

@ -1,6 +0,0 @@
[package]
name = "obrc"
version = "0.1.0"
edition = "2021"
[dependencies]

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}

@ -53,8 +53,9 @@ impl std::convert::From<&EditorState> for bool {
} }
/// Tag component for editor entities /// Tag component for editor entities
#[derive(Component)] #[derive(Component, Reflect, Debug, Default)]
struct EditorTag; #[reflect(Component, Default)]
pub(crate) struct EditorTag;
fn toggle_editor_state( fn toggle_editor_state(
curr_state: Res<State<EditorState>>, curr_state: Res<State<EditorState>>,
@ -73,15 +74,11 @@ fn toggle_editor_state(
} }
} }
fn spawn_editor( fn spawn_editor(mut _commands: Commands) {
mut _commands: Commands,
) {
todo!("Spawn editor"); todo!("Spawn editor");
} }
fn despawn_editor( fn despawn_editor(mut _comands: Commands) {
mut _comands: Commands,
) {
todo!("Despawn editor"); todo!("Despawn editor");
} }
@ -123,4 +120,4 @@ fn plane_gizmos(mut gizmos: Gizmos) {
gizmos.arrow(Vec3::ZERO, Vec3::Y, DARK_GREEN); gizmos.arrow(Vec3::ZERO, Vec3::Y, DARK_GREEN);
gizmos.arrow(Vec3::ZERO, Vec3::Z, BLUE); gizmos.arrow(Vec3::ZERO, Vec3::Z, BLUE);
} }
} }

@ -32,4 +32,4 @@ fn main() {
.add_plugins(save::SavePlugin) .add_plugins(save::SavePlugin)
.add_plugins(window::WindowPlugin) .add_plugins(window::WindowPlugin)
.run(); .run();
} }

@ -1,11 +1,7 @@
use nom::character::complete::hex_digit1;
use crate::prelude::*; use crate::prelude::*;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub(crate) enum SaveEntityParseError { pub(crate) enum SaveEntityParseError {
#[error("Failed to parse Uuid: {0}")]
Uuid(#[from] uuid::Error),
#[error("Failed to parse name")] #[error("Failed to parse name")]
Name, Name,
#[error("Failed to parse Transform")] #[error("Failed to parse Transform")]
@ -14,8 +10,6 @@ pub(crate) enum SaveEntityParseError {
Nom(nom::Err<nom::error::Error<Box<str>>>), Nom(nom::Err<nom::error::Error<Box<str>>>),
#[error("Failed to parse camera")] #[error("Failed to parse camera")]
Camera, Camera,
#[error("Failed to parse marker component")]
Marker,
} }
// Convert Nom error to parse error // Convert Nom error to parse error
@ -49,8 +43,9 @@ fn parse_string(i: &str) -> IResult<&str, &str> {
} }
/// ///
/// Returns reflected `Transform`
/// ///
pub(crate) fn parse_save_transform(line: &str) -> Result<Transform, SaveEntityParseError> { pub(crate) fn parse_save_transform(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
let (rem, _) = tag("transform")(line)?; let (rem, _) = tag("transform")(line)?;
let mut transform = Transform::default(); let mut transform = Transform::default();
@ -80,7 +75,7 @@ pub(crate) fn parse_save_transform(line: &str) -> Result<Transform, SaveEntityPa
// Assert there are no trailing characters on the line // Assert there are no trailing characters on the line
debug_assert_eq!(curr, ""); debug_assert_eq!(curr, "");
Ok(transform) Ok(transform.clone_value())
} }
#[test] #[test]
@ -93,19 +88,23 @@ fn test_parse_transform() {
scale: Vec3::new(1.1, 1.2, 1.3), scale: Vec3::new(1.1, 1.2, 1.3),
}; };
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
/// ///
/// Returns a reflected `Name`
/// ///
pub(crate) fn parse_save_name(line: &str) -> Result<Name, SaveEntityParseError> { pub(crate) fn parse_save_name(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
let (remainder, _) = tag("name")(line)?; let (remainder, _) = tag("name")(line)?;
let n = remainder.trim().to_string(); let n = remainder.trim().to_string();
if n.is_empty() { if n.is_empty() {
Err(SaveEntityParseError::Name) Err(SaveEntityParseError::Name)
} else { } else {
let name = Name::new(n); let name = Name::new(n);
Ok(name) Ok(name.clone_value())
} }
} }
@ -116,87 +115,104 @@ fn test_parse_name() {
let parsed = parse_save_name(line).unwrap(); let parsed = parse_save_name(line).unwrap();
let expected = Name::new("Van"); let expected = Name::new("Van");
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
{ {
let line = "name Big Mike"; let line = "name Big Mike";
let parsed = parse_save_name(line).unwrap(); let parsed = parse_save_name(line).unwrap();
let expected = Name::new("Big Mike"); let expected = Name::new("Big Mike");
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
} }
#[derive(Component, Clone, Debug, Reflect, PartialEq)] #[derive(Debug, Default, Reflect, PartialEq)]
#[reflect(Component)] #[reflect(Component, PartialEq)]
pub(crate) struct EntityUuid { pub(crate) struct SaveModel {
id: String, gltf_file: PathBuf,
scene_name: String,
} }
/// impl Component for SaveModel {
/// const STORAGE_TYPE: StorageType = StorageType::Table;
pub(crate) fn parse_save_uuid(line: &str) -> Result<EntityUuid, SaveEntityParseError> {
let (remainder, _) = tag("uuid")(line)?;
let id = remainder.trim().into();
Ok(EntityUuid { id })
}
#[test] fn register_component_hooks(hooks: &mut ComponentHooks) {
fn test_parse_uuid() { todo!("Assign Scene Handle for SaveModel")
let line = "uuid 1c16ab9a-5f79-4340-8469-4086f69c64f2"; }
let parsed = parse_save_uuid(line).unwrap();
let expected = EntityUuid {
id: "1c16ab9a-5f79-4340-8469-4086f69c64f2".into(),
};
assert_eq!(parsed, expected);
} }
/// ///
/// Returns a reflected `SaveModel`
/// ///
pub(crate) fn parse_save_model(line: &str) -> Result<(String, String), SaveEntityParseError> { pub(crate) fn parse_save_model(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
let (rem, (_, _, gltf_path, _, scene_name)) = let (rem, (_, _, gltf_path, _, scene_name)) =
tuple((tag("model"), space1, parse_string, space1, parse_string))(line)?; tuple((tag("model"), space1, parse_string, space1, parse_string))(line)?;
debug_assert!(rem == ""); debug_assert!(rem == "");
Ok((gltf_path.into(), scene_name.into())) Ok(SaveModel {
gltf_file: gltf_path.into(),
scene_name: scene_name.into(),
}
.clone_value())
} }
#[test] #[test]
fn test_parse_model() { fn test_parse_model() {
let line = "model \"models/foo.glb\" \"My Scene\""; let line = "model \"models/foo.glb\" \"My Scene\"";
let parsed = parse_save_model(line).unwrap(); let parsed = parse_save_model(line).unwrap();
let expected = (String::from("models/foo.glb"), String::from("My Scene")); let expected = SaveModel {
gltf_file: "models/foo.glb".into(),
scene_name: "My Scene".into(),
};
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
#[derive(Component, Debug, Default, PartialEq, Reflect, Clone)] #[derive(Debug, Default, PartialEq, Reflect, Clone)]
#[reflect_value(Component, Default)] #[reflect_value(Component, Default, PartialEq)]
pub(crate) enum SaveCameraRenderTarget { pub(crate) enum SaveCameraRenderTarget {
#[default] #[default]
Default, Default,
Window(Uuid), Window(PathBuf),
} }
pub(crate) fn parse_save_camera( impl Component for SaveCameraRenderTarget {
line: &str, const STORAGE_TYPE: StorageType = StorageType::Table;
) -> Result<SaveCameraRenderTarget, SaveEntityParseError> {
fn register_component_hooks(hooks: &mut ComponentHooks) {
todo!("Assign Render Target")
}
}
///
/// Returns a reflected `SaveCameraRenderTarget
///
pub(crate) fn parse_save_camera(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
if let Ok((rem, _camera)) = tag::<&str, &str, ()>("camera")(line) { if let Ok((rem, _camera)) = tag::<&str, &str, ()>("camera")(line) {
if let Ok((rem, (_, _target))) = tuple((space1::<&str, ()>, tag("target")))(rem) { if let Ok((rem, (_, _target))) = tuple((space1::<&str, ()>, tag("target")))(rem) {
if let Ok((rem, (_, _window))) = tuple((space1::<&str, ()>, tag("window")))(rem) { if let Ok((rem, (_, _window))) = tuple((space1::<&str, ()>, tag("window")))(rem) {
// Camera + target + window + UUID // Camera + target + window + UUID
if let Ok((rem, (_, uuid))) = tuple((space1::<&str, ()>, take(36usize)))(rem) { if let Ok((rem, (_, path))) =
tuple((space1::<&str, nom::error::Error<&str>>, parse_string))(rem)
{
debug_assert!(rem == ""); debug_assert!(rem == "");
let parsed_uuid = Uuid::parse_str(uuid)?; Ok(SaveCameraRenderTarget::Window(path.into()).clone_value())
Ok(SaveCameraRenderTarget::Window(parsed_uuid))
// Camera + target + widow // Camera + target + widow
} else { } else {
debug_assert!(rem == ""); debug_assert!(rem == "");
Ok(SaveCameraRenderTarget::Default) Ok(SaveCameraRenderTarget::Default.clone_value())
} }
// camera + target // camera + target
} else { } else {
@ -208,7 +224,7 @@ pub(crate) fn parse_save_camera(
} else { } else {
debug_assert!(rem == ""); debug_assert!(rem == "");
Ok(SaveCameraRenderTarget::Default) Ok(SaveCameraRenderTarget::Default.clone_value())
} }
// Nothing parsed well // Nothing parsed well
} else { } else {
@ -222,13 +238,19 @@ fn test_parse_camera() {
let line = "camera"; let line = "camera";
let parsed = parse_save_camera(line).unwrap(); let parsed = parse_save_camera(line).unwrap();
let expected = SaveCameraRenderTarget::Default; let expected = SaveCameraRenderTarget::Default;
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
{ {
let line = "camera target window"; let line = "camera target window";
let parsed = parse_save_camera(line).unwrap(); let parsed = parse_save_camera(line).unwrap();
let expected = SaveCameraRenderTarget::Default; let expected = SaveCameraRenderTarget::Default;
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
{ {
let line = "camera target"; let line = "camera target";
@ -236,11 +258,13 @@ fn test_parse_camera() {
assert!(parsed.is_err()); assert!(parsed.is_err());
} }
{ {
let line = "camera target window 9a1367e0-71e5-4c79-b4ad-02aa44b68af0"; let line = "camera target window \"some.entity\"";
let target_uuid = Uuid::parse_str("9a1367e0-71e5-4c79-b4ad-02aa44b68af0").unwrap();
let parsed = parse_save_camera(line).unwrap(); let parsed = parse_save_camera(line).unwrap();
let expected = SaveCameraRenderTarget::Window(target_uuid); let expected = SaveCameraRenderTarget::Window("some.entity".into());
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
{ {
let line = "notcamera"; let line = "notcamera";
@ -251,20 +275,32 @@ fn test_parse_camera() {
/// SaveParent entity which is a reference to which entity this is a child of /// SaveParent entity which is a reference to which entity this is a child of
/// A run-time system converts this to a bevy Parent component /// A run-time system converts this to a bevy Parent component
#[derive(Component, PartialEq, Debug, Reflect, Clone)] #[derive(PartialEq, Debug, Reflect, Clone)]
#[reflect_value(Component)] #[reflect_value(Component, PartialEq)]
pub(crate) struct SaveParent(String); pub(crate) struct SaveParent(String);
impl Component for SaveParent {
const STORAGE_TYPE: StorageType = StorageType::Table;
fn register_component_hooks(hooks: &mut ComponentHooks) {
todo!("Assign parent for entity")
}
}
///
/// Parses a parent entity with this format: /// Parses a parent entity with this format:
/// ```text /// ```text
/// parent some_other_file.entity /// parent some_other_file.entity
/// ``` /// ```
pub(crate) fn parse_save_parent(line: &str) -> Result<SaveParent, SaveEntityParseError> { ///
/// Returns a reflected `SaveParent`
///
pub(crate) fn parse_save_parent(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
let (rem, (_, _, parent_file)) = tuple((tag("parent"), space1, parse_string))(line)?; let (rem, (_, _, parent_file)) = tuple((tag("parent"), space1, parse_string))(line)?;
debug_assert!(rem.is_empty()); debug_assert!(rem.is_empty());
Ok(SaveParent(parent_file.into())) Ok(SaveParent(parent_file.into()).clone_value())
} }
#[test] #[test]
@ -272,14 +308,19 @@ fn test_parse_parent() {
let line = "parent \"some_other_file.entity\""; let line = "parent \"some_other_file.entity\"";
let parsed = parse_save_parent(line).unwrap(); let parsed = parse_save_parent(line).unwrap();
let expected = SaveParent("some_other_file.entity".into()); let expected = SaveParent("some_other_file.entity".into());
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
/// ///
/// Parse the Window component (which is very big!) /// Parse the Window component (which is very big!)
/// We only sparsely define the bits that we want to edit (for now) /// We only sparsely define the bits that we want to edit (for now)
/// ///
pub(crate) fn parse_save_window(line: &str) -> Result<Window, SaveEntityParseError> { /// Returns a reflected `Window`
///
pub(crate) fn parse_save_window(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
let (rem, (_, _, window_title)) = tuple((tag("window"), space1, parse_string))(line)?; let (rem, (_, _, window_title)) = tuple((tag("window"), space1, parse_string))(line)?;
let (rem, (_, _, _, visibility)) = tuple((space1, tag("visible"), space1, parse_bool))(rem)?; let (rem, (_, _, _, visibility)) = tuple((space1, tag("visible"), space1, parse_bool))(rem)?;
@ -290,7 +331,8 @@ pub(crate) fn parse_save_window(line: &str) -> Result<Window, SaveEntityParseErr
title: window_title.into(), title: window_title.into(),
visible: visibility, visible: visibility,
..default() ..default()
}) }
.clone_value())
} }
#[test] #[test]
@ -302,17 +344,22 @@ fn test_parse_window() {
title: "Editor".into(), title: "Editor".into(),
..default() ..default()
}; };
assert_eq!(parsed.visible, expected.visible); assert!(expected
assert_eq!(parsed.title, expected.title); .clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
/// ///
/// The UI Text bundle specified as a sparse subset of a bundle /// The UI Text bundle specified as a sparse subset of a bundle
/// ```text /// ```text
/// text "This is the text" color #abc123 size 12.34 /// uiText "This is the text" color #abc123 size 12.34
/// ``` /// ```
pub(crate) fn parse_save_ui_text(line: &str) -> Result<TextBundle, SaveEntityParseError> { ///
let (rem, (_tag_text, _space1, text)) = tuple((tag("text"), space1, parse_string))(line)?; /// Returns a reflected `Text`
///
pub(crate) fn parse_save_ui_text(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
let (rem, (_tag_text, _space1, text)) = tuple((tag("uiText"), space1, parse_string))(line)?;
let (rem, (_space, _tag_color, _space1, _hash, hex_color)) = let (rem, (_space, _tag_color, _space1, _hash, hex_color)) =
tuple((space1, tag("color"), space1, char('#'), hex_digit1))(rem)?; tuple((space1, tag("color"), space1, char('#'), hex_digit1))(rem)?;
@ -327,15 +374,12 @@ pub(crate) fn parse_save_ui_text(line: &str) -> Result<TextBundle, SaveEntityPar
font_size, font_size,
..default() ..default()
}; };
Ok(TextBundle { Ok(Text::from_section(text, style).clone_value())
text: Text::from_section(text, style),
..default()
})
} }
#[test] #[test]
fn test_save_ui_text() { fn test_save_ui_text() {
let line = "text \"This is the text\" color #caffee size 14.6"; let line = "uiText \"This is the text\" color #caffee size 14.6";
let parsed = parse_save_ui_text(line).unwrap(); let parsed = parse_save_ui_text(line).unwrap();
let expected = Text::from_section( let expected = Text::from_section(
"This is the text", "This is the text",
@ -345,24 +389,22 @@ fn test_save_ui_text() {
..default() ..default()
}, },
); );
assert_eq!(parsed.text.sections[0].value, expected.sections[0].value); assert!(expected
assert_eq!( .clone_value()
parsed.text.sections[0].style.color, .reflect_partial_eq(parsed.as_reflect())
expected.sections[0].style.color, .unwrap());
);
assert_eq!(
parsed.text.sections[0].style.font_size,
expected.sections[0].style.font_size,
);
} }
/// ///
/// Returns a parser function for a basic stand-alone tag /// Returns a parser function for a basic stand-alone tag
/// e.g., "editor_tag" or "ui_node" /// e.g., "editor_tag" or "ui_node"
///
pub(crate) fn parse_save_tag<T: Component + Reflect + Default>( pub(crate) fn parse_save_tag<T: Component + Reflect + Default>(
t: &str, t: &str,
) -> impl FnOnce(&str) -> Result<T, SaveEntityParseError> + '_ { ) -> impl FnOnce(&str) -> Result<Box<dyn Reflect>, SaveEntityParseError> + '_ {
move |line: &str| -> Result<T, SaveEntityParseError> { Ok(tag(t)(line).map(|_| T::default())?) } move |line: &str| -> Result<Box<dyn Reflect>, SaveEntityParseError> {
Ok(tag(t)(line).map(|_| T::default().clone_value())?)
}
} }
#[derive(Component, Reflect, PartialEq, Debug, Default)] #[derive(Component, Reflect, PartialEq, Debug, Default)]
@ -374,24 +416,37 @@ fn test_save_tag() {
let line = "testing"; let line = "testing";
let parsed = parse_save_tag::<TestingTag>("testing")(line).unwrap(); let parsed = parse_save_tag::<TestingTag>("testing")(line).unwrap();
let expected = TestingTag; let expected = TestingTag;
assert_eq!(parsed, expected); assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }
#[derive(Component, Clone, Debug, Reflect, PartialEq)] #[derive(Clone, Debug, Reflect, PartialEq)]
#[reflect(Component)] #[reflect(Component)]
pub(crate) struct SaveTargetCamera(String); pub(crate) struct SaveTargetCamera(String);
impl Component for SaveTargetCamera {
const STORAGE_TYPE: StorageType = StorageType::Table;
fn register_component_hooks(hooks: &mut ComponentHooks) {
todo!("Assign target camera")
}
}
/// Parses the a SaveTargetCamera which at runtime is converted to a TargetCamera /// Parses the a SaveTargetCamera which at runtime is converted to a TargetCamera
/// ```text /// ```text
/// target-camera "./level-camera.entity" /// targetCamera "./level-camera.entity"
/// ``` /// ```
///
/// Returns reflected `SaveTargetCamera`
pub(crate) fn parse_save_target_camera( pub(crate) fn parse_save_target_camera(
line: &str, line: &str,
) -> Result<SaveTargetCamera, SaveEntityParseError> { ) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
Ok( Ok(
tuple((tag("target-camera"), space1, parse_string))(line).map( tuple((tag("targetCamera"), space1, parse_string))(line).map(
|(_, (_, _, target_camera_entity_file))| { |(_, (_, _, target_camera_entity_file))| {
SaveTargetCamera(target_camera_entity_file.into()) SaveTargetCamera(target_camera_entity_file.into()).clone_value()
}, },
)?, )?,
) )
@ -399,8 +454,12 @@ pub(crate) fn parse_save_target_camera(
#[test] #[test]
fn test_target_camera() { fn test_target_camera() {
let line = "target-camera \"./level-camera.entity\""; let line = "targetCamera \"./level-camera.entity\"";
let parsed = parse_save_target_camera(line).unwrap(); let parsed = parse_save_target_camera(line).unwrap();
let expected = SaveTargetCamera("./level-camera.entity".into()); let expected = SaveTargetCamera("./level-camera.entity".into());
assert_eq!(parsed, expected);
assert!(expected
.clone_value()
.reflect_partial_eq(parsed.as_reflect())
.unwrap());
} }

@ -9,16 +9,18 @@ pub(crate) use bevy::{
render::camera::RenderTarget, render::camera::RenderTarget,
window::{PrimaryWindow, WindowCloseRequested, WindowRef}, window::{PrimaryWindow, WindowCloseRequested, WindowRef},
}; };
pub(crate) use nom::bytes::complete::take; pub(crate) use nom::character::complete::hex_digit1;
pub(crate) use nom::{ pub(crate) use nom::{
branch::{alt, permutation}, branch::alt,
bytes::complete::{tag, take_until1}, bytes::complete::{tag, take_until1},
character::complete::{char, hex_digit1, space1}, character::complete::{char, space1},
number::complete::float, number::complete::float,
sequence::tuple, sequence::tuple,
IResult, IResult,
}; };
pub(crate) use std::path::PathBuf;
pub(crate) use thiserror::Error; pub(crate) use thiserror::Error;
pub(crate) use uuid::Uuid;
pub(crate) use crate::{conditions::*, parser::*}; pub(crate) use crate::{conditions::*, parser::*};
pub(crate) use bevy::ecs::component::{ComponentHooks, StorageType};

@ -5,10 +5,9 @@ pub(crate) struct SavePlugin;
impl Plugin for SavePlugin { impl Plugin for SavePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.register_type::<SaveCameraRenderTarget>()
.register_type::<EntityUuid>()
.register_type::<SaveCameraRenderTarget>()
.register_type::<GltfScene>() .register_type::<GltfScene>()
.register_type::<SaveModel>()
.init_asset::<SaveEntity>() .init_asset::<SaveEntity>()
.init_asset_loader::<SaveEntityLoader>() .init_asset_loader::<SaveEntityLoader>()
.init_asset_loader::<SaveSceneLoader>() .init_asset_loader::<SaveSceneLoader>()
@ -37,31 +36,40 @@ impl SaveEntity {
) -> 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() };
lines.into_iter().for_each(|line| { let fns = [
parse_save_name,
if let Ok(name) = parse_save_name(line) { parse_save_transform,
entity.components.push(name.clone_value()); parse_save_model,
} else if let Ok(transform) = parse_save_transform(line) { parse_save_camera,
entity.components.push(transform.clone_value()); parse_save_parent,
} else if let Ok(uuid) = parse_save_uuid(line) { parse_save_window,
entity.components.push(uuid.clone_value()); parse_save_target_camera,
} else if let Ok((gltf_file, scene_name)) = parse_save_model(line) { parse_save_ui_text,
let gltf_scene = GltfScene { gltf: load_context.load(gltf_file), name: scene_name }; // parse_save_tag::<EditorTag>("editor_tag"),
entity.components.push(gltf_scene.clone_value()); ];
} else if let Ok(target) = parse_save_camera(line) { lines
entity.components.push(target.clone_value()); .into_iter()
} else if let Ok(parent) = parse_save_parent(line) { .filter(|line| !line.is_empty())
entity.components.push(parent.clone_value()); .for_each(|line| {
} else if let Ok(window) = parse_save_window(line) { // track if this line matched any components
entity.components.push(window.clone_value()); let mut good = false;
// } else if let Ok(ui_text_bundle) = parse_save_ui_text(line) {
// entity.components.push(ui_text_bundle.clone_value()); // Run line against all parsers
} else if let Ok(target_camera) = parse_save_target_camera(line) { for f in fns {
entity.components.push(target_camera.clone_value()); if let Ok(v) = f(line) {
} else { entity.components.push(v);
error!("Failed to parse line component `{:?}`", line); good = true;
} }
}); }
if !good {
error!(
file = load_context.path().to_str().unwrap(),
line = line,
"failed to parse component",
);
}
});
Ok(entity) Ok(entity)
} }
} }
@ -129,11 +137,11 @@ impl AssetLoader for SaveSceneLoader {
let asset_path = load_context.path().to_path_buf(); let asset_path = load_context.path().to_path_buf();
let parent_dir = asset_path.parent().unwrap(); let parent_dir = asset_path.parent().unwrap();
let _sub_assets: Vec<Handle<SaveEntity>> = s.lines().map(|line| { let _sub_assets: Vec<Handle<SaveEntity>> = s
parent_dir.join(line) .lines()
}).map(|path| { .map(|line| parent_dir.join(line))
load_context.load(path) .map(|path| load_context.load(path))
}).collect(); .collect();
Ok(DynamicScene::default()) Ok(DynamicScene::default())
} }
@ -143,14 +151,10 @@ impl AssetLoader for SaveSceneLoader {
} }
} }
fn test_load_entity(loader: Res<AssetServer>, mut commands: Commands) { fn test_load_entity(loader: Res<AssetServer>, mut commands: Commands) {
let _: Handle<DynamicScene> = loader.load("editor/_.scene"); let _: Handle<DynamicScene> = loader.load("editor/_.scene");
let handle: Handle<SaveEntity> = loader.load("levels/00/entities/van.entity"); let handle: Handle<SaveEntity> = loader.load("levels/00/entities/van.entity");
commands.spawn(( commands.spawn((SpatialBundle { ..default() }, handle));
SpatialBundle { ..default() },
handle,
));
} }
fn spawn_loaded_entities( fn spawn_loaded_entities(

@ -0,0 +1 @@
Wed Jul 31 09:09:04 PM PDT 2024 Ended work on T -> Box<dyn Reflect> parsing stuff
Loading…
Cancel
Save