From ddf7c12c4927d8696c641d9f72b1fef94e046f77 Mon Sep 17 00:00:00 2001 From: troido Date: Fri, 25 Sep 2020 16:19:05 +0200 Subject: encyclopedia now using serde serialisation too --- src/assemblage.rs | 8 ++- src/encyclopedia.rs | 160 ++++++++++++++++++++++------------------------------ src/worldloader.rs | 5 +- 3 files changed, 76 insertions(+), 97 deletions(-) diff --git a/src/assemblage.rs b/src/assemblage.rs index f157117..80c10ab 100644 --- a/src/assemblage.rs +++ b/src/assemblage.rs @@ -8,8 +8,7 @@ use crate::{ components::Serialise, Template, Result as AnyResult, - aerr, - fromtoparameter::FromToParameter + aerr }; type ArgumentDef = (String, ParameterType, Option); @@ -81,12 +80,15 @@ impl Assemblage { } } +#[macro_export] macro_rules! compmap { {$($name: ident: $val: expr),*} => {{ + #[allow(unused_imports)] + use crate::fromtoparameter::FromToParameter; #[allow(unused_mut)] let mut h = std::collections::HashMap::new(); $( - h.insert(stringify!($name).to_string(), ParameterExpression::Constant($val.to_parameter())); + h.insert(stringify!($name).to_string(), crate::parameterexpression::ParameterExpression::Constant($val.to_parameter())); )* h }} diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs index 72cc483..16d26a8 100644 --- a/src/encyclopedia.rs +++ b/src/encyclopedia.rs @@ -1,20 +1,20 @@ use std::collections::HashMap; -use serde_json::{Value, json}; -use serde::Deserialize; +use serde::{de, Deserialize, Serialize, Deserializer}; use crate::{ assemblage::Assemblage, componentwrapper::PreEntity, Template, template::EntityType, - Result, + Result as AnyResult, aerr, ItemId, item::Item, item::ItemAction, - PResult, - perr, - parameter::Parameter + parameter::Parameter, + Sprite, + compmap, + componentwrapper::ComponentType }; #[derive(Default, Clone)] @@ -25,97 +25,14 @@ pub struct Encyclopedia { impl Encyclopedia { - pub fn from_json(val: Value) -> PResult { - let mut assemblages = - val - .get("assemblages") - .ok_or(perr!("no assemblages in encyclopedia json"))? - .as_object() - .ok_or(perr!("encyclopedia assemblages not a json object"))? - .into_iter() - .map(|(k, v)| Ok((EntityType(k.clone()), Assemblage::deserialize(v).map_err(|e| perr!("invalid assemblage {:?}: {}", v, e))?))) - .collect::>>()?; - let items = - val - .get("items") - .unwrap_or(&json!({})) - .as_object() - .ok_or(perr!("encyclopedia items not a json object"))? - .into_iter() - .map(|(k, v)| { - let id = ItemId(k.clone()); - let sprite = - if let Some(sprite) = v.get("sprite") { - sprite.as_str().ok_or(perr!("item sprite not a string: {:?}", v))? - } else { - k - }; - let name = - if let Some(name) = v.get("name") { - name.as_str().ok_or(perr!("item name not a string: {:?}", v))?.to_string() - } else { - k.to_string() - }; - let item = Item { - name: name.clone(), - ent: - if let Some(ent) = v.get("entity") { - Template::deserialize(ent).map_err(|e| perr!("template json error deserializing {:?} {:?}", ent, e))? - } else { - let enttyp = EntityType(k.clone()); - assemblages.insert(enttyp.clone(), Assemblage::deserialize(&json!({ - "height": 0.3, - "sprite": sprite, - "name": name, - "item": k - })).map_err(|e| perr!("invalid assemblage {:?}: {}", v, e))?); - Template::from_entity_type(enttyp) - }, - action: - if let Some(action) = v.get("action") { - ItemAction::deserialize(action).map_err(|e| perr!("failed to parse ItemAction {:?} {:?}", v, e))? - } else { - ItemAction::None - } - }; - Ok((id, item)) - }) - .collect::>>()?; - for (name, v) in - val - .get("templates") - .unwrap_or(&json!({})) - .as_object().ok_or(perr!("templates not a json dict: {:?}", val.get("templates")))? - .iter() { - let enttype = EntityType(v - .get(0).ok_or(perr!("index 0 not in subtitution template"))? - .as_str().ok_or(perr!("subtitution origin name not a string"))? - .to_string()); - let values = v.get(1).ok_or(perr!("index 0 not in subtitution template"))?; - let mut assemblage = assemblages.get(&enttype).ok_or(perr!("template name '{:?}' does not point to not an assemblage", enttype))?.clone(); - for arg in assemblage.arguments.iter_mut() { - if let Some(x) = values.get(&arg.0) { - let param = Parameter::from_typed_json(arg.1, x)?; - arg.2 = Some(param); - } - } - assemblages.insert(EntityType(name.to_string()), assemblage); - } - - Ok(Encyclopedia{ - assemblages, - items - }) - } - - pub fn validate(&self) -> Result<()> { + pub fn validate(&self) -> AnyResult<()> { for assemblage in self.assemblages.values() { assemblage.validate()?; } Ok(()) } - pub fn construct(&self, template: &Template) -> Result { + pub fn construct(&self, template: &Template) -> AnyResult { let assemblage = self.assemblages .get(&template.name) .ok_or(aerr!("unknown assemblage name: '{:?}' in {:?}", template.name, template))?; @@ -133,3 +50,64 @@ impl Encyclopedia { } } + +impl<'de> Deserialize<'de> for Encyclopedia { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> { + let EncyclopediaSave{mut assemblages, items, templates} = EncyclopediaSave::deserialize(deserializer)?; + let mut itemdefs = HashMap::new(); + for (id, item) in items.into_iter(){ + let sprite = item.sprite.unwrap_or(Sprite(id.clone())); + let name = item.name.unwrap_or(id.clone()); + let ent = item.entity.unwrap_or_else(||{ + let enttyp = EntityType(id.clone()); + assemblages.insert(enttyp.clone(), Assemblage { + arguments: Vec::new(), + save: true, + extract: Vec::new(), + components: vec![ + (ComponentType::Visible, compmap!{height: 0.3_f64, sprite: sprite.0, name: name.clone()}), + (ComponentType::Item, compmap!{item: id.clone()}) + ] + }); + Template::from_entity_type(enttyp) + }); + itemdefs.insert(ItemId(id), Item{ + ent, + name, + action: item.action.unwrap_or(ItemAction::None) + }); + } + for (templatename, (baseent, mut args)) in templates { + let mut assemblage = assemblages.get(&baseent).ok_or(de::Error::custom(format!("template name '{:?}' does not point to not an assemblage", baseent)))?.clone(); + for arg in assemblage.arguments.iter_mut() { + if let Some(param) = args.remove(&arg.0) { + // todo: verify argument type + arg.2 = Some(param); + } + } + assemblages.insert(templatename, assemblage); + } + + Ok(Encyclopedia{ + assemblages, + items: itemdefs + }) + } +} +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +struct ItemSave { + sprite: Option, + name: Option, + entity: Option