aboutsummaryrefslogtreecommitdiff
path: root/snapshot/src/receiver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'snapshot/src/receiver.rs')
-rw-r--r--snapshot/src/receiver.rs245
1 files changed, 0 insertions, 245 deletions
diff --git a/snapshot/src/receiver.rs b/snapshot/src/receiver.rs
deleted file mode 100644
index 49833d1..0000000
--- a/snapshot/src/receiver.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-use common::num::Cast;
-use gamenet::msg::system;
-use std::ops;
-use to_usize;
-use vec_map::VecMap;
-use warn::Warn;
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum Warning {
- DuplicateSnap,
- DifferingAttributes,
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum Error {
- OldDelta,
- InvalidNumParts,
- InvalidPart,
- DuplicatePart,
-}
-
-// TODO: How to handle `tick` overflowing?
-#[derive(Clone, Debug)]
-struct CurrentDelta {
- tick: i32,
- delta_tick: i32,
- num_parts: i32,
- crc: i32,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub struct ReceivedDelta<'a> {
- pub delta_tick: i32,
- pub tick: i32,
- pub data_and_crc: Option<(&'a [u8], i32)>,
-}
-
-#[derive(Clone, Default)]
-pub struct DeltaReceiver {
- previous_tick: Option<i32>,
- current: Option<CurrentDelta>,
- // `parts` points into `receive_buf`.
- parts: VecMap<ops::Range<u32>>,
- receive_buf: Vec<u8>,
- result: Vec<u8>,
-}
-
-impl DeltaReceiver {
- pub fn new() -> DeltaReceiver {
- Default::default()
- }
- pub fn reset(&mut self) {
- self.previous_tick = None;
- self.current = None;
- }
- fn can_receive(&self, tick: i32) -> bool {
- self.current.as_ref().map(|c| c.tick <= tick)
- .or(self.previous_tick.map(|t| t < tick))
- .unwrap_or(true)
- }
- fn init_delta(&mut self) {
- self.parts.clear();
- self.receive_buf.clear();
- self.result.clear();
- }
- fn finish_delta(&mut self, tick: i32) {
- self.current = None;
- self.previous_tick = Some(tick);
- }
- pub fn snap_empty<W>(&mut self, warn: &mut W, snap: system::SnapEmpty)
- -> Result<Option<ReceivedDelta>, Error>
- where W: Warn<Warning>,
- {
- if !self.can_receive(snap.tick) {
- return Err(Error::OldDelta);
- }
- if self.current.as_ref().map(|c| c.tick == snap.tick).unwrap_or(false) {
- warn.warn(Warning::DuplicateSnap);
- }
- self.init_delta();
- self.finish_delta(snap.tick);
- Ok(Some(ReceivedDelta {
- delta_tick: snap.tick.wrapping_sub(snap.delta_tick),
- tick: snap.tick,
- data_and_crc: None,
- }))
- }
- pub fn snap_single<W>(&mut self, warn: &mut W, snap: system::SnapSingle)
- -> Result<Option<ReceivedDelta>, Error>
- where W: Warn<Warning>,
- {
- if !self.can_receive(snap.tick) {
- return Err(Error::OldDelta);
- }
- if self.current.as_ref().map(|c| c.tick == snap.tick).unwrap_or(false) {
- warn.warn(Warning::DuplicateSnap);
- }
- self.init_delta();
- self.finish_delta(snap.tick);
- self.result.extend(snap.data);
- Ok(Some(ReceivedDelta {
- delta_tick: snap.tick.wrapping_sub(snap.delta_tick),
- tick: snap.tick,
- data_and_crc: Some((&self.result, snap.crc)),
- }))
- }
- pub fn snap<W>(&mut self, warn: &mut W, snap: system::Snap)
- -> Result<Option<ReceivedDelta>, Error>
- where W: Warn<Warning>,
- {
- if !self.can_receive(snap.tick) {
- return Err(Error::OldDelta);
- }
- if !(0 <= snap.num_parts && snap.num_parts <= 32) {
- return Err(Error::InvalidNumParts);
- }
- if !(0 <= snap.part && snap.part < snap.num_parts) {
- return Err(Error::InvalidPart);
- }
- if self.current.as_ref().map(|c| c.tick != snap.tick).unwrap_or(false) {
- self.current = None;
- }
- if let None = self.current {
- self.init_delta();
- self.current = Some(CurrentDelta {
- tick: snap.tick,
- delta_tick: snap.tick.wrapping_sub(snap.delta_tick),
- num_parts: snap.num_parts,
- crc: snap.crc,
- });
-
- // Checked above.
- let num_parts = snap.num_parts.assert_usize();
- self.parts.reserve_len(num_parts);
- }
- let delta_tick;
- let tick;
- let crc;
- let num_parts;
- {
- let current: &mut CurrentDelta = self.current.as_mut().unwrap();
- if snap.delta_tick != current.delta_tick
- || snap.num_parts != current.num_parts
- || snap.crc != current.crc
- {
- warn.warn(Warning::DifferingAttributes);
- }
- delta_tick = current.delta_tick;
- tick = current.tick;
- crc = current.crc;
- num_parts = current.num_parts;
- }
- let part = snap.part.assert_usize();
- if self.parts.contains_key(part) {
- return Err(Error::DuplicatePart);
- }
- let start = self.receive_buf.len().assert_u32();
- let end = (self.receive_buf.len() + snap.data.len()).assert_u32();
- self.receive_buf.extend(snap.data);
- assert!(self.parts.insert(part, start..end).is_none());
-
- if self.parts.len().assert_i32() != num_parts {
- return Ok(None);
- }
-
- self.finish_delta(tick);
- self.result.reserve(self.receive_buf.len());
- for range in self.parts.values() {
- self.result.extend(&self.receive_buf[to_usize(range.clone())]);
- }
-
- Ok(Some(ReceivedDelta {
- delta_tick: delta_tick,
- tick: tick,
- data_and_crc: Some((&self.result, crc)),
- }))
- }
-}
-
-#[cfg(test)]
-mod test {
- use common::num::Cast;
- use gamenet::msg::system::Snap;
- use gamenet::msg::system::SnapEmpty;
- use gamenet::msg::system::SnapSingle;
- use super::DeltaReceiver;
- use super::Error;
- use super::ReceivedDelta;
- use warn::Panic;
-
- #[test]
- fn old() {
- let mut receiver = DeltaReceiver::new();
- {
- let result = receiver.snap_empty(&mut Panic, SnapEmpty {
- tick: 1,
- delta_tick: 2,
- }).unwrap();
-
- assert_eq!(result, Some(ReceivedDelta {
- delta_tick: -1,
- tick: 1,
- data_and_crc: None,
- }));
- }
-
- assert_eq!(receiver.snap_single(&mut Panic, SnapSingle {
- tick: 0,
- delta_tick: 0,
- data: b"123",
- crc: 0,
- }).unwrap_err(), Error::OldDelta);
- }
-
- #[test]
- fn reorder() {
- let mut receiver = DeltaReceiver::new();
- let chunks: &[(i32, &[u8])] = &[
- (3, b"3"),
- (2, b"2"),
- (4, b"4_"),
- (1, b"1__"),
- (0, b"0"),
- ];
- for &(i, c) in chunks {
- let result = receiver.snap(&mut Panic, Snap {
- tick: 2,
- delta_tick: 1,
- num_parts: chunks.len().assert_i32(),
- part: i,
- crc: 3,
- data: c,
- }).unwrap();
- if i != 0 {
- assert_eq!(result, None);
- } else {
- assert_eq!(result, Some(ReceivedDelta {
- delta_tick: 1,
- tick: 2,
- data_and_crc: Some((b"01__234_", 3)),
- }));
- }
- }
- }
-}