diff options
Diffstat (limited to 'src/lobby.rs')
-rw-r--r-- | src/lobby.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/lobby.rs b/src/lobby.rs new file mode 100644 index 000000000000..ac6ab305414a --- /dev/null +++ b/src/lobby.rs @@ -0,0 +1,87 @@ +//! 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<BTreeMap<LobbyId, Arc<MetaLobby>>>, +} + +/// 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<Color>, + 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); + } +} |