use std::collections::BTreeMap;
use crate::{intent::Intent, packet::PacketHeader, replay::ReplayWindow};
pub struct Receiver {
expected_seq: u32,
buffer: BTreeMap<u32, Vec<u8>>,
buffer_size_bytes: usize,
replay: ReplayWindow,
}
impl Receiver {
pub fn new() -> Self {
Self {
expected_seq: 1,
buffer: BTreeMap::new(),
buffer_size_bytes: 0,
replay: ReplayWindow::new(1024),
}
}
}
impl Default for Receiver {
fn default() -> Self {
Self::new()
}
}
impl Receiver {
pub fn accept(&mut self, seq: u32) -> bool {
self.replay.check(seq)
}
pub fn deliver(
&mut self,
header: PacketHeader,
payload: Vec<u8>,
mut on_deliver: impl FnMut(Vec<u8>),
) {
match header.intent {
Intent::Realtime => {
on_deliver(payload);
}
Intent::Reliable => {
if header.seq == self.expected_seq {
on_deliver(payload);
self.expected_seq = self.expected_seq.wrapping_add(1);
while let Some(buffered) = self.buffer.remove(&self.expected_seq) {
let sz = buffered.len();
self.buffer_size_bytes = self.buffer_size_bytes.saturating_sub(sz);
on_deliver(buffered);
self.expected_seq = self.expected_seq.wrapping_add(1);
}
} else {
self.buffer_size_bytes += payload.len();
self.buffer.insert(header.seq, payload);
}
}
}
}
pub fn pending_reliable(&self) -> usize {
self.buffer.len()
}
pub fn buffer_size(&self) -> usize {
self.buffer_size_bytes
}
}