use bevy::prelude::*;
use bytes::Bytes;
use log::trace;
#[derive(Resource, Default)]
pub struct ServerMessages {
received_messages: Vec<Vec<(Entity, Bytes)>>,
sent_messages: Vec<(Entity, usize, Bytes)>,
}
impl ServerMessages {
pub(crate) fn setup_client_channels(&mut self, channels_count: usize) {
self.received_messages.resize(channels_count, Vec::new());
}
pub(crate) fn remove_client(&mut self, client: Entity) {
for receive_channel in &mut self.received_messages {
receive_channel.retain(|&(entity, _)| entity != client);
}
self.sent_messages.retain(|&(entity, ..)| entity != client);
}
pub(crate) fn receive<I: Into<usize>>(
&mut self,
channel_id: I,
) -> impl Iterator<Item = (Entity, Bytes)> + '_ {
let channel_id = channel_id.into();
let channel_messages = self
.received_messages
.get_mut(channel_id)
.unwrap_or_else(|| panic!("server should have a receive channel with id {channel_id}"));
if !channel_messages.is_empty() {
trace!(
"received {} message(s) totaling {} bytes from channel {channel_id}",
channel_messages.len(),
channel_messages
.iter()
.map(|(_, bytes)| bytes.len())
.sum::<usize>()
);
}
channel_messages.drain(..)
}
pub fn send<I: Into<usize>, B: Into<Bytes>>(
&mut self,
client: Entity,
channel_id: I,
message: B,
) {
let channel_id = channel_id.into();
let message: Bytes = message.into();
trace!("sending {} bytes over channel {channel_id}", message.len());
self.sent_messages.push((client, channel_id, message));
}
pub(crate) fn retain_sent<F>(&mut self, f: F)
where
F: FnMut(&(Entity, usize, Bytes)) -> bool,
{
self.sent_messages.retain(f)
}
pub fn drain_sent(&mut self) -> impl Iterator<Item = (Entity, usize, Bytes)> + '_ {
self.sent_messages.drain(..)
}
pub fn insert_received<I: Into<usize>, B: Into<Bytes>>(
&mut self,
client: Entity,
channel_id: I,
message: B,
) {
let channel_id = channel_id.into();
let receive_channel = self
.received_messages
.get_mut(channel_id)
.unwrap_or_else(|| panic!("server should have a receive channel with id {channel_id}"));
receive_channel.push((client, message.into()));
}
pub(crate) fn clear(&mut self) {
for receive_channel in &mut self.received_messages {
receive_channel.clear();
}
self.sent_messages.clear();
}
}