use std::collections::HashMap;
use crate::sys::{registerSystem};
use crate::utils::*;
use serde::Serialize;
use wasm_bindgen::{JsCast, prelude::*};
#[macro_export]
macro_rules! system_def
{
(
$(schema: $schema:expr,)?
$(init: $init:expr,)?
$(pause: $pause:expr,)?
$(play: $play:expr,)?
$(tick: $tick:expr,)?
$(properties: $($fn_name:ident: $func:expr),*)?
) =>
{
$crate::system::SystemReg
{
$(schema: $schema,)?
$(init: $init.into(),)?
$(pause: $pause.into(),)?
$(play: $play.into(),)?
$(tick: $tick.into(),)?
$(properties:
{
let mut props = std::collections::HashMap::new();
$(
props.insert(stringify!($fn_name), $func.into());
)*
props
},)?
..$crate::system::SystemReg::default()
}
}
}
#[derive(Serialize, Clone)]
pub struct SystemReg
{
pub schema: HashMap<&'static str, AframeProperty>,
#[serde(skip)] pub init: JsValue,
#[serde(skip)] pub pause: JsValue,
#[serde(skip)] pub play: JsValue,
#[serde(skip)] pub tick: JsValue,
#[serde(skip)] pub properties: HashMap<&'static str, JsValue>
}
impl Default for SystemReg
{
fn default() -> Self
{
let empty_fn: JsValue = js_sys::Function::default().into();
Self
{
schema: HashMap::new(),
init: empty_fn.clone(),
pause: empty_fn.clone(),
play: empty_fn.clone(),
tick: empty_fn,
properties: HashMap::new()
}
}
}
impl From<&SystemReg> for JsValue
{
fn from(sysr: &SystemReg) -> Self
{
let js_value = serde_wasm_bindgen::to_value(sysr).expect("Failed to convert SystemReg into JsObject");
define_property(js_value.unchecked_ref(), "init", (sysr.init).unchecked_ref());
define_property(js_value.unchecked_ref(), "pause", (sysr.pause).unchecked_ref());
define_property(js_value.unchecked_ref(), "play", (sysr.play).unchecked_ref());
define_property(js_value.unchecked_ref(), "tick", (sysr.tick).unchecked_ref());
for (k, v) in sysr.properties.iter()
{
define_property(js_value.unchecked_ref(), k, v.unchecked_ref());
}
js_value
}
}
impl SystemReg
{
pub unsafe fn register(self, name: &str)
{
registerSystem(name, (&self).into());
}
}