# HG changeset patch # User unc0rr # Date 1564745723 -7200 # Node ID ae8e14d14596a4222b8fa813496f1c81f17b5dc0 # Parent 478d5372eb4aca2a3e4c9d135fafbe22b8d96ee6 Move messages queue to hedgewars-engine-messages lib diff -r 478d5372eb4a -r ae8e14d14596 .hgignore --- a/.hgignore Tue Jul 30 22:59:06 2019 +0300 +++ b/.hgignore Fri Aug 02 13:35:23 2019 +0200 @@ -92,3 +92,5 @@ build-qmlfrontend* .cabal-sandbox cabal.sandbox.config +*.so +*_autogen diff -r 478d5372eb4a -r ae8e14d14596 rust/hedgewars-engine-messages/Cargo.toml --- a/rust/hedgewars-engine-messages/Cargo.toml Tue Jul 30 22:59:06 2019 +0300 +++ b/rust/hedgewars-engine-messages/Cargo.toml Fri Aug 02 13:35:23 2019 +0200 @@ -7,3 +7,4 @@ [dependencies] nom = "4.1" byteorder = "1.2" +queues = "1.1" diff -r 478d5372eb4a -r ae8e14d14596 rust/hedgewars-engine-messages/src/lib.rs --- a/rust/hedgewars-engine-messages/src/lib.rs Tue Jul 30 22:59:06 2019 +0300 +++ b/rust/hedgewars-engine-messages/src/lib.rs Fri Aug 02 13:35:23 2019 +0200 @@ -1,2 +1,3 @@ pub mod messages; pub mod parser; +pub mod queue; diff -r 478d5372eb4a -r ae8e14d14596 rust/hedgewars-engine-messages/src/parser.rs --- a/rust/hedgewars-engine-messages/src/parser.rs Tue Jul 30 22:59:06 2019 +0300 +++ b/rust/hedgewars-engine-messages/src/parser.rs Fri Aug 02 13:35:23 2019 +0200 @@ -1,10 +1,9 @@ -use nom::{Err::Error, *}; -use std::str; - -use super::messages::{ +use crate::messages::{ ConfigEngineMessage::*, EngineMessage::*, KeystrokeAction::*, SyncedEngineMessage::*, UnorderedEngineMessage::*, *, }; +use nom::{Err::Error, *}; +use std::str; macro_rules! eof_slice ( ($i:expr,) => ( @@ -129,62 +128,74 @@ let consumed = buf.len() - tail.len(); Some((consumed, msg)) - }, + } Err(Err::Incomplete(_)) => None, Err(Err::Error(_)) | Err(Err::Failure(_)) => unreachable!(), } } -#[test] -fn parse_length() { - assert_eq!(length_specifier(b"\x01"), Ok((&b""[..], 1))); - assert_eq!(length_specifier(b"\x00"), Ok((&b""[..], 0))); - assert_eq!(length_specifier(b"\x3f"), Ok((&b""[..], 63))); - assert_eq!(length_specifier(b"\x40\x00"), Ok((&b""[..], 64))); - assert_eq!( - length_specifier(b"\xff\xff"), - Ok((&b""[..], EngineMessage::MAX_LEN)) - ); -} +#[cfg(test)] +mod tests { + use crate::messages::UnsyncedEngineMessage::*; + use crate::parser::*; -#[test] -fn parse_synced_messages() { - assert_eq!( - message(b"\x03L\x01\x02"), - Ok((&b""[..], Synced(Left(Press), 258))) - ); + #[test] + fn parse_length() { + assert_eq!(length_specifier(b"\x01"), Ok((&b""[..], 1))); + assert_eq!(length_specifier(b"\x00"), Ok((&b""[..], 0))); + assert_eq!(length_specifier(b"\x3f"), Ok((&b""[..], 63))); + assert_eq!(length_specifier(b"\x40\x00"), Ok((&b""[..], 64))); + assert_eq!( + length_specifier(b"\xff\xff"), + Ok((&b""[..], EngineMessage::MAX_LEN)) + ); + } - assert_eq!(message(b"\x01#"), Ok((&b""[..], Synced(TimeWrap, 65535)))); + #[test] + fn parse_synced_messages() { + assert_eq!( + message(b"\x03L\x01\x02"), + Ok((&b""[..], Synced(Left(Press), 258))) + ); - assert_eq!(message(&vec![9, b'p', 255, 133, 151, 1, 0, 2, 0, 0]), Ok((&b""[..], Synced(Put(-31337, 65538), 0)))); -} + assert_eq!(message(b"\x01#"), Ok((&b""[..], Synced(TimeWrap, 65535)))); + + assert_eq!( + message(&vec![9, b'p', 255, 133, 151, 1, 0, 2, 0, 0]), + Ok((&b""[..], Synced(Put(-31337, 65538), 0))) + ); + } -#[test] -fn parse_unsynced_messages() { - assert_eq!( - message(b"\x06shello"), - Ok((&b""[..], Unordered(ChatMessage(String::from("hello"))))) - ); -} + #[test] + fn parse_unsynced_messages() { + assert_eq!( + message(b"\x06shello"), + Ok((&b""[..], Unsynced(ChatMessage(String::from("hello"))))) + ); + } -#[test] -fn parse_incorrect_messages() { - assert_eq!(message(b"\x00"), Ok((&b""[..], Empty))); - assert_eq!(message(b"\x01\x00"), Ok((&b""[..], Unknown))); + #[test] + fn parse_incorrect_messages() { + assert_eq!(message(b"\x00"), Ok((&b""[..], Empty))); + assert_eq!(message(b"\x01\x00"), Ok((&b""[..], Unknown))); + + // garbage after correct message + assert_eq!(message(b"\x04La\x01\x02"), Ok((&b""[..], Unknown))); + } - // garbage after correct message - assert_eq!(message(b"\x04La\x01\x02"), Ok((&b""[..], Unknown))); -} + #[test] + fn parse_config_messages() { + assert_eq!(message(b"\x01C"), Ok((&b""[..], Config(ConfigRequest)))); + } -#[test] -fn parse_config_messages() { - assert_eq!(message(b"\x01C"), Ok((&b""[..], Config(ConfigRequest)))); + #[test] + fn parse_test_general() { + assert_eq!(string_tail(b"abc"), Ok((&b""[..], String::from("abc")))); + + assert_eq!(extract_message(b"\x02#"), None); + assert_eq!( + extract_message(b"\x01#"), + Some((2, Synced(TimeWrap, 65535))) + ); + } } - -#[test] -fn parse_test_general() { - assert_eq!(string_tail(b"abc"), Ok((&b""[..], String::from("abc")))); - - assert_eq!(extract_message(b"\x02#"), None); - assert_eq!(extract_message(b"\x01#"), Some((2, Synced(TimeWrap, 65535)))); -} diff -r 478d5372eb4a -r ae8e14d14596 rust/hedgewars-engine-messages/src/queue.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hedgewars-engine-messages/src/queue.rs Fri Aug 02 13:35:23 2019 +0200 @@ -0,0 +1,112 @@ +use crate::messages::{EngineMessage::*, SyncedEngineMessage::*, UnsyncedEngineMessage::*, *}; +use queues::*; + +#[derive(PartialEq)] +pub enum QueueChatStrategy { + NetworkGame, + LocalGame, +} + +pub struct MessagesQueue { + strategy: QueueChatStrategy, + hi_ticks: u32, + unordered: Queue, + ordered: Queue, +} + +impl MessagesQueue { + pub fn new(strategy: QueueChatStrategy) -> Self { + MessagesQueue { + strategy, + hi_ticks: 0, + unordered: queue![], + ordered: queue![], + } + } + + fn is_unordered(&self, message: &EngineMessage) -> bool { + match message { + Unordered(_) => true, + Unsynced(HogSay(_)) | Unsynced(ChatMessage(_)) | Unsynced(TeamMessage(_)) => { + self.strategy == QueueChatStrategy::NetworkGame + } + _ => false, + } + } + + pub fn push(&mut self, engine_message: EngineMessage) { + if self.is_unordered(&engine_message) { + self.unordered.add(engine_message).unwrap(); + } else if let Synced(TimeWrap, timestamp) = engine_message { + self.ordered + .add(Synced(TimeWrap, timestamp + self.hi_ticks)) + .unwrap(); + self.hi_ticks += 65536; + } else if let Synced(message, timestamp) = engine_message { + self.ordered + .add(Synced(message, timestamp + self.hi_ticks)) + .unwrap(); + } else { + self.ordered.add(engine_message).unwrap(); + } + } + + pub fn pop(&mut self, timestamp: u32) -> Option { + if let Ok(message) = self.unordered.remove() { + Some(message) + } else if let Ok(Synced(_, message_timestamp)) = self.ordered.peek() { + if message_timestamp == timestamp { + self.ordered.remove().ok() + } else { + None + } + } else { + self.ordered.remove().ok() + } + } + + pub fn iter(&mut self, timestamp: u32) -> MessagesQueueIterator { + MessagesQueueIterator { + timestamp, + queue: self, + } + } +} + +pub struct MessagesQueueIterator<'a> { + timestamp: u32, + queue: &'a mut MessagesQueue, +} + +impl<'a> Iterator for MessagesQueueIterator<'a> { + type Item = EngineMessage; + + fn next(&mut self) -> Option { + self.queue.pop(self.timestamp) + } +} + +#[test] +fn queue_order() { + use crate::messages::UnorderedEngineMessage::*; + + let mut queue = MessagesQueue::new(QueueChatStrategy::LocalGame); + + queue.push(Synced(Skip, 1)); + queue.push(Unsynced(ChatMessage("hi".to_string()))); + queue.push(Synced(TimeWrap, 65535)); + queue.push(Unordered(Ping)); + queue.push(Synced(Skip, 2)); + + let zero_tick: Vec = queue.iter(0).collect(); + assert_eq!(zero_tick, vec![Unordered(Ping)]); + assert_eq!(queue.pop(1), Some(Synced(Skip, 1))); + assert_eq!(queue.pop(1), Some(Unsynced(ChatMessage("hi".to_string())))); + assert_eq!(queue.pop(1), None); + assert_eq!(queue.pop(2), None); + assert_eq!(queue.pop(65535), Some(Synced(TimeWrap, 65535))); + assert_eq!(queue.pop(65535), None); + assert_eq!(queue.pop(65538), Some(Synced(Skip, 65538))); + assert_eq!(queue.pop(65538), None); + assert_eq!(queue.pop(65539), None); +} diff -r 478d5372eb4a -r ae8e14d14596 rust/lib-hedgewars-engine/Cargo.toml --- a/rust/lib-hedgewars-engine/Cargo.toml Tue Jul 30 22:59:06 2019 +0300 +++ b/rust/lib-hedgewars-engine/Cargo.toml Fri Aug 02 13:35:23 2019 +0200 @@ -9,7 +9,6 @@ netbuf = "0.4" itertools = "0.8" png = "0.13" -queues = "1.1" fpnum = { path = "../fpnum" } land2d = { path = "../land2d" } diff -r 478d5372eb4a -r ae8e14d14596 rust/lib-hedgewars-engine/src/instance.rs --- a/rust/lib-hedgewars-engine/src/instance.rs Tue Jul 30 22:59:06 2019 +0300 +++ b/rust/lib-hedgewars-engine/src/instance.rs Fri Aug 02 13:35:23 2019 +0200 @@ -2,6 +2,7 @@ ConfigEngineMessage::*, EngineMessage::*, KeystrokeAction::*, SyncedEngineMessage::*, UnorderedEngineMessage::*, UnsyncedEngineMessage::*, *, }; +use hedgewars_engine_messages::queue::*; use integral_geometry::{Point, Rect, Size}; use landgen::outline_template::OutlineTemplate; diff -r 478d5372eb4a -r ae8e14d14596 rust/lib-hedgewars-engine/src/ipc.rs --- a/rust/lib-hedgewars-engine/src/ipc.rs Tue Jul 30 22:59:06 2019 +0300 +++ b/rust/lib-hedgewars-engine/src/ipc.rs Fri Aug 02 13:35:23 2019 +0200 @@ -1,5 +1,3 @@ mod channel; -mod queue; pub use self::channel::*; -pub use self::queue::*; diff -r 478d5372eb4a -r ae8e14d14596 rust/lib-hedgewars-engine/src/ipc/queue.rs --- a/rust/lib-hedgewars-engine/src/ipc/queue.rs Tue Jul 30 22:59:06 2019 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -use hedgewars_engine_messages::{ - messages::EngineMessage::*, messages::SyncedEngineMessage::*, - messages::UnsyncedEngineMessage::*, messages::*, -}; -use queues::*; - -#[derive(PartialEq)] -pub enum QueueChatStrategy { - NetworkGame, - LocalGame, -} - -pub struct MessagesQueue { - strategy: QueueChatStrategy, - hi_ticks: u32, - unordered: Queue, - ordered: Queue, -} - -impl MessagesQueue { - pub fn new(strategy: QueueChatStrategy) -> Self { - MessagesQueue { - strategy, - hi_ticks: 0, - unordered: queue![], - ordered: queue![], - } - } - - fn is_unordered(&self, message: &EngineMessage) -> bool { - match message { - Unordered(_) => true, - Unsynced(HogSay(_)) | Unsynced(ChatMessage(_)) | Unsynced(TeamMessage(_)) => { - self.strategy == QueueChatStrategy::NetworkGame - } - _ => false, - } - } - - pub fn push(&mut self, engine_message: EngineMessage) { - if self.is_unordered(&engine_message) { - self.unordered.add(engine_message).unwrap(); - } else if let Synced(TimeWrap, timestamp) = engine_message { - self.ordered - .add(Synced(TimeWrap, timestamp + self.hi_ticks)) - .unwrap(); - self.hi_ticks += 65536; - } else if let Synced(message, timestamp) = engine_message { - self.ordered - .add(Synced(message, timestamp + self.hi_ticks)) - .unwrap(); - } else { - self.ordered.add(engine_message).unwrap(); - } - } - - pub fn pop(&mut self, timestamp: u32) -> Option { - if let Ok(message) = self.unordered.remove() { - Some(message) - } else if let Ok(Synced(_, message_timestamp)) = self.ordered.peek() { - if message_timestamp == timestamp { - self.ordered.remove().ok() - } else { - None - } - } else { - self.ordered.remove().ok() - } - } - - pub fn iter(&mut self, timestamp: u32) -> MessagesQueueIterator { - MessagesQueueIterator { - timestamp, - queue: self, - } - } -} - -pub struct MessagesQueueIterator<'a> { - timestamp: u32, - queue: &'a mut MessagesQueue, -} - -impl<'a> Iterator for MessagesQueueIterator<'a> { - type Item = EngineMessage; - - fn next(&mut self) -> Option { - self.queue.pop(self.timestamp) - } -} - -#[test] -fn queue_order() { - use hedgewars_engine_messages::messages::UnorderedEngineMessage::*; - - let mut queue = MessagesQueue::new(QueueChatStrategy::LocalGame); - - queue.push(Synced(Skip, 1)); - queue.push(Unsynced(ChatMessage("hi".to_string()))); - queue.push(Synced(TimeWrap, 65535)); - queue.push(Unordered(Ping)); - queue.push(Synced(Skip, 2)); - - let zero_tick: Vec = queue.iter(0).collect(); - assert_eq!(zero_tick, vec![Unordered(Ping)]); - assert_eq!(queue.pop(1), Some(Synced(Skip, 1))); - assert_eq!(queue.pop(1), Some(Unsynced(ChatMessage("hi".to_string())))); - assert_eq!(queue.pop(1), None); - assert_eq!(queue.pop(2), None); - assert_eq!(queue.pop(65535), Some(Synced(TimeWrap, 65535))); - assert_eq!(queue.pop(65535), None); - assert_eq!(queue.pop(65538), Some(Synced(Skip, 65538))); - assert_eq!(queue.pop(65538), None); - assert_eq!(queue.pop(65539), None); -}