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