dreamwell_runtime/
mirror.rs1pub const MAX_MIRROR_ENTITIES: usize = 65536;
8
9#[derive(Debug, Default)]
13pub struct ClientMirror {
14 pub positions: Vec<[f32; 3]>,
16 pub rotations: Vec<[f32; 4]>,
18 pub entity_count: usize,
20 pub tick: u64,
22 pub(crate) pending_despawns: Vec<usize>,
25}
26
27impl ClientMirror {
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn apply_snapshot(&mut self, positions: Vec<[f32; 3]>, rotations: Vec<[f32; 4]>) {
34 let cap = positions.len().min(MAX_MIRROR_ENTITIES);
35 self.entity_count = cap;
36 self.positions = positions;
37 self.positions.truncate(cap);
38 self.rotations = rotations;
39 self.rotations.truncate(cap);
40 }
41
42 pub fn advance_tick(&mut self) {
44 self.tick += 1;
45 }
46
47 pub(crate) fn queue_despawn(&mut self, slot: usize) {
49 self.pending_despawns.push(slot);
50 }
51
52 pub(crate) fn flush_despawns(&mut self) {
55 self.pending_despawns.sort_unstable();
56 self.pending_despawns.dedup();
57 for &slot in self.pending_despawns.iter().rev() {
59 if slot < self.positions.len() {
60 self.positions.swap_remove(slot);
61 self.rotations.swap_remove(slot);
62 }
63 }
64 self.entity_count = self.positions.len();
65 self.pending_despawns.clear();
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn default_mirror() {
75 let m = ClientMirror::new();
76 assert_eq!(m.entity_count, 0);
77 assert_eq!(m.tick, 0);
78 }
79
80 #[test]
81 fn apply_snapshot() {
82 let mut m = ClientMirror::new();
83 m.apply_snapshot(vec![[1.0, 2.0, 3.0]], vec![[0.0, 0.0, 0.0, 1.0]]);
84 assert_eq!(m.entity_count, 1);
85 }
86
87 #[test]
88 fn snapshot_respects_cap() {
89 let mut m = ClientMirror::new();
90 let big: Vec<[f32; 3]> = (0..MAX_MIRROR_ENTITIES + 100).map(|i| [i as f32, 0.0, 0.0]).collect();
91 let rots: Vec<[f32; 4]> = vec![[0.0, 0.0, 0.0, 1.0]; big.len()];
92 m.apply_snapshot(big, rots);
93 assert_eq!(m.entity_count, MAX_MIRROR_ENTITIES);
94 assert_eq!(m.positions.len(), MAX_MIRROR_ENTITIES);
95 }
96
97 #[test]
98 fn deferred_despawn_reverse_order() {
99 let mut m = ClientMirror::new();
100 m.positions = vec![[0.0; 3]; 5];
101 m.rotations = vec![[0.0, 0.0, 0.0, 1.0]; 5];
102 m.entity_count = 5;
103 m.queue_despawn(1);
104 m.queue_despawn(3);
105 m.flush_despawns();
106 assert_eq!(m.entity_count, 3);
107 }
108}