From a24e17014f37318d08fc8224d38e4062c959f34e Mon Sep 17 00:00:00 2001 From: troido Date: Fri, 21 Feb 2020 22:47:35 +0100 Subject: only send minimal data to the player --- src/worldmessages.rs | 103 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 29 deletions(-) (limited to 'src/worldmessages.rs') 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 -} + 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 = 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 = 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)>), - Inventory(Vec), - 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)>; +pub type HealthMessage = (i64, i64); +pub type InventoryMessage = Vec; + + +#[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> } +#[derive(Debug, Clone, Default)] +pub struct MessageCache { + pub cache: HashMap +} + +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()); + } + } +} + -- cgit