summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compwrapper.rs50
-rw-r--r--src/main.rs23
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!(
+//
+