summaryrefslogtreecommitdiff
path: root/src/systems
diff options
context:
space:
mode:
Diffstat (limited to 'src/systems')
-rw-r--r--src/systems/makefloor.rs6
-rw-r--r--src/systems/moving.rs15
-rw-r--r--src/systems/view.rs96
3 files changed, 77 insertions, 40 deletions
diff --git a/src/systems/makefloor.rs b/src/systems/makefloor.rs
index b6fedd9..209d965 100644
--- a/src/systems/makefloor.rs
+++ b/src/systems/makefloor.rs
@@ -8,7 +8,7 @@ use specs::{
Join
};
-use super::super::pos::Pos;
+use super::super::components::Position;
use super::super::resources::{
Floor
@@ -17,11 +17,11 @@ use super::super::resources::{
pub struct MakeFloor;
impl <'a> System<'a> for MakeFloor {
- type SystemData = (Entities<'a>, Write<'a, Floor>, ReadStorage<'a, Pos>);
+ type SystemData = (Entities<'a>, Write<'a, Floor>, ReadStorage<'a, Position>);
fn run(&mut self, (entities, mut floor, positions): Self::SystemData) {
floor.cells.clear();
for (ent, pos) in (&entities, &positions).join() {
- floor.cells.entry(*pos).or_insert(Vec::new()).push(ent);
+ floor.cells.entry(pos.pos).or_insert(Vec::new()).push(ent);
}
}
}
diff --git a/src/systems/moving.rs b/src/systems/moving.rs
index 38588d5..2ea0650 100644
--- a/src/systems/moving.rs
+++ b/src/systems/moving.rs
@@ -11,7 +11,8 @@ use super::super::pos::Pos;
use super::super::components::{
Controller,
- Blocking
+ Blocking,
+ Position
};
use super::super::controls::{
@@ -27,12 +28,12 @@ use super::super::resources::{
pub struct Move;
impl <'a> System<'a> for Move {
- type SystemData = (ReadStorage<'a, Controller>, WriteStorage<'a, Pos>, Read<'a, Size>, ReadStorage<'a, Blocking>, Read<'a, Floor>);
- fn run(&mut self, (controller, mut pos, size, blocking, floor): Self::SystemData) {
- for (controller, pos) in (&controller, &mut pos).join(){
+ type SystemData = (ReadStorage<'a, Controller>, WriteStorage<'a, Position>, Read<'a, Size>, ReadStorage<'a, Blocking>, Read<'a, Floor>);
+ fn run(&mut self, (controllers, mut positions, size, blocking, floor): Self::SystemData) {
+ for (controller, mut pos) in (&controllers, &mut positions.restrict_mut()).join(){
match &controller.0 {
Control::Move(direction) => {
- let newpos = (*pos + direction.to_position()).clamp(Pos::new(0, 0), Pos::new(size.width - 1, size.height - 1));
+ let newpos = (pos.get_unchecked().pos + direction.to_position()).clamp(Pos::new(0, 0), Pos::new(size.width - 1, size.height - 1));
let mut blocked = false;
for ent in floor.cells.get(&newpos).unwrap_or(&Vec::new()) {
if blocking.get(*ent).is_some(){
@@ -41,7 +42,9 @@ impl <'a> System<'a> for Move {
}
}
if !blocked {
- pos.clone_from(&newpos);
+ let mut pos_mut = pos.get_mut_unchecked();
+ pos_mut.prev = Some(pos_mut.pos);
+ pos_mut.pos = newpos.clone();
}
}
_ => {}
diff --git a/src/systems/view.rs b/src/systems/view.rs
index 209b1a5..b854348 100644
--- a/src/systems/view.rs
+++ b/src/systems/view.rs
@@ -1,8 +1,14 @@
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
use specs::{
+ BitSet,
+ storage::ComponentEvent,
+ ReaderId,
+ World,
+ SystemData,
ReadStorage,
+ WriteStorage,
Read,
Write,
System,
@@ -10,39 +16,29 @@ use specs::{
};
use super::super::pos::Pos;
-
-use super::super::components::{
- Visible,
- Played
-};
-
-use super::super::resources::{
- Size,
- Output
-};
-
-use super::super::worldmessages::{
- WorldMessage,
- WorldUpdate,
- FieldMessage
-};
+use super::super::components::{Visible, Played, Position};
+use super::super::resources::{Size, Output};
+use super::super::worldmessages::{WorldMessage, WorldUpdate, FieldMessage};
+#[derive(Default)]
+pub struct View {
+ reader_id: Option<ReaderId<ComponentEvent>>,
+ dirty: BitSet
+}
-pub struct View;
impl <'a> System<'a> for View {
- type SystemData = (ReadStorage<'a, Pos>, ReadStorage<'a, Visible>, Read<'a, Size>, ReadStorage<'a, Played>, Write<'a, Output>);
- fn run(&mut self, (positions, visible, size, players, mut output): Self::SystemData) {
-
+ type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Visible>, Read<'a, Size>, WriteStorage<'a, Played>, Write<'a, Output>);
+ fn run(&mut self, (positions, visible, size, mut players, mut output): Self::SystemData) {
let mut cells: HashMap<Pos, Vec<Visible>> = HashMap::new();
for (pos, vis) in (&positions, &visible).join(){
- cells.entry(*pos).or_insert(Vec::new()).push(vis.clone());
- cells.get_mut(pos).unwrap().sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap());
+ 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 width = size.width;
let height = size.height;
- let (values, mapping) = draw_room(cells, (width, height));
+ let (values, mapping) = draw_room(cells.clone(), (width, height));
let field = WorldUpdate::Field(FieldMessage{
width,
@@ -50,19 +46,57 @@ impl <'a> System<'a> for View {
field: values,
mapping
});
+
+
+ self.dirty.clear();
+ {
+ let events = positions.channel().read(self.reader_id.as_mut().unwrap());
+ for event in events {
+ match event {
+ ComponentEvent::Modified(id) | ComponentEvent::Inserted(id) | ComponentEvent::Removed(id) => {
+ self.dirty.add(*id);
+ }
+ };
+ }
+ }
+ let mut changed: HashSet<Pos> = HashSet::new();
+ for (pos, _) in (&positions, &self.dirty).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().iter().map(|v| v.sprite.clone()).collect()));
+ }
+ let changed_msg = WorldUpdate::Change(changes);
+
+
output.output.clear();
- for (player, pos) in (&players, &positions).join() {
-
- let message = WorldMessage{updates: vec![
- field.clone(),
- WorldUpdate::Pos(*pos)
- ]};
+ for (mut player, pos) in (&mut players, &positions).join() {
+ let mut updates: Vec<WorldUpdate> = Vec::new();
+ if player.is_new {
+ updates.push(field.clone());
+ } 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.reader_id = Some(
+ WriteStorage::<Position>::fetch(&world).register_reader()
+ );
+ }
}
-
fn draw_room(cells: HashMap<Pos, Vec<Visible>>, (width, height): (i32, i32)) -> (Vec<usize>, Vec<Vec<String>>){
let size = width * height;