use std::fmt::Debug;
use bytes::Bytes;
use web_time::Duration;
use crate::{
client::ClientState,
lane::LaneIndex,
server::{ServerEvent, ServerState, ServerTransport},
};
use super::{Conditioner, ConditionerConfig};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "bevy", derive(bevy_ecs::prelude::Resource))]
pub struct ConditionedServer<T: ServerTransport> {
inner: T,
cond: Conditioner<(T::ClientKey, Bytes, LaneIndex)>,
}
impl<T: ServerTransport> ConditionedServer<T> {
#[must_use]
pub fn new(inner: T, config: &ConditionerConfig) -> Self {
Self {
inner,
cond: Conditioner::new(config),
}
}
pub const fn inner(&self) -> &T {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn set_config(&mut self, config: &ConditionerConfig) {
self.cond.set_config(config);
}
}
impl<T: ServerTransport> ServerTransport for ConditionedServer<T> {
type Error = T::Error;
type Opening<'this> = T::Opening<'this> where Self: 'this;
type Open<'this> = T::Open<'this> where Self: 'this;
type Connecting<'this> = T::Connecting<'this> where Self: 'this;
type Connected<'this> = T::Connected<'this> where Self: 'this;
type ClientKey = T::ClientKey;
type MessageKey = T::MessageKey;
fn state(&self) -> ServerState<Self::Opening<'_>, Self::Open<'_>> {
self.inner.state()
}
fn client_state(
&self,
client_key: Self::ClientKey,
) -> ClientState<Self::Connecting<'_>, Self::Connected<'_>> {
self.inner.client_state(client_key)
}
fn client_keys(&self) -> impl Iterator<Item = Self::ClientKey> + '_ {
self.inner.client_keys()
}
fn send(
&mut self,
client_key: Self::ClientKey,
msg: impl Into<Bytes>,
lane: impl Into<LaneIndex>,
) -> Result<Self::MessageKey, Self::Error> {
self.inner.send(client_key, msg, lane)
}
fn flush(&mut self) -> Result<(), Self::Error> {
self.inner.flush()
}
fn disconnect(
&mut self,
client_key: Self::ClientKey,
reason: impl Into<String>,
) -> Result<(), Self::Error> {
self.inner.disconnect(client_key, reason)
}
fn close(&mut self, reason: impl Into<String>) -> Result<(), Self::Error> {
self.inner.close(reason)
}
fn poll(&mut self, delta_time: Duration) -> impl Iterator<Item = ServerEvent<Self>> {
let mut events = Vec::<ServerEvent<Self>>::new();
events.extend(
self.cond
.buffered()
.map(|(client_key, msg, lane)| ServerEvent::Recv {
client_key,
msg,
lane,
}),
);
for event in self.inner.poll(delta_time) {
let event = match event {
ServerEvent::Recv {
client_key,
msg,
lane,
} => self.cond.condition((client_key.clone(), msg, lane)).map(
|(client_key, msg, lane)| ServerEvent::Recv {
client_key,
msg,
lane,
},
),
event => Some(event.remap()),
};
if let Some(event) = event {
events.push(event);
}
}
events.into_iter()
}
}