summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components.rs10
-rw-r--r--src/systems/makefloor.rs7
-rw-r--r--src/systems/moving.rs10
-rw-r--r--src/systems/remove.rs16
-rw-r--r--src/systems/view.rs110
-rw-r--r--src/worldmessages.rs6
6 files changed, 73 insertions, 86 deletions
diff --git a/src/components.rs b/src/components.rs
index 5bd6ddd..277dd01 100644
--- a/src/components.rs
+++ b/src/components.rs
@@ -13,12 +13,11 @@ use super::pos::Pos;
#[derive(Debug, Clone)]
pub struct Position{
- pub pos: Pos,
- pub prev: Option<Pos>
+ pub pos: Pos
}
impl Position {
pub fn new(pos: Pos) -> Position {
- Position{pos, prev: None}
+ Position{pos}
}
}
@@ -58,12 +57,11 @@ pub struct Moved {
#[derive(Component, Debug, Clone)]
#[storage(HashMapStorage)]
pub struct Player {
- pub name: String,
- pub is_new: bool
+ pub name: String
}
impl Player {
pub fn new(name: String) -> Self {
- Self{name, is_new: true}
+ Self{name}
}
}
diff --git a/src/systems/makefloor.rs b/src/systems/makefloor.rs
index 74e4389..689fcec 100644
--- a/src/systems/makefloor.rs
+++ b/src/systems/makefloor.rs
@@ -36,13 +36,6 @@ impl <'a> System<'a> for MakeFloor {
for (ent, pos, _new) in (&entities, &positions, &new).join() {
ground.cells.entry(pos.pos).or_insert(HashSet::new()).insert(ent);
}
- for (ent, pos, mov) in (&entities, &positions, &moved).join() {
- ground.cells.entry(pos.pos).or_insert(HashSet::new()).insert(ent);
- ground.cells.get_mut(&mov.from).unwrap().remove(&ent);
- }
- for (ent, pos, _removed) in (&entities, &positions, &removed).join() {
- ground.cells.get_mut(&pos.pos).unwrap().remove(&ent);
- }
}
}
diff --git a/src/systems/moving.rs b/src/systems/moving.rs
index 35f73ea..98b0979 100644
--- a/src/systems/moving.rs
+++ b/src/systems/moving.rs
@@ -7,7 +7,8 @@ use specs::{
WriteStorage,
Read,
System,
- Join
+ Join,
+ Write
};
use super::super::pos::Pos;
@@ -39,12 +40,12 @@ impl <'a> System<'a> for Move {
WriteStorage<'a, Position>,
Read<'a, Size>,
ReadStorage<'a, Blocking>,
- Read<'a, Ground>,
+ Write<'a, Ground>,
ReadStorage<'a, Floor>,
WriteStorage<'a, Moved>
);
- fn run(&mut self, (entities, controllers, mut positions, size, blocking, ground, floor, mut moved): Self::SystemData) {
+ fn run(&mut self, (entities, controllers, mut positions, size, blocking, mut ground, floor, mut moved): Self::SystemData) {
{
let mut ents = Vec::new();
for (ent, _moved) in (&*entities, &moved).join() {
@@ -71,9 +72,10 @@ impl <'a> System<'a> for Move {
}
if !blocked && on_floor {
let mut pos_mut = pos.get_mut_unchecked();
- pos_mut.prev = Some(pos_mut.pos);
moved.insert(ent, Moved{from: pos_mut.pos}).expect("can't insert Moved");
+ ground.cells.get_mut(&pos_mut.pos).unwrap().remove(&ent);
pos_mut.pos = newpos.clone();
+ ground.cells.entry(newpos).or_insert(HashSet::new()).insert(ent);
}
}
_ => {}
diff --git a/src/systems/remove.rs b/src/systems/remove.rs
index 2c531e2..b73a2fb 100644
--- a/src/systems/remove.rs
+++ b/src/systems/remove.rs
@@ -3,25 +3,31 @@ use specs::{
ReadStorage,
System,
Join,
+ Write,
Entities
};
-use crate::components::{Removed};
-
+use crate::components::{Removed, Position};
+use crate::resources::Ground;
pub struct Remove;
impl <'a> System<'a> for Remove {
type SystemData = (
Entities<'a>,
- ReadStorage<'a, Removed>
+ ReadStorage<'a, Removed>,
+ ReadStorage<'a, Position>,
+ Write<'a, Ground>
);
- fn run(&mut self, (entities, removals): Self::SystemData) {
- for (ent, _) in (&*entities, &removals).join() {
+ fn run(&mut self, (entities, removals, positions, mut ground): Self::SystemData) {
+ for (ent, _) in (&*entities, &removals, ).join() {
if let Err(msg) = entities.delete(ent){
println!("{:?}", msg);
}
+ if let Some(position) = positions.get(ent) {
+ ground.cells.get_mut(&position.pos).unwrap().remove(&ent);
+ }
}
}
}
diff --git a/src/systems/view.rs b/src/systems/view.rs
index 12b5f78..79078f4 100644
--- a/src/systems/view.rs
+++ b/src/systems/view.rs
@@ -12,106 +12,94 @@ use specs::{
Read,
Write,
System,
- Join
+ Join,
+ Entities,
+ Entity
};
use super::super::pos::Pos;
-use super::super::components::{Visible, Player, Position, New};
-use super::super::resources::{Size, Output};
+use super::super::components::{Visible, Player, Position, New, Moved, Removed};
+use super::super::resources::{Size, Output, Ground};
use super::super::worldmessages::{WorldMessage, WorldUpdate, FieldMessage};
#[derive(Default)]
-pub struct View {
- pos_reader_id: Option<ReaderId<ComponentEvent>>,
- vis_reader_id: Option<ReaderId<ComponentEvent>>,
- dirty: BitSet
-}
+pub struct View;
impl <'a> System<'a> for View {
- type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Visible>, Read<'a, Size>, WriteStorage<'a, Player>, Write<'a, Output>, ReadStorage<'a, New>);
- fn run(&mut self, (positions, visible, size, mut players, mut output, _new): Self::SystemData) {
+ type SystemData = (
+ Entities<'a>,
+ ReadStorage<'a, Position>,
+ ReadStorage<'a, Visible>,
+ Read<'a, Size>,
+ WriteStorage<'a, Player>,
+ Write<'a, Output>,
+ ReadStorage<'a, New>,
+ ReadStorage<'a, Moved>,
+ ReadStorage<'a, Removed>,
+ Read<'a, Ground>
+ );
+ fn run(&mut self, (entities, positions, visible, size, mut players, mut output, new, moved, removed, ground): Self::SystemData) {
- let mut cells: HashMap<Pos, Vec<Visible>> = HashMap::new();
- for (pos, vis) in (&positions, &visible).join(){
- cells.entry(pos.pos).or_insert(Vec::new()).push(vis.clone());
- cells.get_mut(&pos.pos).unwrap().sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap());
+ let mut changed = HashSet::new();
+ for (pos, _new) in (&positions, &new).join() {
+ changed.insert(pos.pos);
}
- let width = size.width;
- let height = size.height;
- let (values, mapping) = draw_room(cells.clone(), (width, height));
-
- let field = WorldUpdate::Field(FieldMessage{
- width,
- height,
- field: values,
- mapping
- });
-
-
- self.dirty.clear();
- {
- let pos_events = positions.channel().read(self.pos_reader_id.as_mut().unwrap());
- let vis_events = visible.channel().read(self.vis_reader_id.as_mut().unwrap());
- let events = vec![pos_events, vis_events].into_iter().flatten();
- for event in events {
- match event {
- ComponentEvent::Modified(id) | ComponentEvent::Inserted(id) | ComponentEvent::Removed(id) => {
- self.dirty.add(*id);
- }
- };
- }
+ for (pos, mov) in (&positions, &moved).join() {
+ changed.insert(pos.pos);
+ changed.insert(mov.from);
}
- let mut changed: HashSet<Pos> = HashSet::new();
- for (pos, _) in (&positions, &self.dirty).join(){
+ for (pos, _removed) in (&positions, &removed).join() {
changed.insert(pos.pos);
- if let Some(prev) = pos.prev{
- changed.insert(prev);
- }
}
+
+
let has_changed: bool = changed.len() > 0;
let mut changes: Vec<(Pos, Vec<String>)> = Vec::new();
for pos in changed {
- changes.push((pos, cells.get(&pos).unwrap_or(&Vec::new()).iter().map(|v| v.sprite.clone()).collect()));
+ changes.push((pos, cell_sprites(ground.cells.get(&pos).unwrap_or(&HashSet::new()), &visible)));
}
let changed_msg = WorldUpdate::Change(changes);
output.output.clear();
- for (mut player, pos) in (&mut players, &positions).join() {
+
+ for (ent, mut player, pos) in (&entities, &mut players, &positions).join() {
let mut updates: Vec<WorldUpdate> = Vec::new();
- if player.is_new {
- updates.push(field.clone());
+ if new.get(ent).is_some() {
+ let (values, mapping) = draw_room(&ground.cells, (size.width, size.height), &visible);
+ let field = WorldUpdate::Field(FieldMessage{
+ width: size.width,
+ height: size.height,
+ field: values,
+ mapping
+ });
+ updates.push(field);
} else if has_changed {
updates.push(changed_msg.clone());
}
updates.push(WorldUpdate::Pos(pos.pos));
let message = WorldMessage{updates};
output.output.insert(player.name.clone(), message);
- player.is_new = false;
}
}
-
- fn setup(&mut self, world: &mut World) {
- Self::SystemData::setup(world);
- self.pos_reader_id = Some(
- WriteStorage::<Position>::fetch(&world).register_reader()
- );
- self.vis_reader_id = Some(
- WriteStorage::<Visible>::fetch(&world).register_reader()
- );
- }
}
-fn draw_room(cells: HashMap<Pos, Vec<Visible>>, (width, height): (i64, i64)) -> (Vec<usize>, Vec<Vec<String>>){
+fn cell_sprites(entities: &HashSet<Entity>, visible: &ReadStorage<Visible>) -> Vec<String> {
+ let mut visibles: Vec<&Visible> = entities.iter().filter_map(|ent| visible.get(*ent)).collect();
+ visibles.sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap());
+ visibles.iter().map(|vis| vis.sprite.clone()).collect()
+}
+
+fn draw_room(ground: &HashMap<Pos, HashSet<Entity>>, (width, height): (i64, i64), visible: &ReadStorage<Visible>) -> (Vec<usize>, Vec<Vec<String>>){
let size = width * height;
let mut values :Vec<usize> = Vec::with_capacity(size as usize);
let mut mapping: Vec<Vec<String>> = Vec::new();
for y in 0..height {
for x in 0..width {
- let sprites: Vec<String> = match cells.get(&Pos{x: x, y: y}) {
- Some(sprites) => {sprites.iter().map(|v| v.sprite.clone()).collect()}
+ let sprites: Vec<String> = match ground.get(&Pos{x: x, y: y}) {
+ Some(ents) => {cell_sprites(ents, visible)}
None => {vec![]}
};
values.push(
diff --git a/src/worldmessages.rs b/src/worldmessages.rs
index 79cd400..cbbc2ec 100644
--- a/src/worldmessages.rs
+++ b/src/worldmessages.rs
@@ -4,7 +4,7 @@ use serde::Serialize;
use super::util::ToJson;
use super::pos::Pos;
-#[derive(Clone)]
+#[derive(Debug, Clone)]
pub struct WorldMessage {
pub updates: Vec<WorldUpdate>
}
@@ -16,7 +16,7 @@ impl ToJson for WorldMessage {
}
}
-#[derive(Clone)]
+#[derive(Debug, Clone)]
pub enum WorldUpdate {
Field(FieldMessage),
Pos(Pos),
@@ -33,7 +33,7 @@ impl ToJson for WorldUpdate {
}
}
-#[derive(Clone, Serialize)]
+#[derive(Debug, Clone, Serialize)]
pub struct FieldMessage {
pub width: i64,
pub height: i64,