naia_shared/connection/
bandwidth_monitor.rs

1use std::time::Duration;
2
3pub struct BandwidthMonitor {
4    time_queue: ExpiringTimeQueue<usize>,
5    total_bytes: u16,
6    to_kbps_factor: f32,
7}
8
9impl BandwidthMonitor {
10    pub fn new(bandwidth_measure_duration: Duration) -> Self {
11        Self {
12            time_queue: ExpiringTimeQueue::new(bandwidth_measure_duration),
13            total_bytes: 0,
14            to_kbps_factor: 0.008 / bandwidth_measure_duration.as_secs_f32(),
15        }
16    }
17
18    pub fn record_packet(&mut self, bytes: usize) {
19        self.clear_expired_packets();
20
21        self.total_bytes += bytes as u16;
22        self.time_queue.add_item(bytes);
23    }
24
25    pub fn bandwidth(&mut self) -> f32 {
26        self.clear_expired_packets();
27
28        self.total_bytes as f32 * self.to_kbps_factor
29    }
30
31    fn clear_expired_packets(&mut self) {
32        let now = Instant::now();
33        while let Some(bytes) = self.time_queue.pop_item(&now) {
34            self.total_bytes -= bytes as u16;
35        }
36    }
37}
38
39////
40
41use naia_socket_shared::{Instant, TimeQueue};
42
43#[derive(Clone)]
44struct ExpiringTimeQueue<T: Eq + PartialEq> {
45    queue: TimeQueue<T>,
46    expire_time: Duration,
47}
48
49impl<T: Eq + PartialEq> ExpiringTimeQueue<T> {
50    pub fn new(duration: Duration) -> Self {
51        Self {
52            queue: TimeQueue::new(),
53            expire_time: duration,
54        }
55    }
56
57    pub fn add_item(&mut self, item: T) {
58        let mut instant = Instant::now();
59        instant.add_millis(self.expire_time.as_millis() as u32);
60        self.queue.add_item(instant, item);
61    }
62
63    pub fn pop_item(&mut self, now: &Instant) -> Option<T> {
64        self.queue.pop_item(now)
65    }
66}