use serde::{de::DeserializeOwned, Serialize};
use std::{error::Error, fmt::Debug};
use crate::{clocksync::ClockSyncMessage, timestamp::Timestamped, world::World};
pub type ConnectionHandleType = usize;
pub trait NetworkResource<WorldType: World> {
type ConnectionType<'a>: Connection<WorldType>
where
Self: 'a,
WorldType: 'a;
fn connections<'a>(
&'a mut self,
) -> Box<dyn Iterator<Item = (ConnectionHandleType, Self::ConnectionType<'a>)> + 'a>;
fn get_connection(&mut self, handle: ConnectionHandleType) -> Option<Self::ConnectionType<'_>>;
fn broadcast_message<MessageType>(&mut self, message: MessageType)
where
MessageType: Debug + Clone + Serialize + DeserializeOwned + Send + Sync + 'static,
{
for (_, mut connection) in self.connections() {
connection.send(message.clone());
connection.flush::<MessageType>();
}
}
fn send_message<MessageType>(
&mut self,
handle: ConnectionHandleType,
message: MessageType,
) -> Result<Option<MessageType>, Box<dyn Error + Send>>
where
MessageType: Debug + Clone + Serialize + DeserializeOwned + Send + Sync + 'static,
{
match self.get_connection(handle) {
Some(mut connection) => {
let unsent = connection.send(message);
connection.flush::<MessageType>();
Ok(unsent)
}
None => Err(Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"No such connection",
))),
}
}
}
pub trait Connection<WorldType: World> {
fn recv_command(&mut self) -> Option<Timestamped<WorldType::CommandType>>;
fn recv_snapshot(&mut self) -> Option<Timestamped<WorldType::SnapshotType>>;
fn recv_clock_sync(&mut self) -> Option<ClockSyncMessage>;
fn send<MessageType>(&mut self, message: MessageType) -> Option<MessageType>
where
MessageType: Debug + Clone + Serialize + DeserializeOwned + Send + Sync + 'static;
fn flush<MessageType>(&mut self)
where
MessageType: Debug + Clone + Serialize + DeserializeOwned + Send + Sync + 'static;
}