Morphorm ECS and serializing/deserializing
Closed this issue · 6 comments
Hi,
I'm trying to write a JSON serializer/deserializer for morphorm ECS, as part of trying to learn how to write my own library crates.
I'd like to be able to write my Kayak UI in a serialized format that is loaded.
So far I've been unable to access the morphorm_ecs
crate. It doesn't seem to be available on crates.io?
[package]
name = "morphorm-serializer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
morphorm = "0.3.0"
regex = "1.7.0"
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.89"
use std::ops::Add;
use regex::Regex;
// use morphorm::Cache;
use morphorm::*;
use morphorm_ecs::*; // unresolved import
use serde_json;
use std::result::Result;
use std::error::Error;
use serde::{Deserialize, Serialize};
pub fn build_world(world: World, root: Entity, ui: UiNode) {
let mut world = World::default();
let root: Entity = world.add(None);
build_node(world, root, ui);
}
// starting very simple, just trying to handle with and pixels unit
pub fn build_node(world: World, node: Entity, ui: UiNode) {
if let Some(str) = ui.width {
let re = Regex::new(r"px$").unwrap();
if re.is_match(str) {
let number = str[..str.len() - 2];
let pixels = number.parse::<f32>().unwrap();
world.set_width(node, Units::Pixels(pixels));
}
}
dbg!(node)
}
type OptStr = Option<String>;
// type OptNum = Option<u32>;
#[derive(Debug, Serialize, Deserialize)]
pub struct UiNode {
#[serde(skip_serializing_if = "Option::is_none")]
width: OptStr,
height: OptStr,
child_space: OptStr,
position_type: OptStr,
}
pub fn parse_ui() -> Result<(), Box<dyn Error>> {
let json1 = r#"
{
"width": "2 px",
"height": "5 px"
}
"#;
let ui: UiNode = serde_json::from_str(json1)?;
println!("ui {:#?}", ui);
build_world(world, root, ui);
Ok(())
}
I think I understand now that the ecs
folder is just a sample use case and that I need to operate on Kayak UI directly?
I think I understand now that the
ecs
folder is just a sample use case and that I need to operate on Kayak UI directly?
Yes you are correct. The morphorm_ecs
crate is purely for demonstration on how morphorm can be integrated with an ECS pattern such as bevy and I think kayak? I believe that you only need to operate on the kayak crate but if that's not the case then I can add serde as an optional feature and provide serialization for the morphorm types. Let me know.
Thanks. I'm currently working on a Kayak UI JSON deserializer here: https://github.com/kristianmandrup/kayak_ui_deserializer
I discovered that I will need a macro in order to build the UI objects conditionally
let posx = self.posx();
let posy = self.posy();
let width = self.width();
let height = self.height();
let z_index = self.z_index();
let rect = Rect {
..Default::default()
};
if let Some(val) = posx {
// no setter available
rect.posx = val;
}
Will need to be replaced with something like the following if I understand correctly?
rect! { posx, posy, width, height, z_index }
I discovered how to generalize it using a macro approach exactly as described here :)
https://www.ralphminderhoud.com/blog/simple-struct-macro/
pub fn parse(&self) -> Result<Rect, &'static str> {
let posx = self.posx();
// ... repeat
let mut rect = Rect::default();
// ... repeat: use macro!
if let Some(val) = posx {
rect.posx = val;
}
I discovered how to generalize it using a macro approach exactly as described here :)
https://www.ralphminderhoud.com/blog/simple-struct-macro/
pub fn parse(&self) -> Result<Rect, &'static str> { let posx = self.posx(); // ... repeat let mut rect = Rect::default(); // ... repeat: use macro! if let Some(val) = posx { rect.posx = val; }
Ah that's great 👍 is this issue resolved then? Am I okay to close it?
Sure 😃