|
|
|
@ -1,7 +1,11 @@
|
|
|
|
|
|
|
|
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")]
|
|
|
|
@ -10,6 +14,8 @@ 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
|
|
|
|
@ -43,9 +49,8 @@ fn parse_string(i: &str) -> IResult<&str, &str> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Returns reflected `Transform`
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
pub(crate) fn parse_save_transform(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
|
|
|
|
pub(crate) fn parse_save_transform(line: &str) -> Result<Transform, SaveEntityParseError> {
|
|
|
|
let (rem, _) = tag("transform")(line)?;
|
|
|
|
let (rem, _) = tag("transform")(line)?;
|
|
|
|
|
|
|
|
|
|
|
|
let mut transform = Transform::default();
|
|
|
|
let mut transform = Transform::default();
|
|
|
|
@ -75,7 +80,7 @@ pub(crate) fn parse_save_transform(line: &str) -> Result<Box<dyn Reflect>, SaveE
|
|
|
|
// 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.clone_value())
|
|
|
|
Ok(transform)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
@ -88,23 +93,19 @@ fn test_parse_transform() {
|
|
|
|
scale: Vec3::new(1.1, 1.2, 1.3),
|
|
|
|
scale: Vec3::new(1.1, 1.2, 1.3),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
assert!(expected
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
.clone_value()
|
|
|
|
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
|
|
|
|
.unwrap());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Returns a reflected `Name`
|
|
|
|
|
|
|
|
///
|
|
|
|
///
|
|
|
|
pub(crate) fn parse_save_name(line: &str) -> Result<Box<dyn Reflect>, SaveEntityParseError> {
|
|
|
|
pub(crate) fn parse_save_name(line: &str) -> Result<Name, 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.clone_value())
|
|
|
|
Ok(name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -115,104 +116,87 @@ 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!(expected
|
|
|
|
assert_eq!(parsed, 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!(expected
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
.clone_value()
|
|
|
|
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
|
|
|
|
.unwrap());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Reflect, PartialEq)]
|
|
|
|
#[derive(Component, Clone, Debug, Reflect, PartialEq)]
|
|
|
|
#[reflect(Component, PartialEq)]
|
|
|
|
#[reflect(Component)]
|
|
|
|
pub(crate) struct SaveModel {
|
|
|
|
pub(crate) struct EntityUuid {
|
|
|
|
gltf_file: PathBuf,
|
|
|
|
id: String,
|
|
|
|
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 })
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn register_component_hooks(hooks: &mut ComponentHooks) {
|
|
|
|
#[test]
|
|
|
|
todo!("Assign Scene Handle for SaveModel")
|
|
|
|
fn test_parse_uuid() {
|
|
|
|
}
|
|
|
|
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<Box<dyn Reflect>, SaveEntityParseError> {
|
|
|
|
pub(crate) fn parse_save_model(line: &str) -> Result<(String, String), 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(SaveModel {
|
|
|
|
Ok((gltf_path.into(), scene_name.into()))
|
|
|
|
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 = SaveModel {
|
|
|
|
let expected = (String::from("models/foo.glb"), String::from("My Scene"));
|
|
|
|
gltf_file: "models/foo.glb".into(),
|
|
|
|
|
|
|
|
scene_name: "My Scene".into(),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert!(expected
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
.clone_value()
|
|
|
|
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
|
|
|
|
.unwrap());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default, PartialEq, Reflect, Clone)]
|
|
|
|
#[derive(Component, Debug, Default, PartialEq, Reflect, Clone)]
|
|
|
|
#[reflect_value(Component, Default, PartialEq)]
|
|
|
|
#[reflect_value(Component, Default)]
|
|
|
|
pub(crate) enum SaveCameraRenderTarget {
|
|
|
|
pub(crate) enum SaveCameraRenderTarget {
|
|
|
|
#[default]
|
|
|
|
#[default]
|
|
|
|
Default,
|
|
|
|
Default,
|
|
|
|
Window(PathBuf),
|
|
|
|
Window(Uuid),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Component for SaveCameraRenderTarget {
|
|
|
|
pub(crate) fn parse_save_camera(
|
|
|
|
const STORAGE_TYPE: StorageType = StorageType::Table;
|
|
|
|
line: &str,
|
|
|
|
|
|
|
|
) -> 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, (_, path))) =
|
|
|
|
if let Ok((rem, (_, uuid))) = tuple((space1::<&str, ()>, take(36usize)))(rem) {
|
|
|
|
tuple((space1::<&str, nom::error::Error<&str>>, parse_string))(rem)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
debug_assert!(rem == "");
|
|
|
|
debug_assert!(rem == "");
|
|
|
|
|
|
|
|
|
|
|
|
Ok(SaveCameraRenderTarget::Window(path.into()).clone_value())
|
|
|
|
let parsed_uuid = Uuid::parse_str(uuid)?;
|
|
|
|
|
|
|
|
Ok(SaveCameraRenderTarget::Window(parsed_uuid))
|
|
|
|
// Camera + target + widow
|
|
|
|
// Camera + target + widow
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
debug_assert!(rem == "");
|
|
|
|
debug_assert!(rem == "");
|
|
|
|
|
|
|
|
|
|
|
|
Ok(SaveCameraRenderTarget::Default.clone_value())
|
|
|
|
Ok(SaveCameraRenderTarget::Default)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// camera + target
|
|
|
|
// camera + target
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -224,7 +208,7 @@ pub(crate) fn parse_save_camera(line: &str) -> Result<Box<dyn Reflect>, SaveEnti
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
debug_assert!(rem == "");
|
|
|
|
debug_assert!(rem == "");
|
|
|
|
|
|
|
|
|
|
|
|
Ok(SaveCameraRenderTarget::Default.clone_value())
|
|
|
|
Ok(SaveCameraRenderTarget::Default)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Nothing parsed well
|
|
|
|
// Nothing parsed well
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -238,19 +222,13 @@ 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!(expected
|
|
|
|
assert_eq!(parsed, 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!(expected
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
.clone_value()
|
|
|
|
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
|
|
|
|
.unwrap());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let line = "camera target";
|
|
|
|
let line = "camera target";
|
|
|
|
@ -258,13 +236,11 @@ fn test_parse_camera() {
|
|
|
|
assert!(parsed.is_err());
|
|
|
|
assert!(parsed.is_err());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let line = "camera target window \"some.entity\"";
|
|
|
|
let line = "camera target window 9a1367e0-71e5-4c79-b4ad-02aa44b68af0";
|
|
|
|
|
|
|
|
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("some.entity".into());
|
|
|
|
let expected = SaveCameraRenderTarget::Window(target_uuid);
|
|
|
|
assert!(expected
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
.clone_value()
|
|
|
|
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
|
|
|
|
.unwrap());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let line = "notcamera";
|
|
|
|
let line = "notcamera";
|
|
|
|
@ -275,32 +251,20 @@ 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(PartialEq, Debug, Reflect, Clone)]
|
|
|
|
#[derive(Component, PartialEq, Debug, Reflect, Clone)]
|
|
|
|
#[reflect_value(Component, PartialEq)]
|
|
|
|
#[reflect_value(Component)]
|
|
|
|
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()).clone_value())
|
|
|
|
Ok(SaveParent(parent_file.into()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
@ -308,19 +272,14 @@ 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!(expected
|
|
|
|
assert_eq!(parsed, 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)
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Returns a reflected `Window`
|
|
|
|
pub(crate) fn parse_save_window(line: &str) -> Result<Window, SaveEntityParseError> {
|
|
|
|
///
|
|
|
|
|
|
|
|
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)?;
|
|
|
|
@ -331,8 +290,7 @@ pub(crate) fn parse_save_window(line: &str) -> Result<Box<dyn Reflect>, SaveEnti
|
|
|
|
title: window_title.into(),
|
|
|
|
title: window_title.into(),
|
|
|
|
visible: visibility,
|
|
|
|
visible: visibility,
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.clone_value())
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
@ -344,22 +302,17 @@ fn test_parse_window() {
|
|
|
|
title: "Editor".into(),
|
|
|
|
title: "Editor".into(),
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
assert!(expected
|
|
|
|
assert_eq!(parsed.visible, expected.visible);
|
|
|
|
.clone_value()
|
|
|
|
assert_eq!(parsed.title, expected.title);
|
|
|
|
.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
|
|
|
|
/// uiText "This is the text" color #abc123 size 12.34
|
|
|
|
/// text "This is the text" color #abc123 size 12.34
|
|
|
|
/// ```
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
pub(crate) fn parse_save_ui_text(line: &str) -> Result<TextBundle, SaveEntityParseError> {
|
|
|
|
/// Returns a reflected `Text`
|
|
|
|
let (rem, (_tag_text, _space1, text)) = tuple((tag("text"), space1, parse_string))(line)?;
|
|
|
|
///
|
|
|
|
|
|
|
|
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)?;
|
|
|
|
@ -374,12 +327,15 @@ pub(crate) fn parse_save_ui_text(line: &str) -> Result<Box<dyn Reflect>, SaveEnt
|
|
|
|
font_size,
|
|
|
|
font_size,
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
Ok(Text::from_section(text, style).clone_value())
|
|
|
|
Ok(TextBundle {
|
|
|
|
|
|
|
|
text: Text::from_section(text, style),
|
|
|
|
|
|
|
|
..default()
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
fn test_save_ui_text() {
|
|
|
|
fn test_save_ui_text() {
|
|
|
|
let line = "uiText \"This is the text\" color #caffee size 14.6";
|
|
|
|
let line = "text \"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",
|
|
|
|
@ -389,22 +345,24 @@ fn test_save_ui_text() {
|
|
|
|
..default()
|
|
|
|
..default()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
);
|
|
|
|
assert!(expected
|
|
|
|
assert_eq!(parsed.text.sections[0].value, expected.sections[0].value);
|
|
|
|
.clone_value()
|
|
|
|
assert_eq!(
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
parsed.text.sections[0].style.color,
|
|
|
|
.unwrap());
|
|
|
|
expected.sections[0].style.color,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
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<Box<dyn Reflect>, SaveEntityParseError> + '_ {
|
|
|
|
) -> impl FnOnce(&str) -> Result<T, SaveEntityParseError> + '_ {
|
|
|
|
move |line: &str| -> Result<Box<dyn Reflect>, SaveEntityParseError> {
|
|
|
|
move |line: &str| -> Result<T, SaveEntityParseError> { Ok(tag(t)(line).map(|_| T::default())?) }
|
|
|
|
Ok(tag(t)(line).map(|_| T::default().clone_value())?)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Component, Reflect, PartialEq, Debug, Default)]
|
|
|
|
#[derive(Component, Reflect, PartialEq, Debug, Default)]
|
|
|
|
@ -416,37 +374,24 @@ 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!(expected
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
.clone_value()
|
|
|
|
|
|
|
|
.reflect_partial_eq(parsed.as_reflect())
|
|
|
|
|
|
|
|
.unwrap());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Reflect, PartialEq)]
|
|
|
|
#[derive(Component, 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
|
|
|
|
/// targetCamera "./level-camera.entity"
|
|
|
|
/// target-camera "./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<Box<dyn Reflect>, SaveEntityParseError> {
|
|
|
|
) -> Result<SaveTargetCamera, SaveEntityParseError> {
|
|
|
|
Ok(
|
|
|
|
Ok(
|
|
|
|
tuple((tag("targetCamera"), space1, parse_string))(line).map(
|
|
|
|
tuple((tag("target-camera"), space1, parse_string))(line).map(
|
|
|
|
|(_, (_, _, target_camera_entity_file))| {
|
|
|
|
|(_, (_, _, target_camera_entity_file))| {
|
|
|
|
SaveTargetCamera(target_camera_entity_file.into()).clone_value()
|
|
|
|
SaveTargetCamera(target_camera_entity_file.into())
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)?,
|
|
|
|
)?,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
@ -454,12 +399,8 @@ pub(crate) fn parse_save_target_camera(
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
fn test_target_camera() {
|
|
|
|
fn test_target_camera() {
|
|
|
|
let line = "targetCamera \"./level-camera.entity\"";
|
|
|
|
let line = "target-camera \"./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());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|