summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/assemblage.rs6
-rw-r--r--src/assemblages.rs50
-rw-r--r--src/componentparameter.rs2
-rw-r--r--src/encyclopedia.rs4
-rw-r--r--src/main.rs34
-rw-r--r--src/oldassemblage.rs63
-rw-r--r--src/resources.rs5
-rw-r--r--src/room.rs32
-rw-r--r--src/systems/controlinput.rs31
-rw-r--r--src/template.rs8
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())
+ }
}