aboutsummaryrefslogtreecommitdiff
path: root/src/lobby.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lobby.rs')
-rw-r--r--src/lobby.rs87
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);
+ }
+}