Skip to main content

libtw2_snapshot/
manager.rs

1use crate::format;
2use crate::receiver;
3use crate::snap;
4use crate::storage;
5use crate::Delta;
6use crate::DeltaReceiver;
7use crate::ReceivedDelta;
8use crate::Snap;
9use crate::Storage;
10use libtw2_gamenet_snap as msg;
11use libtw2_packer::Unpacker;
12use libtw2_warn::wrap;
13use libtw2_warn::Warn;
14
15#[derive(Clone, Debug, Eq, PartialEq)]
16pub enum Error {
17    Receiver(receiver::Error),
18    Snap(snap::Error),
19    Storage(storage::Error),
20}
21
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub enum Warning {
24    Receiver(receiver::Warning),
25    Snap(format::Warning),
26    Storage(storage::Warning),
27}
28
29impl From<receiver::Error> for Error {
30    fn from(err: receiver::Error) -> Error {
31        Error::Receiver(err)
32    }
33}
34
35impl From<snap::Error> for Error {
36    fn from(err: snap::Error) -> Error {
37        Error::Snap(err)
38    }
39}
40
41impl From<storage::Error> for Error {
42    fn from(err: storage::Error) -> Error {
43        Error::Storage(err)
44    }
45}
46
47impl From<receiver::Warning> for Warning {
48    fn from(w: receiver::Warning) -> Warning {
49        Warning::Receiver(w)
50    }
51}
52
53impl From<format::Warning> for Warning {
54    fn from(w: format::Warning) -> Warning {
55        Warning::Snap(w)
56    }
57}
58
59impl From<storage::Warning> for Warning {
60    fn from(w: storage::Warning) -> Warning {
61        Warning::Storage(w)
62    }
63}
64
65#[derive(Clone, Default)]
66struct ManagerInner {
67    temp_delta: Delta,
68    storage: Storage,
69}
70
71#[derive(Clone, Default)]
72pub struct Manager {
73    inner: ManagerInner,
74    receiver: DeltaReceiver,
75}
76
77impl Manager {
78    pub fn new() -> Manager {
79        Default::default()
80    }
81    pub fn reset(&mut self) {
82        self.inner.storage.reset();
83        self.receiver.reset();
84    }
85    pub fn ack_tick(&self) -> Option<i32> {
86        self.inner.storage.ack_tick()
87    }
88    pub fn snap_empty<W, O>(
89        &mut self,
90        warn: &mut W,
91        object_size: O,
92        snap: msg::SnapEmpty,
93    ) -> Result<Option<&Snap>, Error>
94    where
95        W: Warn<Warning>,
96        O: FnMut(u16) -> Option<u32>,
97    {
98        let res = self.receiver.snap_empty(wrap(warn), snap);
99        self.inner.handle_msg(warn, object_size, res)
100    }
101    pub fn snap_single<W, O>(
102        &mut self,
103        warn: &mut W,
104        object_size: O,
105        snap: msg::SnapSingle,
106    ) -> Result<Option<&Snap>, Error>
107    where
108        W: Warn<Warning>,
109        O: FnMut(u16) -> Option<u32>,
110    {
111        let res = self.receiver.snap_single(wrap(warn), snap);
112        self.inner.handle_msg(warn, object_size, res)
113    }
114    pub fn snap<W, O>(
115        &mut self,
116        warn: &mut W,
117        object_size: O,
118        snap: msg::Snap,
119    ) -> Result<Option<&Snap>, Error>
120    where
121        W: Warn<Warning>,
122        O: FnMut(u16) -> Option<u32>,
123    {
124        let res = self.receiver.snap(wrap(warn), snap);
125        self.inner.handle_msg(warn, object_size, res)
126    }
127}
128
129impl ManagerInner {
130    fn handle_msg<W, O>(
131        &mut self,
132        warn: &mut W,
133        object_size: O,
134        res: Result<Option<ReceivedDelta>, receiver::Error>,
135    ) -> Result<Option<&Snap>, Error>
136    where
137        W: Warn<Warning>,
138        O: FnMut(u16) -> Option<u32>,
139    {
140        Ok(match res? {
141            Some(delta) => Some(self.add_delta(warn, object_size, delta)?),
142            None => None,
143        })
144    }
145    fn add_delta<W, O>(
146        &mut self,
147        warn: &mut W,
148        object_size: O,
149        delta: ReceivedDelta,
150    ) -> Result<&Snap, Error>
151    where
152        W: Warn<Warning>,
153        O: FnMut(u16) -> Option<u32>,
154    {
155        let crc = delta.data_and_crc.map(|d| d.1);
156        if let Some((data, _)) = delta.data_and_crc {
157            self.temp_delta
158                .read(wrap(warn), object_size, &mut Unpacker::new(data))?;
159        } else {
160            self.temp_delta.clear();
161        }
162        Ok(self.storage.add_delta(
163            wrap(warn),
164            crc,
165            delta.delta_tick,
166            delta.tick,
167            &self.temp_delta,
168        )?)
169    }
170}