1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
use std::collections::HashMap;
use serde_json::{Value, json};
use serde::Serialize;
use crate::{
Pos,
Sprite,
PlayerId
};
macro_rules! worldmessages {
($($name: ident, $typ: ident, $strname: expr, $filter: expr);*;) => {
#[derive(Debug, Clone, Default, PartialEq)]
pub struct WorldMessage {
$(
pub $name: Option<$typ>,
)*
}
impl WorldMessage {
pub fn remove_old(&mut self, previous: &WorldMessage){
$(
if $filter && 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())*
}
pub 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])
}
}
}
}
worldmessages!(
field, FieldMessage, "field", true;
pos, Pos, "playerpos", true;
change, ChangeMessage, "changecells", true;
inventory, InventoryMessage, "inv", true;
health, HealthMessage, "health", true;
ground, GroundMessage, "ground", true;
sounds, SoundMessage, "messages", false;
);
pub type ChangeMessage = Vec<(Pos, Vec<Sprite>)>;
pub type HealthMessage = (i64, i64);
pub type InventoryMessage = Vec<(String, bool)>;
pub type GroundMessage = Vec<String>;
pub type SoundMessage = Vec<(String, String, Value)>;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
pub struct FieldMessage {
pub width: i64,
pub height: i64,
pub field: Vec<usize>,
pub mapping: Vec<Vec<Sprite>>
}
#[derive(Debug, Clone, Default)]
pub struct MessageCache {
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());
}
}
pub fn remove(&mut self, player: &PlayerId){
self.cache.remove(player);
}
}
|