diff options
Diffstat (limited to 'snapshot/src/manager.rs')
-rw-r--r-- | snapshot/src/manager.rs | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/snapshot/src/manager.rs b/snapshot/src/manager.rs new file mode 100644 index 0000000..65d0c72 --- /dev/null +++ b/snapshot/src/manager.rs @@ -0,0 +1,140 @@ +use Delta; +use DeltaReader; +use DeltaReceiver; +use ReceivedDelta; +use Snap; +use Storage; +use format; +use gamenet::msg::system; +use packer::Unpacker; +use receiver; +use snap; +use storage; +use warn::Warn; +use warn::wrap; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Error { + Receiver(receiver::Error), + Snap(snap::Error), + Storage(storage::Error), +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Warning { + Receiver(receiver::Warning), + Snap(format::Warning), + Storage(storage::Warning), +} + +impl From<receiver::Error> for Error { + fn from(err: receiver::Error) -> Error { + Error::Receiver(err) + } +} + +impl From<snap::Error> for Error { + fn from(err: snap::Error) -> Error { + Error::Snap(err) + } +} + +impl From<storage::Error> for Error { + fn from(err: storage::Error) -> Error { + Error::Storage(err) + } +} + +impl From<receiver::Warning> for Warning { + fn from(w: receiver::Warning) -> Warning { + Warning::Receiver(w) + } +} + +impl From<format::Warning> for Warning { + fn from(w: format::Warning) -> Warning { + Warning::Snap(w) + } +} + +impl From<storage::Warning> for Warning { + fn from(w: storage::Warning) -> Warning { + Warning::Storage(w) + } +} + +#[derive(Clone, Default)] +struct ManagerInner { + temp_delta: Delta, + reader: DeltaReader, + storage: Storage, +} + +#[derive(Clone, Default)] +pub struct Manager { + inner: ManagerInner, + receiver: DeltaReceiver, +} + +impl Manager { + pub fn new() -> Manager { + Default::default() + } + pub fn reset(&mut self) { + self.inner.storage.reset(); + self.receiver.reset(); + } + pub fn ack_tick(&self) -> Option<i32> { + self.inner.storage.ack_tick() + } + pub fn snap_empty<W, O>(&mut self, warn: &mut W, object_size: O, snap: system::SnapEmpty) + -> Result<Option<&Snap>, Error> + where W: Warn<Warning>, + O: FnMut(u16) -> Option<u32>, + { + let res = self.receiver.snap_empty(wrap(warn), snap); + self.inner.handle_msg(warn, object_size, res) + } + pub fn snap_single<W, O>(&mut self, warn: &mut W, object_size: O, snap: system::SnapSingle) + -> Result<Option<&Snap>, Error> + where W: Warn<Warning>, + O: FnMut(u16) -> Option<u32>, + { + let res = self.receiver.snap_single(wrap(warn), snap); + self.inner.handle_msg(warn, object_size, res) + } + pub fn snap<W, O>(&mut self, warn: &mut W, object_size: O, snap: system::Snap) + -> Result<Option<&Snap>, Error> + where W: Warn<Warning>, + O: FnMut(u16) -> Option<u32>, + { + let res = self.receiver.snap(wrap(warn), snap); + self.inner.handle_msg(warn, object_size, res) + } +} + +impl ManagerInner { + fn handle_msg<W, O>(&mut self, warn: &mut W, object_size: O, res: Result<Option<ReceivedDelta>, receiver::Error>) + -> Result<Option<&Snap>, Error> + where W: Warn<Warning>, + O: FnMut(u16) -> Option<u32>, + { + Ok(match res? { + Some(delta) => Some(self.add_delta(warn, object_size, delta)?), + None => None, + }) + } + fn add_delta<W, O>(&mut self, warn: &mut W, object_size: O, delta: ReceivedDelta) + -> Result<&Snap, Error> + where W: Warn<Warning>, + O: FnMut(u16) -> Option<u32>, + { + let crc = delta.data_and_crc.map(|d| d.1); + if let Some((data, _)) = delta.data_and_crc { + self.reader.read(wrap(warn), &mut self.temp_delta, object_size, &mut Unpacker::new(data))?; + } else { + self.temp_delta.clear(); + } + Ok(self.storage.add_delta(wrap(warn), crc, delta.delta_tick, delta.tick, &self.temp_delta)?) + } +} |