naia_shared/connection/
ping_store.rs

1use std::collections::VecDeque;
2
3use crate::{sequence_greater_than, GameInstant};
4
5pub type PingIndex = u16;
6
7const SENT_PINGS_HISTORY_SIZE: u16 = 32;
8
9pub struct PingStore {
10    ping_index: PingIndex,
11    // front big, back small
12    // front recent, back past
13    buffer: VecDeque<(PingIndex, GameInstant)>,
14}
15
16impl PingStore {
17    pub fn new() -> Self {
18        PingStore {
19            ping_index: 0,
20            buffer: VecDeque::new(),
21        }
22    }
23
24    pub fn push_new(&mut self, now: GameInstant) -> PingIndex {
25        // save current ping index and add a new ping instant associated with it
26        let ping_index = self.ping_index;
27        self.ping_index = self.ping_index.wrapping_add(1);
28        self.buffer.push_front((ping_index, now));
29
30        // a good time to prune down the size of this buffer
31        while self.buffer.len() > SENT_PINGS_HISTORY_SIZE.into() {
32            self.buffer.pop_back();
33        }
34
35        ping_index
36    }
37
38    pub fn remove(&mut self, ping_index: PingIndex) -> Option<GameInstant> {
39        let mut vec_index = self.buffer.len();
40
41        if vec_index == 0 {
42            return None;
43        }
44
45        let mut found = false;
46
47        loop {
48            vec_index -= 1;
49
50            if let Some((old_index, _)) = self.buffer.get(vec_index) {
51                if *old_index == ping_index {
52                    //found it!
53                    found = true;
54                } else {
55                    // if old_index is bigger than ping_index, give up, it's only getting
56                    // bigger
57                    if sequence_greater_than(*old_index, ping_index) {
58                        return None;
59                    }
60                }
61            }
62
63            if found {
64                let (_, ping_instant) = self.buffer.remove(vec_index).unwrap();
65                return Some(ping_instant);
66            }
67
68            // made it to the front
69            if vec_index == 0 {
70                return None;
71            }
72        }
73    }
74
75    pub fn clear(&mut self) {
76        self.buffer.clear();
77    }
78}