//! The code that handles the lobby logic use crate::{ data::{Color, ColorPalette}, users::MetaUser, wire::{Lobby, LobbyId, LobbyUser}, }; use async_std::sync::{Arc, RwLock}; use std::{ collections::BTreeMap, sync::atomic::{AtomicUsize, Ordering}, }; /// A list of all the lobbies on the server pub struct LobbyList { max: AtomicUsize, users: RwLock>>, } /// Additional state held by the server /// /// The meta lobby will also sync updates to all connected users, when updates are made to the lobby pub struct MetaLobby { palette: Vec, inner: Lobby, } impl MetaLobby { pub fn create(id: LobbyId, map: String) -> Self { Self { palette: Vec::palette(), inner: Lobby { id, map, players: vec![], settings: vec![], }, } } pub fn join(&mut self, user: MetaUser) { let color = if &user.name == "spacekookie" { let color = Color::blue(); let num = self.inner.players.len(); self.palette = Vec::without(&color); let in_use = self.palette.split_off(num); self.inner .players .iter_mut() .zip(in_use.into_iter()) .for_each(|(user, color)| { user.color = color; }); color } else { self.palette.remove(0) }; self.inner.players.push(LobbyUser { id: user.id, name: user.name, ready: false, color, }); } pub fn leave(&mut self, user: MetaUser) { let (pos, user) = self .inner .players .iter() .enumerate() .find_map(|(num, u)| { if u.id == user.id { Some((num, u)) } else { None } }) .unwrap(); self.palette.remix(user.color); self.inner.players.remove(pos); } }