diff --git a/src/gameplay_modes.rs b/src/gameplay_modes.rs index ec07897..e9ea2ca 100644 --- a/src/gameplay_modes.rs +++ b/src/gameplay_modes.rs @@ -1,6 +1,7 @@ use std::collections::{HashSet,HashMap}; use crate::model::ModelId; use crate::gameplay_style; +use crate::updatable::Updatable; #[derive(Clone)] pub struct StageElement{ @@ -100,6 +101,18 @@ impl Stage{ self.unordered_checkpoints.contains(&model_id) } } +#[derive(Default)] +pub struct StageUpdate{ + //other behaviour models of this stage can have + ordered_checkpoints:HashMap, + unordered_checkpoints:HashSet, +} +impl Updatable for Stage{ + fn update(&mut self,update:StageUpdate){ + self.ordered_checkpoints.extend(update.ordered_checkpoints); + self.unordered_checkpoints.extend(update.unordered_checkpoints); + } +} #[derive(Clone,Copy,Hash,Eq,PartialEq)] pub enum Zone{ @@ -186,6 +199,47 @@ impl Mode{ } } } +//this would be nice as a macro +#[derive(Default)] +pub struct ModeUpdate{ + zones:HashMap, + stages:HashMap, + //mutually exlusive stage element behaviour + elements:HashMap, +} +impl Updatable for Mode{ + fn update(&mut self,update:ModeUpdate){ + self.zones.extend(update.zones); + for (stage,stage_update) in update.stages{ + if let Some(stage)=self.stages.get_mut(stage.0 as usize){ + stage.update(stage_update); + } + } + self.elements.extend(update.elements); + } +} +impl ModeUpdate{ + pub fn zone(model_id:ModelId,zone:Zone)->Self{ + let mut mu=Self::default(); + mu.zones.insert(model_id,zone); + mu + } + pub fn stage(stage_id:StageId,stage_update:StageUpdate)->Self{ + let mut mu=Self::default(); + mu.stages.insert(stage_id,stage_update); + mu + } + pub fn element(model_id:ModelId,element:StageElement)->Self{ + let mut mu=Self::default(); + mu.elements.insert(model_id,element); + mu + } + pub fn map_stage_element_idsStageId>(&mut self,f:F){ + for (_,stage_element) in self.elements.iter_mut(){ + stage_element.stage_id=f(stage_element.stage_id); + } + } +} #[derive(Default,Clone)] pub struct Modes{ @@ -204,3 +258,15 @@ impl Modes{ self.modes.get(mode.0 as usize) } } +pub struct ModesUpdate{ + modes:HashMap, +} +impl Updatable for Modes{ + fn update(&mut self,update:ModesUpdate){ + for (mode,mode_update) in update.modes{ + if let Some(mode)=self.modes.get_mut(mode.0 as usize){ + mode.update(mode_update); + } + } + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 78b4e46..36a0933 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ pub mod aabb; pub mod model; pub mod zeroes; pub mod integer; +pub mod updatable; pub mod instruction; pub mod gameplay_attributes; pub mod gameplay_modes; diff --git a/src/updatable.rs b/src/updatable.rs new file mode 100644 index 0000000..13b6dd2 --- /dev/null +++ b/src/updatable.rs @@ -0,0 +1,56 @@ +pub trait Updatable{ + fn update(&mut self,update:Updater); +} +#[derive(Clone,Copy,Hash,Eq,PartialEq)] +struct InnerId(u32); +#[derive(Clone)] +struct Inner{ + id:InnerId, + enabled:bool, +} +#[derive(Clone,Copy,Hash,Eq,PartialEq)] +struct OuterId(u32); +struct Outer{ + id:OuterId, + inners:std::collections::HashMap, +} + +enum Update{ + Insert(I), + Update(U), + Remove +} + +struct InnerUpdate{ + //#[updatable(Update)] + enabled:Option, +} +struct OuterUpdate{ + //#[updatable(Insert,Update,Remove)] + inners:std::collections::HashMap>, + //#[updatable(Update)] + //inners:std::collections::HashMap, +} +impl Updatable for Inner{ + fn update(&mut self,update:InnerUpdate){ + if let Some(enabled)=update.enabled{ + self.enabled=enabled; + } + } +} +impl Updatable for Outer{ + fn update(&mut self,update:OuterUpdate){ + for (id,up) in update.inners{ + match up{ + Update::Insert(new_inner)=>self.inners.insert(id,new_inner), + Update::Update(inner_update)=>self.inners.get_mut(&id).map(|inner|{ + let old=inner.clone(); + inner.update(inner_update); + old + }), + Update::Remove=>self.inners.remove(&id), + }; + } + } +} +//*/ \ No newline at end of file