use crate::{Identity, Tick};
use bevy::prelude::Resource;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SendRule {
All,
Except(u32),
Only(u32),
List(Vec<u32>),
}
impl SendRule {
pub fn filter_to(self, new_clients: &[u32]) -> Option<SendRule> {
if new_clients.is_empty() {
return None;
}
match self {
Self::All => Some(Self::List(new_clients.to_vec())),
Self::Except(c) => {
let list: Vec<u32> = new_clients
.iter()
.filter(|new_c| **new_c != c)
.cloned()
.collect();
if list.is_empty() {
return None;
}
Some(Self::List(list))
}
Self::Only(c) => {
if new_clients.contains(&c) {
Some(self)
} else {
None
}
}
Self::List(mut list) => {
list.retain(|c| new_clients.contains(c));
if list.is_empty() {
return None;
}
Some(Self::List(list))
}
}
}
pub fn includes(&self, ident: Identity) -> bool {
match self {
Self::All => true,
Self::Except(client_id) => ident != Identity::Client(*client_id),
Self::Only(client_id) => ident == Identity::Client(*client_id),
Self::List(list) => {
if let Identity::Client(client_id) = ident {
list.contains(&client_id)
} else {
false
}
}
}
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BufferKey {
pub channel: u8,
pub rule: SendRule,
}
impl BufferKey {
pub fn new(channel: u8, rule: SendRule) -> Self {
Self { channel, rule }
}
}
const CAP: usize = 1198;
#[derive(Resource, Default)]
pub struct Buffers {
map: bevy::utils::HashMap<BufferKey, usize>,
pub(crate) buffers: Vec<(BufferKey, Vec<u8>)>,
}
impl<'a> Buffers {
pub(crate) fn clear(&mut self) {
self.map.clear();
}
pub fn reserve_mut(&'a mut self, key: BufferKey, len: usize, tick: Tick) -> &'a mut Vec<u8> {
if let Some(n) = self.map.get_mut(&key) {
if self.buffers[*n].1.len() + len <= CAP {
return &mut self.buffers[*n].1;
}
self.buffers.push((key, Vec::with_capacity(CAP)));
*n = self.buffers.len() - 1;
self.buffers[*n].1.extend_from_slice(&(*tick).to_le_bytes());
return &mut self.buffers[*n].1;
}
self.buffers.push((key.clone(), Vec::with_capacity(CAP)));
let n = self.buffers.len() - 1;
self.buffers[n].1.extend_from_slice(&(*tick).to_le_bytes());
self.map.insert(key, n);
&mut self.buffers[n].1
}
}