diff options
| -rw-r--r-- | src/assemblage.rs | 6 | ||||
| -rw-r--r-- | src/assemblages.rs | 50 | ||||
| -rw-r--r-- | src/componentparameter.rs | 2 | ||||
| -rw-r--r-- | src/encyclopedia.rs | 4 | ||||
| -rw-r--r-- | src/main.rs | 34 | ||||
| -rw-r--r-- | src/oldassemblage.rs | 63 | ||||
| -rw-r--r-- | src/resources.rs | 5 | ||||
| -rw-r--r-- | src/room.rs | 32 | ||||
| -rw-r--r-- | src/systems/controlinput.rs | 31 | ||||
| -rw-r--r-- | src/template.rs | 8 |
10 files changed, 69 insertions, 166 deletions
diff --git a/src/assemblage.rs b/src/assemblage.rs index 1e7eb44..28bf26f 100644 --- a/src/assemblage.rs +++ b/src/assemblage.rs @@ -5,7 +5,7 @@ use super::componentparameter::ComponentParameter; use super::parameter::{Parameter, ParameterType}; use super::componentwrapper::{ComponentWrapper, ComponentType}; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Assemblage { pub arguments: Vec<(String, ParameterType, Option<Parameter>)>, pub components: Vec<(ComponentType, HashMap<String, ComponentParameter>)> @@ -69,7 +69,7 @@ impl Assemblage { Ok(assemblage) } - fn prepare_arguments(&self, args: &Vec<Parameter>, kwargs: &HashMap<String, Parameter>) -> Result<HashMap<&str, Parameter>, &str> { + fn prepare_arguments(&self, args: &Vec<Parameter>, kwargs: &HashMap<String, Parameter>) -> Result<HashMap<&str, Parameter>, &'static str> { let mut arguments: HashMap<&str, Parameter> = HashMap::new(); for (idx, (name, typ, def)) in self.arguments.iter().enumerate() { let value: Option<Parameter> = { @@ -92,7 +92,7 @@ impl Assemblage { Ok(arguments) } - pub fn instantiate(&self, args: &Vec<Parameter>, kwargs: &HashMap<String, Parameter>) -> Result<Vec<ComponentWrapper>, &str>{ + pub fn instantiate(&self, args: &Vec<Parameter>, kwargs: &HashMap<String, Parameter>) -> Result<Vec<ComponentWrapper>, &'static str>{ let mut components: Vec<ComponentWrapper> = Vec::new(); let arguments = self.prepare_arguments(args, kwargs)?; for (comptype, compparams) in &self.components { diff --git a/src/assemblages.rs b/src/assemblages.rs deleted file mode 100644 index e8335f3..0000000 --- a/src/assemblages.rs +++ /dev/null @@ -1,50 +0,0 @@ - -use rand::Rng; -use super::components::{Visible, Blocking, Played}; -use super::assemblage; -use super::oldassemblage::Assemblage; - -assemblage!(Wall {}; Visible{sprite: "wall".to_string(), height: 2.0}, Blocking); - -assemblage!(Grass { sprite : String}; Visible{sprite: sprite.to_string(), height: 0.1}); - -impl Grass { - pub fn new() -> Grass { - Grass { - sprite: ["grass1", "grass2", "grass3", "grass1", "grass2", "grass3", "ground"][rand::thread_rng().gen_range(0,7)].to_string() - } - } -} - - -assemblage!(Player {name: String}; Visible{sprite: "player".to_string(), height: 1.0}, Played::new(name.to_string())); - -impl Player { - pub fn new(name: &str) -> Player { - Player { name: name.to_string()} - } -} - - - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::json; - use super::super::hashmap; - #[test] - fn test_assemblage_from_json() { - let mut p = Player::new("Joe"); - assert_eq!(p.name, "Joe"); - p.init_from_json(vec![json!("Bob"), json!("Mike")], hashmap!()); - assert_eq!(p.name, "Bob"); - p.init_from_json(vec![], hashmap!("sprite".to_string() => json!("stone"))); - assert_eq!(p.name, "Bob"); - p.init_from_json(vec![], hashmap!("name".to_string() => json!("Teddy"))); - assert_eq!(p.name, "Teddy"); - p.init_from_json(vec![json!("Bill")], hashmap!("name".to_string() => json!("Stan"))); - assert_eq!(p.name, "Stan"); - } -} - - diff --git a/src/componentparameter.rs b/src/componentparameter.rs index 491486a..b0d10cf 100644 --- a/src/componentparameter.rs +++ b/src/componentparameter.rs @@ -4,7 +4,7 @@ use rand::Rng; use serde_json::Value; use crate::parameter::{Parameter, ParameterType}; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum ComponentParameter { Constant(Parameter), Argument(String), diff --git a/src/encyclopedia.rs b/src/encyclopedia.rs index 17e9857..19d4297 100644 --- a/src/encyclopedia.rs +++ b/src/encyclopedia.rs @@ -5,7 +5,7 @@ use crate::assemblage::Assemblage; use crate::componentwrapper::ComponentWrapper; use crate::template::Template; -#[derive(Default)] +#[derive(Default, Clone)] pub struct Encyclopedia { items: HashMap<String, Assemblage> } @@ -32,7 +32,7 @@ impl Encyclopedia { Ok(()) } - pub fn construct(&self, template: &Template) -> Result<Vec<ComponentWrapper>, &str> { + pub fn construct(&self, template: &Template) -> Result<Vec<ComponentWrapper>, &'static str> { let assemblage = self.items.get(&template.name).ok_or("unknown assemblage name")?; assemblage.instantiate(&template.args, &template.kwargs) } diff --git a/src/main.rs b/src/main.rs index 30ef0a4..1f1d217 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,13 +11,11 @@ mod gameserver; mod room; mod util; mod controls; -mod assemblages; mod components; mod resources; mod systems; mod worldmessages; mod pos; -mod oldassemblage; mod componentwrapper; mod parameter; mod assemblage; @@ -33,6 +31,7 @@ use self::room::Room; use self::util::ToJson; use self::encyclopedia::Encyclopedia; use self::template::Template; +use self::pos::Pos; @@ -66,22 +65,21 @@ fn main() { } fn gen_room<'a, 'b>(width: i32, height: i32) -> Room<'a, 'b> { - let mut room = Room::new((width, height)); let assemblages = default_assemblages(); - let wall = assemblages.construct(&Template::empty("wall")).unwrap(); -// let grass = &assemblages["grass"]; + let mut room = Room::new(assemblages.clone(), (width, height)); + let wall = &Template::empty("wall"); for x in 0..width { - room.add_complist(&wall, (x, 0)); - room.add_complist(&wall, (x, height - 1)); + room.add_entity(&wall, Pos::new(x, 0)).unwrap(); + room.add_entity(&wall, Pos::new(x, height - 1)).unwrap(); } for y in 1..height-1 { - room.add_complist(&wall, (0, y)); - room.add_complist(&wall, (width - 1, y)); + room.add_entity(&wall, Pos::new(0, y)).unwrap(); + room.add_entity(&wall, Pos::new(width - 1, y)).unwrap(); } for x in 1..width-1 { for y in 1..height-1 { - let grass = assemblages.construct(&Template::empty("grass")).unwrap(); - room.add_complist(&grass, (x, y)); //&grass.instantiate(&Vec::new(), &HashMap::new()).unwrap(), (x, y)); + let grass = &Template::empty("grass"); + room.add_entity(&grass, Pos::new(x, y)).unwrap(); } } room @@ -95,7 +93,7 @@ fn default_assemblages() -> Encyclopedia { ["Blocking", {}], ["Visible", { "sprite": ["string", "wall"], - "height": ["float", 1.0] + "height": ["float", 2.0] }] ] }, @@ -115,6 +113,18 @@ fn default_assemblages() -> Encyclopedia { "height": ["float", 0.1] }] ] + }, + "player": { + "arguments": [["name", "string", null]], + "components": [ + ["Visible", { + "sprite": ["string", "player"], + "height": ["float", 1.0] + }], + ["Player", { + "name": ["arg", "name"] + }] + ] } })).unwrap() } diff --git a/src/oldassemblage.rs b/src/oldassemblage.rs deleted file mode 100644 index a81ce82..0000000 --- a/src/oldassemblage.rs +++ /dev/null @@ -1,63 +0,0 @@ - - -use std::any::Any; - - -#[macro_export] -macro_rules! assemblage { - ($name:ident { $($arg:ident : $argt:ident ),* } ; $( $comp:expr ),* ) => { - #[derive(Debug, Clone, Default)] - pub struct $name {$( - pub $arg : $argt - )* } - impl Assemblage for $name { - fn build<'a>(&self, mut builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a>{ - $( - let $arg = &self.$arg; - )* - $( - builder = specs::Builder::with(builder, $comp); - )* - builder - } - - #[allow(unused_variables, unused_mut)] - fn init_from_json(&mut self, mut args: Vec<serde_json::Value>, kwargs: std::collections::HashMap<String, serde_json::Value>) { - $( - if args.len() > 0 { - let val = args.remove(0); - if let Some(actual_val) = super::unpack_json!($argt, val) { - self.$arg = actual_val; - } - } - )* - $( - if let Some(val) = kwargs.get(stringify!($arg)) { - if let Some(actual_val) = super::unpack_json!($argt, val) { - self.$arg = actual_val; - } - } - )* - } - } - } -} - -#[macro_export] -macro_rules! unpack_json { - (String, $val: ident) => { - if let Some(txt) = $val.as_str(){ - Some(txt.to_string()) - } else { - None - } - } -} - - -pub trait Assemblage: Send + Sync + Any { - fn build<'a>(&self, builder: specs::EntityBuilder<'a>) -> specs::EntityBuilder<'a>; - fn init_from_json(&mut self, args: Vec<serde_json::Value>, kwargs: std::collections::HashMap<String, serde_json::Value>); -} - - diff --git a/src/resources.rs b/src/resources.rs index 1fc4c17..b1c193c 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -4,8 +4,9 @@ use specs::Entity; use super::pos::Pos; use super::controls::Action; -use super::oldassemblage::Assemblage; +// use super::oldassemblage::Assemblage; use super::worldmessages::WorldMessage; +use super::template::Template; #[derive(Default)] @@ -31,5 +32,5 @@ pub struct Floor { #[derive(Default)] pub struct NewEntities { - pub assemblages: Vec<(Pos, Box<dyn Assemblage>)> + pub templates: Vec<(Pos, Template)> } diff --git a/src/room.rs b/src/room.rs index dc2c683..a953a04 100644 --- a/src/room.rs +++ b/src/room.rs @@ -13,7 +13,6 @@ use specs::{ use super::controls::Action; use super::pos::Pos; use super::components::Position; -use super::oldassemblage::Assemblage as OldAssemblage; use super::worldmessages::WorldMessage; use super::resources::{ Size, @@ -29,17 +28,20 @@ use super::systems::{ view::View }; use super::componentwrapper::ComponentWrapper; +use crate::encyclopedia::Encyclopedia; +use crate::template::Template; pub struct Room<'a, 'b> { world: World, - dispatcher: Dispatcher<'a, 'b> + dispatcher: Dispatcher<'a, 'b>, + encyclopedia: Encyclopedia } impl <'a, 'b>Room<'a, 'b> { - pub fn new(size: (i32, i32)) -> Room<'a, 'b> { + pub fn new(encyclopedia: Encyclopedia, size: (i32, i32)) -> Room<'a, 'b> { let (width, height) = size; let mut world = World::new(); world.insert(Size{width, height}); @@ -58,7 +60,8 @@ impl <'a, 'b>Room<'a, 'b> { Room { world, - dispatcher + dispatcher, + encyclopedia } } @@ -68,10 +71,12 @@ impl <'a, 'b>Room<'a, 'b> { pub fn update(&mut self) { self.dispatcher.dispatch(&mut self.world); - let assemblages = self.world.remove::<NewEntities>().unwrap_or(NewEntities{assemblages: Vec::new()}).assemblages; - self.world.insert(NewEntities{assemblages: Vec::new()}); - for (pos, assemblage) in assemblages{ - assemblage.build(self.world.create_entity()).with(Position::new(pos)).build(); + let templates = self.world.remove::<NewEntities>().unwrap_or(NewEntities::default()).templates; + self.world.insert(NewEntities::default()); + for (pos, template) in templates{ + if let Err(msg) = self.add_entity(&template, pos){ + println!("failed to add entity {:?}: {}", template, msg); + } } self.world.maintain(); } @@ -80,16 +85,17 @@ impl <'a, 'b>Room<'a, 'b> { self.world.fetch_mut::<Input>().actions = actions; } - pub fn add_obj(&mut self, template: &dyn OldAssemblage, (x, y): (i32, i32)) -> Entity { - template.build(self.world.create_entity()).with(Position::new(Pos{x, y})).build() + pub fn add_entity(&mut self, template: &Template, pos: Pos) -> Result<Entity, &'static str> { + let preentity = self.encyclopedia.construct(template)?; + Ok(self.add_complist(&preentity, pos)) } - - pub fn add_complist(&mut self, template: &Vec<ComponentWrapper>, (x, y): (i32, i32)) -> Entity{ +// + pub fn add_complist(&mut self, template: &Vec<ComponentWrapper>, pos: Pos) -> Entity{ let mut builder = self.world.create_entity(); for comp in template { builder = comp.build(builder); } - builder.with(Position::new(Pos{x, y})).build() + builder.with(Position::new(pos)).build() } } diff --git a/src/systems/controlinput.rs b/src/systems/controlinput.rs index 2de9d29..e5f0151 100644 --- a/src/systems/controlinput.rs +++ b/src/systems/controlinput.rs @@ -12,24 +12,14 @@ use specs::{ }; use crate::pos::Pos; +use crate::components::{Controller, Played}; +use crate::controls::{Control, Action}; +use crate::resources::{Input, NewEntities}; +use crate::hashmap; +use crate::template::Template; +use crate::parameter::Parameter; -use crate::components::{ - Controller, - Played -}; - -use crate::controls::{ - Control, - Action -}; - -use crate::resources::{ - Input, - NewEntities -}; - - -use crate::assemblages::Player; +// use crate::assemblages::Player; pub struct ControlInput; @@ -40,7 +30,12 @@ impl <'a> System<'a> for ControlInput { let mut leaving = HashSet::new(); for action in &input.actions { match action { - Action::Join(name) => {new.assemblages.push((Pos{x:10, y:10}, Box::new(Player::new(&name))));} + Action::Join(name) => { + new.templates.push(( + Pos{x:10, y:10}, + Template::new("player", hashmap!("name".to_string() => Parameter::String(name.to_string()))) + )); + } Action::Leave(name) => {leaving.insert(name);} Action::Input(name, control) => {playercontrols.insert(name, control.clone());} } diff --git a/src/template.rs b/src/template.rs index 51bba8b..b6b34cb 100644 --- a/src/template.rs +++ b/src/template.rs @@ -13,11 +13,15 @@ pub struct Template { impl Template { - pub fn empty(name: &str) -> Self { + pub fn new(name: &str, kwargs: HashMap<String, Parameter>) -> Self { Self { name: name.to_string(), args: Vec::new(), - kwargs: HashMap::new() + kwargs } } + + pub fn empty(name: &str) -> Self { + Self::new(name, HashMap::new()) + } } |
