diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compwrapper.rs | 50 | ||||
| -rw-r--r-- | src/main.rs | 23 |
2 files changed, 46 insertions, 27 deletions
diff --git a/src/compwrapper.rs b/src/compwrapper.rs index 4a861db..06c11cf 100644 --- a/src/compwrapper.rs +++ b/src/compwrapper.rs @@ -17,7 +17,7 @@ pub enum CompWrapper{ impl CompWrapper { - pub fn build<'a>(&self, builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a> { + 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), @@ -76,7 +76,7 @@ impl ComponentType { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum Parameter { String(String), Int(i64), @@ -187,12 +187,12 @@ impl Template { let paramtype: ParamType = comptype.parameters().remove(key.as_str()).ok_or("unknown parameter name")?; let paramvalue = value.get(1).ok_or("index 0 not in component parameter")?; let param = match value.get(0).ok_or("index 0 not in component parameter")?.as_str().ok_or("compparam type not a string")? { - "C" => Ok(CompParam::Constant( + "C" | "const" => Ok(CompParam::Constant( Parameter::from_typed_json(paramtype, paramvalue).ok_or("failed to parse parameter constant")? )), - "A" => { + "A" | "arg" => { let argname = paramvalue.as_str().ok_or("argument parameter not a string")?.to_string(); - let arg = arguments.iter().find(|(a, t, d)| a == &argname).ok_or("unknown argument name")?; + let arg = arguments.iter().find(|(a, _t, _d)| a == &argname).ok_or("unknown argument name")?; if arg.1 == paramtype { Ok(CompParam::Argument(argname)) } else { @@ -210,28 +210,42 @@ impl Template { components }) } + + fn prepare_arguments(&self, args: Vec<Parameter>, kwargs: HashMap<String, Parameter>) -> Result<HashMap<&str, Parameter>, &str> { + let mut arguments: HashMap<&str, Parameter> = HashMap::new(); + for (idx, (name, typ, def)) in self.arguments.iter().enumerate() { + let value: Option<Parameter> = { + if let Some(val) = kwargs.get(name) { + Some((*val).clone()) + } else if let Some(val) = args.get(idx) { + Some((*val).clone()) + } else if let Some(val) = def { + Some((*val).clone()) + } else { + None + } + }; + let param = value.ok_or("argument has no value")?; + if param.paramtype() != *typ { + return Err("argument has incorrect type"); + } + arguments.insert(name, param); + } + Ok(arguments) + } pub fn instantiate(&self, args: Vec<Parameter>, kwargs: HashMap<String, Parameter>) -> Result<Vec<CompWrapper>, &str>{ let mut components: Vec<CompWrapper> = Vec::new(); + let arguments = self.prepare_arguments(args, kwargs)?; for (comptype, compparams) in &self.components { let mut compargs: HashMap<&str, &Parameter> = HashMap::new(); for (name, param) in compparams { match param { CompParam::Constant(val) => {compargs.insert(name.as_str(), &val); Ok(())}, CompParam::Argument(argname) => { - if let Some(argval) = kwargs.get(argname.as_str()) { - compargs.insert(name.as_str(), argval); - Ok(()) - } else if let Some(idx) = self.arguments.iter().position(|(x, t, d)| x == name){ - if idx < args.len() { - compargs.insert(name.as_str(), &args[idx]); - Ok(()) - } else { - Err("positional argument out of range") - } - } else { - Err("can't find parameter value") - } + let value = arguments.get(argname.as_str()).ok_or("argument not found")?; + compargs.insert(name.as_str(), value); + Ok(()) } }?; } diff --git a/src/main.rs b/src/main.rs index 524d70f..cff91a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::time::Duration; use std::path::Path; use std::collections::HashMap; +use serde_json::json; mod server; mod gameserver; @@ -63,16 +64,16 @@ fn main() { fn gen_room<'a, 'b>(width: i32, height: i32) -> Room<'a, 'b> { let mut room = Room::new((width, height)); - let wall = Template{ - arguments: Vec::new(), - components: vec![ - (ComponentType::from_str("Blocking").unwrap(), HashMap::new()), - (ComponentType::from_str("Visible").unwrap(), hashmap!( - "sprite".to_string() => CompParam::Constant(Parameter::String("wall".to_string())), - "height".to_string() => CompParam::Constant(Parameter::Float(1.0)) - )) + let wall = Template::from_json(json!({ + "arguments": [], + "components": [ + ["Blocking", {}], + ["Visible", { + "sprite": ["const", "wall"], + "height": ["const", 1.0] + }] ] - }.instantiate(Vec::new(), HashMap::new()).unwrap(); + })).unwrap().instantiate(Vec::new(), HashMap::new()).unwrap(); for x in 0..width { room.add_complist(&wall, (x, 0)); room.add_complist(&wall, (x, height - 1)); @@ -89,3 +90,7 @@ fn gen_room<'a, 'b>(width: i32, height: i32) -> Room<'a, 'b> { room } +// fn default_assemblages() -> Hashmap<&str, Template> { +// hashmap!( +// + |
