#[cfg(feature = "server")]
pub mod local;
#[cfg(all(not(feature = "server"), feature = "client"))]
pub mod remote;
use std::{
collections::BTreeMap,
fmt,
sync::{atomic::AtomicU32, mpsc, Arc},
};
use crate::{
client::{Client, ClientId},
packet::{CreateInstance, Packet, TrustedPacket},
App, Context,
};
pub type Owners = BTreeMap<InstanceId, ClientId>;
struct Server<M> {
packet_rx: mpsc::Receiver<Packet<M>>,
packet_tx: mpsc::Sender<TrustedPacket<M>>,
client_tx: mpsc::Sender<Client>,
client_rx: mpsc::Receiver<Client>,
clients: BTreeMap<ClientId, Client>,
instances: BTreeMap<InstanceId, CreateInstance>,
owners: Owners,
next_instance_id: Arc<AtomicU32>,
}
impl<M> Server<M> {
pub(crate) fn new(
packet_rx: mpsc::Receiver<Packet<M>>,
packet_tx: mpsc::Sender<TrustedPacket<M>>,
client_tx: mpsc::Sender<Client>,
client_rx: mpsc::Receiver<Client>,
next_instance_id: Arc<AtomicU32>,
) -> Self {
Self {
packet_rx,
packet_tx,
client_tx,
client_rx,
clients: BTreeMap::new(),
instances: BTreeMap::new(),
owners: BTreeMap::new(),
next_instance_id,
}
}
}
impl<M> Context<M> {
pub fn send_packet(&self, packet: Packet<M>) {
self.packet_tx.send(packet).unwrap();
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, bitcode::Encode, bitcode::Decode)]
pub struct InstanceId(u32);
impl InstanceId {
pub const NONE: Self = Self(u32::MAX);
#[must_use]
pub fn new(id: u32) -> Self {
Self(id)
}
}
pub fn run<A: App<M>, M>(
packet_tx: mpsc::Sender<TrustedPacket<M>>,
packet_rx: mpsc::Receiver<Packet<M>>,
next_instance_id: Arc<AtomicU32>,
local: CreateInstance,
) where
M: bitcode::DecodeOwned + bitcode::Encode + fmt::Debug,
{
let (client_tx, client_rx) = mpsc::channel();
let state = Server::new(packet_rx, packet_tx, client_tx, client_rx, next_instance_id);
#[cfg(feature = "server")]
Server::run_listener::<A>(&state);
#[cfg(feature = "server")]
Server::run_server(state, local);
#[cfg(all(not(feature = "server"), feature = "client"))]
Server::run_client::<A>(state);
}