summaryrefslogtreecommitdiff
path: root/src/worldmessages.rs
blob: 979faa8f23048b0a3ae8aad2e69e749972286f81 (plain)
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);
	}
}