author | unc0rr |
Fri, 02 Aug 2019 13:35:23 +0200 | |
changeset 15284 | ae8e14d14596 |
parent 15265 | rust/lib-hedgewars-engine/src/ipc/queue.rs@07e909ba4203 |
permissions | -rw-r--r-- |
15284
ae8e14d14596
Move messages queue to hedgewars-engine-messages lib
unc0rr
parents:
15265
diff
changeset
|
1 |
use crate::messages::{EngineMessage::*, SyncedEngineMessage::*, UnsyncedEngineMessage::*, *}; |
15265
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
2 |
use queues::*; |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
3 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
4 |
#[derive(PartialEq)] |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
5 |
pub enum QueueChatStrategy { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
6 |
NetworkGame, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
7 |
LocalGame, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
8 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
9 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
10 |
pub struct MessagesQueue { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
11 |
strategy: QueueChatStrategy, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
12 |
hi_ticks: u32, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
13 |
unordered: Queue<EngineMessage>, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
14 |
ordered: Queue<EngineMessage>, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
15 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
16 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
17 |
impl MessagesQueue { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
18 |
pub fn new(strategy: QueueChatStrategy) -> Self { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
19 |
MessagesQueue { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
20 |
strategy, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
21 |
hi_ticks: 0, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
22 |
unordered: queue![], |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
23 |
ordered: queue![], |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
24 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
25 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
26 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
27 |
fn is_unordered(&self, message: &EngineMessage) -> bool { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
28 |
match message { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
29 |
Unordered(_) => true, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
30 |
Unsynced(HogSay(_)) | Unsynced(ChatMessage(_)) | Unsynced(TeamMessage(_)) => { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
31 |
self.strategy == QueueChatStrategy::NetworkGame |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
32 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
33 |
_ => false, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
34 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
35 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
36 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
37 |
pub fn push(&mut self, engine_message: EngineMessage) { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
38 |
if self.is_unordered(&engine_message) { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
39 |
self.unordered.add(engine_message).unwrap(); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
40 |
} else if let Synced(TimeWrap, timestamp) = engine_message { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
41 |
self.ordered |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
42 |
.add(Synced(TimeWrap, timestamp + self.hi_ticks)) |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
43 |
.unwrap(); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
44 |
self.hi_ticks += 65536; |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
45 |
} else if let Synced(message, timestamp) = engine_message { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
46 |
self.ordered |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
47 |
.add(Synced(message, timestamp + self.hi_ticks)) |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
48 |
.unwrap(); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
49 |
} else { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
50 |
self.ordered.add(engine_message).unwrap(); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
51 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
52 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
53 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
54 |
pub fn pop(&mut self, timestamp: u32) -> Option<EngineMessage> { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
55 |
if let Ok(message) = self.unordered.remove() { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
56 |
Some(message) |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
57 |
} else if let Ok(Synced(_, message_timestamp)) = self.ordered.peek() { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
58 |
if message_timestamp == timestamp { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
59 |
self.ordered.remove().ok() |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
60 |
} else { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
61 |
None |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
62 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
63 |
} else { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
64 |
self.ordered.remove().ok() |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
65 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
66 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
67 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
68 |
pub fn iter(&mut self, timestamp: u32) -> MessagesQueueIterator { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
69 |
MessagesQueueIterator { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
70 |
timestamp, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
71 |
queue: self, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
72 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
73 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
74 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
75 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
76 |
pub struct MessagesQueueIterator<'a> { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
77 |
timestamp: u32, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
78 |
queue: &'a mut MessagesQueue, |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
79 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
80 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
81 |
impl<'a> Iterator for MessagesQueueIterator<'a> { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
82 |
type Item = EngineMessage; |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
83 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
84 |
fn next(&mut self) -> Option<EngineMessage> { |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
85 |
self.queue.pop(self.timestamp) |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
86 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
87 |
} |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
88 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
89 |
#[test] |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
90 |
fn queue_order() { |
15284
ae8e14d14596
Move messages queue to hedgewars-engine-messages lib
unc0rr
parents:
15265
diff
changeset
|
91 |
use crate::messages::UnorderedEngineMessage::*; |
15265
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
92 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
93 |
let mut queue = MessagesQueue::new(QueueChatStrategy::LocalGame); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
94 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
95 |
queue.push(Synced(Skip, 1)); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
96 |
queue.push(Unsynced(ChatMessage("hi".to_string()))); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
97 |
queue.push(Synced(TimeWrap, 65535)); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
98 |
queue.push(Unordered(Ping)); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
99 |
queue.push(Synced(Skip, 2)); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
100 |
|
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
101 |
let zero_tick: Vec<EngineMessage> = queue.iter(0).collect(); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
102 |
assert_eq!(zero_tick, vec![Unordered(Ping)]); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
103 |
assert_eq!(queue.pop(1), Some(Synced(Skip, 1))); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
104 |
assert_eq!(queue.pop(1), Some(Unsynced(ChatMessage("hi".to_string())))); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
105 |
assert_eq!(queue.pop(1), None); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
106 |
assert_eq!(queue.pop(2), None); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
107 |
assert_eq!(queue.pop(65535), Some(Synced(TimeWrap, 65535))); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
108 |
assert_eq!(queue.pop(65535), None); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
109 |
assert_eq!(queue.pop(65538), Some(Synced(Skip, 65538))); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
110 |
assert_eq!(queue.pop(65538), None); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
111 |
assert_eq!(queue.pop(65539), None); |
07e909ba4203
Implement ipc queue which takes care of message ordering and timestamps
unC0Rr
parents:
diff
changeset
|
112 |
} |