naia_shared/world/update/
diff_mask.rs1use std::fmt;
2
3#[derive(PartialEq, Eq, Clone, Debug)]
5pub struct DiffMask {
6 mask: Vec<u8>,
7}
8
9impl DiffMask {
10 pub fn new(bytes: u8) -> DiffMask {
12 DiffMask {
13 mask: vec![0; bytes as usize],
14 }
15 }
16
17 pub fn bit(&self, index: u8) -> Option<bool> {
19 if let Some(byte) = self.mask.get((index / 8) as usize) {
20 let adjusted_index = index % 8;
21 return Some(byte & (1 << adjusted_index) != 0);
22 }
23
24 None
25 }
26
27 pub fn set_bit(&mut self, index: u8, value: bool) {
29 if let Some(byte) = self.mask.get_mut((index / 8) as usize) {
30 let adjusted_index = index % 8;
31 let bit_mask = 1 << adjusted_index;
32 if value {
33 *byte |= bit_mask;
34 } else {
35 *byte &= !bit_mask;
36 }
37 }
38 }
39
40 pub fn clear(&mut self) {
42 let size = self.mask.len();
43 self.mask = vec![0; size];
44 }
45
46 pub fn is_clear(&self) -> bool {
48 for byte in self.mask.iter() {
49 if *byte != 0 {
50 return false;
51 }
52 }
53 true
54 }
55
56 pub fn byte_number(&self) -> u8 {
58 self.mask.len() as u8
59 }
60
61 pub fn byte(&self, index: usize) -> u8 {
63 self.mask[index]
64 }
65
66 pub fn nand(&mut self, other: &DiffMask) {
68 if other.byte_number() != self.byte_number() {
72 return;
73 }
74
75 for n in 0..self.mask.len() {
76 if let Some(my_byte) = self.mask.get_mut(n) {
77 let other_byte = !other.byte(n);
78 *my_byte &= other_byte;
79 }
80 }
81 }
82
83 pub fn or(&mut self, other: &DiffMask) {
85 if other.byte_number() != self.byte_number() {
87 return;
88 }
89
90 for n in 0..self.mask.len() {
91 if let Some(my_byte) = self.mask.get_mut(n) {
92 let other_byte = other.byte(n);
93 *my_byte |= other_byte;
94 }
95 }
96 }
97
98 pub fn copy_contents(&mut self, other: &DiffMask) {
100 if other.byte_number() != self.byte_number() {
102 return;
103 }
104
105 for n in 0..self.mask.len() {
106 if let Some(my_byte) = self.mask.get_mut(n) {
107 let other_byte = other.byte(n);
108 *my_byte = other_byte;
109 }
110 }
111 }
112}
113
114impl fmt::Display for DiffMask {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 let mut out_string: String = String::new();
117 for y in 0..8 {
118 if let Some(bit) = self.bit(y) {
119 if bit {
120 out_string.push('1');
121 } else {
122 out_string.push('0');
123 }
124 }
125 }
126 write!(f, "{}", out_string)
127 }
128}
129
130#[cfg(test)]
131mod single_byte_tests {
132 use crate::DiffMask;
133
134 #[test]
135 fn getset() {
136 let mut mask = DiffMask::new(1);
137
138 mask.set_bit(0, true);
139 mask.set_bit(2, true);
140 mask.set_bit(4, true);
141 mask.set_bit(6, true);
142 mask.set_bit(4, false);
143
144 assert!(mask.bit(0).unwrap());
145 assert!(!mask.bit(1).unwrap());
146 assert!(mask.bit(2).unwrap());
147 assert!(!mask.bit(4).unwrap());
148 assert!(mask.bit(6).unwrap());
149 }
150
151 #[test]
152 fn clear() {
153 let mut mask = DiffMask::new(1);
154
155 mask.set_bit(0, true);
156 mask.set_bit(2, true);
157 mask.set_bit(4, true);
158 mask.set_bit(6, true);
159
160 mask.clear();
161
162 assert!(!mask.bit(0).unwrap());
163 assert!(!mask.bit(2).unwrap());
164 assert!(!mask.bit(4).unwrap());
165 assert!(!mask.bit(6).unwrap());
166 }
167
168 #[test]
169 fn is_clear_true() {
170 let mut mask = DiffMask::new(1);
171
172 mask.set_bit(2, true);
173
174 assert!(!mask.is_clear());
175
176 mask.set_bit(2, false);
177
178 assert!(mask.is_clear());
179 }
180
181 #[test]
182 fn bytes() {
183 let mask = DiffMask::new(1);
184 assert!(mask.byte_number() == 1);
185 }
186
187 #[test]
188 fn byte() {
189 let mut mask = DiffMask::new(1);
190 mask.set_bit(2, true);
191 let byte = mask.byte(0);
192 assert!(byte == 4);
193 }
194
195 #[test]
196 fn nand() {
197 let mut mask_a = DiffMask::new(1);
198 mask_a.set_bit(1, true);
199 mask_a.set_bit(2, true);
200
201 let mut mask_b = DiffMask::new(1);
202 mask_b.set_bit(1, true);
203
204 mask_a.nand(&mask_b);
205
206 assert!(!mask_a.bit(0).unwrap());
207 assert!(!mask_a.bit(1).unwrap());
208 assert!(mask_a.bit(2).unwrap());
209 assert!(!mask_a.bit(3).unwrap());
210 }
211
212 #[test]
213 fn or() {
214 let mut mask_a = DiffMask::new(1);
215 mask_a.set_bit(1, true);
216 mask_a.set_bit(2, true);
217
218 let mut mask_b = DiffMask::new(1);
219 mask_b.set_bit(2, true);
220 mask_b.set_bit(3, true);
221
222 mask_a.or(&mask_b);
223
224 assert!(!mask_a.bit(0).unwrap());
225 assert!(mask_a.bit(1).unwrap());
226 assert!(mask_a.bit(2).unwrap());
227 assert!(mask_a.bit(3).unwrap());
228 assert!(!mask_a.bit(4).unwrap());
229 }
230
231 #[test]
232 fn clone() {
233 let mut mask_a = DiffMask::new(1);
234 mask_a.set_bit(1, true);
235 mask_a.set_bit(4, true);
236
237 let mask_b = mask_a.clone();
238
239 assert!(mask_b.bit(1).unwrap());
240 assert!(!mask_b.bit(3).unwrap());
241 assert!(mask_b.bit(4).unwrap());
242 }
243}
244
245#[cfg(test)]
246mod double_byte_tests {
247 use crate::DiffMask;
248
249 #[test]
250 fn getset() {
251 let mut mask = DiffMask::new(2);
252
253 mask.set_bit(0, true);
254 mask.set_bit(4, true);
255 mask.set_bit(8, true);
256 mask.set_bit(12, true);
257 mask.set_bit(8, false);
258
259 assert!(mask.bit(0).unwrap());
260 assert!(mask.bit(4).unwrap());
261 assert!(!mask.bit(8).unwrap());
262 assert!(mask.bit(12).unwrap());
263 assert!(!mask.bit(13).unwrap());
264 }
265
266 #[test]
267 fn clear() {
268 let mut mask = DiffMask::new(2);
269
270 mask.set_bit(0, true);
271 mask.set_bit(4, true);
272 mask.set_bit(8, true);
273 mask.set_bit(12, true);
274
275 mask.clear();
276
277 assert!(!mask.bit(0).unwrap());
278 assert!(!mask.bit(4).unwrap());
279 assert!(!mask.bit(8).unwrap());
280 assert!(!mask.bit(12).unwrap());
281 }
282
283 #[test]
284 fn is_clear_true() {
285 let mut mask = DiffMask::new(2);
286
287 mask.set_bit(9, true);
288
289 assert!(!mask.is_clear());
290
291 mask.set_bit(9, false);
292
293 assert!(mask.is_clear());
294 }
295
296 #[test]
297 fn bytes() {
298 let mask = DiffMask::new(2);
299 assert!(mask.byte_number() == 2);
300 }
301
302 #[test]
303 fn byte() {
304 let mut mask = DiffMask::new(2);
305 mask.set_bit(10, true);
306 let byte = mask.byte(1);
307 assert!(byte == 4);
308 }
309
310 #[test]
311 fn nand() {
312 let mut mask_a = DiffMask::new(2);
313 mask_a.set_bit(1, true);
314 mask_a.set_bit(2, true);
315 mask_a.set_bit(9, true);
316 mask_a.set_bit(10, true);
317
318 let mut mask_b = DiffMask::new(2);
319 mask_b.set_bit(1, true);
320 mask_b.set_bit(9, true);
321
322 mask_a.nand(&mask_b);
323
324 assert!(!mask_a.bit(0).unwrap());
325 assert!(!mask_a.bit(1).unwrap());
326 assert!(mask_a.bit(2).unwrap());
327 assert!(!mask_a.bit(3).unwrap());
328
329 assert!(!mask_a.bit(8).unwrap());
330 assert!(!mask_a.bit(9).unwrap());
331 assert!(mask_a.bit(10).unwrap());
332 assert!(!mask_a.bit(11).unwrap());
333 }
334
335 #[test]
336 fn or() {
337 let mut mask_a = DiffMask::new(2);
338 mask_a.set_bit(4, true);
339 mask_a.set_bit(8, true);
340
341 let mut mask_b = DiffMask::new(2);
342 mask_b.set_bit(8, true);
343 mask_b.set_bit(12, true);
344
345 mask_a.or(&mask_b);
346
347 assert!(!mask_a.bit(0).unwrap());
348 assert!(mask_a.bit(4).unwrap());
349 assert!(mask_a.bit(8).unwrap());
350 assert!(mask_a.bit(12).unwrap());
351 assert!(!mask_a.bit(15).unwrap());
352 }
353
354 #[test]
355 fn clone() {
356 let mut mask_a = DiffMask::new(2);
357 mask_a.set_bit(2, true);
358 mask_a.set_bit(10, true);
359
360 let mask_b = mask_a.clone();
361
362 assert!(mask_b.bit(2).unwrap());
363 assert!(!mask_b.bit(4).unwrap());
364 assert!(!mask_b.bit(9).unwrap());
365 assert!(mask_b.bit(10).unwrap());
366 }
367}