diff options
| author | troido <troido@protonmail.com> | 2020-02-21 22:47:35 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-02-21 22:47:35 +0100 |
| commit | a24e17014f37318d08fc8224d38e4062c959f34e (patch) | |
| tree | 4a4044a2543f0c154d97dfe963c30eb8c4414ae6 /src/worldmessages.rs | |
| parent | 7e9784f23d1920640152d1bc99a0725f6f22d529 (diff) | |
only send minimal data to the player
Diffstat (limited to 'src/worldmessages.rs')
| -rw-r--r-- | src/worldmessages.rs | 103 |
1 files changed, 74 insertions, 29 deletions
diff --git a/src/worldmessages.rs b/src/worldmessages.rs index 2e80763..1efe477 100644 --- a/src/worldmessages.rs +++ b/src/worldmessages.rs @@ -1,44 +1,72 @@ +use std::collections::HashMap; use serde_json::{Value, json}; use serde::Serialize; use crate::util::ToJson; -use crate::{Pos, Sprite}; +use crate::{Pos, Sprite, PlayerId}; +macro_rules! worldmessages { + ($($name: ident, $typ: ident, $strname: expr);*;) => { + + #[derive(Debug, Clone, Default, PartialEq, Eq)] + pub struct WorldMessage { + $( + pub $name: Option<$typ>, + )* + } -#[derive(Debug, Clone)] -pub struct WorldMessage { - pub updates: Vec<WorldUpdate> -} + impl WorldMessage { + + pub fn remove_old(&mut self, previous: &WorldMessage){ + $( + if self.$name == previous.$name { + self.$name = None; + } + )* + } + + pub fn add(&mut self, other: &WorldMessage){ + $( + if other.$name.is_some() { + self.$name = other.$name.clone(); + } + )* + } + + pub fn is_empty(&self) -> bool { + true $( && self.$name.is_none())* + } + } -impl ToJson for WorldMessage { - fn to_json(&self) -> Value { - let updates: Vec<Value> = self.updates.iter().map(|u| u.to_json()).collect(); - json!(["world", updates]) + impl ToJson for WorldMessage { + fn to_json(&self) -> Value { + let mut updates: Vec<Value> = Vec::new(); + $( + if let Some(update) = &self.$name { + updates.push(json!([$strname, update])); + } + )* + json!(["world", updates]) + } + } } } -#[derive(Debug, Clone)] -pub enum WorldUpdate { - Field(FieldMessage), - Pos(Pos), - Change(Vec<(Pos, Vec<Sprite>)>), - Inventory(Vec<String>), - Health(i64, i64) -} +worldmessages!( + field, FieldMessage, "field"; + pos, Pos, "playerpos"; + change, ChangeMessage, "changecells"; + inventory, InventoryMessage, "inventory"; + health, HealthMessage, "health"; +); -impl ToJson for WorldUpdate { - fn to_json(&self) -> Value { - match self { - WorldUpdate::Field(msg) => json!(["field", msg]), - WorldUpdate::Pos(pos) => json!(["playerpos", pos]), - WorldUpdate::Change(changes) => json!(["changecells", changes]), - WorldUpdate::Inventory(items) => json!(["inventory", items]), - WorldUpdate::Health(health, maxhealth) => json!(["health", [health, maxhealth]]) - } - } -} -#[derive(Debug, Clone, Serialize)] +pub type ChangeMessage = Vec<(Pos, Vec<Sprite>)>; +pub type HealthMessage = (i64, i64); +pub type InventoryMessage = Vec<String>; + + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] pub struct FieldMessage { pub width: i64, pub height: i64, @@ -46,5 +74,22 @@ pub struct FieldMessage { pub mapping: Vec<Vec<Sprite>> } +#[derive(Debug, Clone, Default)] +pub struct MessageCache { + pub cache: HashMap<PlayerId, WorldMessage> +} + +impl MessageCache { + + pub fn trim(&mut self, player: &PlayerId, msg: &mut WorldMessage){ + if let Some(cached) = self.cache.get_mut(player){ + msg.remove_old(cached); + cached.add(&msg); + } else { + self.cache.insert(player.clone(), msg.clone()); + } + } +} + |
