libtw2_snapshot/
manager.rs1use 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}