pub mod color;
pub mod htmlify;
pub use ::htmlify::*;
pub use const_default::ConstDefault;
use js_sys::{Object, Reflect};
use wasm_bindgen::{JsCast, JsValue};
use std::{borrow::Cow, fmt::Display};
use serde::{Serialize, Serializer};
pub use js_sys::Function;
#[macro_export]
macro_rules! js
{
($($arg:ident),* =>> $($tt:tt)*) =>
{
$crate::utils::Function::new_with_args(stringify!($($arg), *), stringify!($($tt)*))
};
($($tt:tt)*) =>
{
$crate::utils::Function::new_no_args(stringify!($($tt)*))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct Vector2
{
pub x: f64,
pub y: f64
}
impl ConstDefault for Vector2
{
const DEFAULT: Vector2 = Vector2 { x: 0.0, y: 0.0 };
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct Vector3
{
pub x: f64,
pub y: f64,
pub z: f64
}
impl ConstDefault for Vector3
{
const DEFAULT: Vector3 = Vector3 { x: 0.0, y: 0.0, z: 0.0 };
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
pub struct Vector4
{
pub x: f64,
pub y: f64,
pub z: f64,
pub w: f64
}
impl ConstDefault for Vector4
{
const DEFAULT: Vector4 = Vector4 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
}
impl Display for Vector2
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result
{
write!(f, "{} {}", self.x, self.y)
}
}
impl Display for Vector3
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result
{
write!(f, "{} {} {}", self.x, self.y, self.z)
}
}
impl Display for Vector4
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result
{
write!(f, "{} {} {} {}", self.x, self.y, self.z, self.w)
}
}
pub(crate) fn define_property(src: &Object, name: &str, value: &Object)
{
if src.unchecked_ref::<JsValue>() != &JsValue::UNDEFINED
{
#[allow(unused_unsafe)]
unsafe
{
Reflect::set(src, &JsValue::from_str(name), value).expect(&format!("Failed to define property on: {}", name));
}
}
}
#[derive(Serialize, Clone)]
pub struct AframeProperty
{
#[serde(rename = "type")]
component_type: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
default: Option<AframeVal>
}
impl AframeProperty
{
pub fn array(default: Option<Vec<Cow<'static, str>>>) -> Self
{
Self { component_type: "array", default: default.map(AframeVal::Array) }
}
pub fn asset(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "asset", default: default.map(AframeVal::Str) }
}
pub fn audio(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "audio", default: default.map(AframeVal::Str) }
}
pub fn boolean(default: Option<bool>) -> Self
{
Self { component_type: "boolean", default: default.map(AframeVal::Bool) }
}
pub fn color(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "color", default: default.map(AframeVal::Str) }
}
pub fn int(default: Option<i64>) -> Self
{
Self { component_type: "int", default: default.map(AframeVal::Int) }
}
pub fn map(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "map", default: default.map(AframeVal::Str) }
}
pub fn model(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "model", default: default.map(AframeVal::Str) }
}
pub fn number(default: Option<f32>) -> Self
{
Self { component_type: "number", default: default.map(AframeVal::Float) }
}
pub fn selector(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "selector", default: default.map(AframeVal::Str) }
}
pub fn selector_all(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "selectorAll", default: default.map(AframeVal::Str) }
}
pub fn string(default: Option<Cow<'static, str>>) -> Self
{
Self { component_type: "string", default: default.map(AframeVal::Str) }
}
pub fn vec2(default: Option<Vector2>) -> Self
{
Self { component_type: "vec2", default: default.map(AframeVal::Vec2) }
}
pub fn vec3(default: Option<Vector3>) -> Self
{
Self { component_type: "vec3", default: default.map(AframeVal::Vec3) }
}
pub fn vec4(default: Option<Vector4>) -> Self
{
Self { component_type: "vec4", default: default.map(AframeVal::Vec4) }
}
}
#[derive(Clone)]
pub enum AframeVal
{
Array(Vec<Cow<'static, str>>),
Bool(bool),
Int(i64),
Str(Cow<'static, str>),
Float(f32),
Vec2(Vector2),
Vec3(Vector3),
Vec4(Vector4)
}
impl Serialize for AframeVal
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>
{
match self
{
Self::Str(s) => s.serialize(serializer),
Self::Float(f) => f.serialize(serializer),
Self::Vec2(vec) => vec.serialize(serializer),
Self::Vec3(vec) => vec.serialize(serializer),
Self::Vec4(vec) => vec.serialize(serializer),
Self::Array(arr) => arr.serialize(serializer),
Self::Bool(b) => b.serialize(serializer),
Self::Int(i) => i.serialize(serializer),
}
}
}