My personal project and infrastructure archive
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
nomicon/src/lobby.rs

87 lines
2.1 KiB

//! 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);
}
}