use crate::wire::{ game::{Action, Update}, Lobby, }; use async_std::sync::RwLock; use std::collections::VecDeque; pub enum ClientUpdate { /// Change to the lobby state Lobby(Lobby), /// A game simulation update GameUpdate(Update), } impl<'l> From<&'l Lobby> for ClientUpdate { fn from(l: &'l Lobby) -> Self { ClientUpdate::Lobby(l.clone()) } } impl<'l> From<&'l Update> for ClientUpdate { fn from(u: &'l Update) -> Self { ClientUpdate::GameUpdate(u.clone()) } } /// A message out buffer that can be attached to any server entity pub struct Outbox { queue: RwLock>, } impl Outbox { pub fn new() -> Self { Self { queue: Default::default(), } } /// Queue a new item to send out pub async fn queue(&self, update: impl Into) { let mut q = self.queue.write().await; q.push_back(update.into()); } /// Run a closure for all queued items pub async fn run_for(&self, handle: F) { let q = self.queue.read().await; q.iter().for_each(|item| handle(item)); } /// Clear the outbox for the next update interval pub async fn clear(&self) { self.queue.write().await.clear(); } } pub struct Inbox { queue: RwLock>, } impl Inbox { pub fn new() -> Self { Self { queue: Default::default(), } } /// Queue a new item to send out pub async fn queue(&self, update: impl Into) { let mut q = self.queue.write().await; q.push_back(update.into()); } pub async fn pop(&self) -> Option { self.queue.write().await.pop_front() } }