From 7dfc7956a7c2df9a1df3ea0b32e0c3d2036fa3ce Mon Sep 17 00:00:00 2001 From: troido Date: Sat, 8 Feb 2020 01:29:06 +0100 Subject: new macro DSL for making component wrappers --- src/componentwrapper.rs | 122 +++++++++++++++++++++++++++--------------------- src/parameter.rs | 6 +-- 2 files changed, 72 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/componentwrapper.rs b/src/componentwrapper.rs index 311becf..8bf8552 100644 --- a/src/componentwrapper.rs +++ b/src/componentwrapper.rs @@ -7,69 +7,85 @@ use crate::hashmap; use crate::parameter::{Parameter, ParameterType}; -#[derive(Clone)] -pub enum ComponentWrapper{ - Visible(Visible), - Blocking(Blocking), - Player(Player), - Floor(Floor) -} -impl ComponentWrapper { - - pub fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a> { - match self.clone() { - Self::Visible(c) => builder.with(c), - Self::Blocking(c) => builder.with(c), - Self::Player(c) => builder.with(c), - Self::Floor(c) => builder.with(c) - } +macro_rules! components { + ($($comp: ident [$($paramname: ident : $paramtype: ident),*] $paramlist: ident {$creation: expr});*) => { + + #[derive(Clone)] + pub enum ComponentWrapper{ + $( + $comp($comp), + )* } - pub fn load_component(comptype: ComponentType, mut parameters: HashMap<&str, Parameter>) -> Option { - match comptype { - ComponentType::Visible => Some(Self::Visible(Visible{ - sprite: parameters.remove("sprite")?.as_str()?.to_string(), - height: parameters.remove("height")?.as_f64()? - })), - ComponentType::Blocking => Some(Self::Blocking(Blocking)), - ComponentType::Player => Some(Self::Player(Player::new( - parameters.remove("name")?.as_str()?.to_string() - ))), - ComponentType::Floor => Some(Self::Floor(Floor)) + impl ComponentWrapper { + + pub fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a> { + match self.clone() { + $( + Self::$comp(c) => builder.with(c), + )* + } + } + + pub fn load_component(comptype: ComponentType, mut parameters_: HashMap<&str, Parameter>) -> Option { + + match comptype { + $( + ComponentType::$comp => Some(Self::$comp({ + let mut $paramlist = parameters_; + $creation + })), + )* + } } } -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum ComponentType { - Visible, - Blocking, - Player, - Floor -} - -impl ComponentType { - pub fn from_str(typename: &str) -> Option{ - match typename { - "Visible" => Some(ComponentType::Visible), - "Blocking" => Some(ComponentType::Blocking), - "Player" => Some(ComponentType::Player), - "Floor" => Some(ComponentType::Floor), - _ => None - } + #[derive(Debug, PartialEq, Eq, Clone, Copy)] + pub enum ComponentType { + $( + $comp, + )* } - pub fn parameters(&self) -> HashMap<&str, ParameterType> { - match self { - ComponentType::Visible => hashmap!("sprite" => ParameterType::String, "height" => ParameterType::Float), - ComponentType::Blocking => HashMap::new(), - ComponentType::Floor => HashMap::new(), - ComponentType::Player => hashmap!("name" => ParameterType::String) + impl ComponentType { + + pub fn from_str(typename: &str) -> Option{ + match typename { + $( + stringify!($comp) => Some(Self::$comp), + )* + _ => None + } + } + + pub fn parameters(&self) -> HashMap<&str, ParameterType> { + match self { + $( + Self::$comp => { + let mut h = HashMap::new(); + $( + h.insert(stringify!($paramname), ParameterType::$paramtype); + )* + h + }, + )* + } } } -} +}} + +components!( + Visible [sprite: String, height: Float] parameters { + Visible { + sprite: parameters.remove("sprite")?.as_string()?, + height: parameters.remove("height")?.as_f64()? + } + }; + Blocking [] p {Blocking}; + Floor [] p {Floor}; + Player [name: String] parameters {Player::new(parameters.remove("name")?.as_string()?)} +); diff --git a/src/parameter.rs b/src/parameter.rs index 8e45b9c..6d15e93 100644 --- a/src/parameter.rs +++ b/src/parameter.rs @@ -54,9 +54,9 @@ impl Parameter { } } -// pub fn as_string(&self) -> Option { -// Some(self.as_str()?.to_string()) -// } + pub fn as_string(&self) -> Option { + Some(self.as_str()?.to_string()) + } pub fn as_i64(&self) -> Option { if let Self::Int(num) = self { -- cgit