use crate::common::serverstate::ClientId; // TODO: room passwords? // TODO: remove clients from areas (or upon insert, remove that id from anywhere else) #[derive(Copy, Clone)] pub struct ClientArea { clients: [Option; N], } impl ClientArea<{N}> { pub fn new() -> ClientArea<{N}> { let mut clients: [std::mem::MaybeUninit>; N] = unsafe { std::mem::MaybeUninit::uninit().assume_init() }; for i in clients.iter_mut() { i.write(None); } ClientArea { clients: unsafe { (&clients as *const _ as *const [Option; N]).read()} } } fn add(&mut self, id: ClientId) -> Option { for (i, client) in self.clients.iter_mut().enumerate() { if client.is_none() { *client = Some(id); return Some(i); } } return None; } fn remove(&mut self, id: ClientId) { for client in self.clients.iter_mut() { if *client == Some(id) { *client = None } } } } pub type Lobby = ClientArea<12>; pub type Room = ClientArea<4>; pub type LobbyId = usize; pub type RoomId = usize; pub struct ClientLocation { lobbies: [Lobby; 15], rooms: [Option; 128], } pub enum JoinRoomError { RoomDoesNotExist, RoomFull, } pub enum JoinLobbyError { LobbyDoesNotExist, LobbyFull, } impl ClientLocation { pub fn new() -> ClientLocation { ClientLocation { lobbies: [Lobby::new(); 15], rooms: [None; 128], } } pub fn add_to_lobby(&mut self, id: ClientId, lobby: LobbyId) -> Result { self.lobbies.get_mut(lobby) .ok_or(JoinLobbyError::LobbyDoesNotExist)? .add(id) .ok_or(JoinLobbyError::LobbyFull) } pub fn add_to_room(&mut self, id: ClientId, room: RoomId) -> Result { self.rooms.get_mut(room) .ok_or(JoinRoomError::RoomDoesNotExist)? .as_mut() .ok_or(JoinRoomError::RoomDoesNotExist)? .add(id) .ok_or(JoinRoomError::RoomFull) } pub fn get_client_neighbors(&self, id: ClientId) -> Vec { for lobby in self.lobbies.iter() { if lobby.clients.contains(&Some(id)) { return lobby.clients.iter().filter(|c| c.is_some()).map(|c| c.unwrap()).collect(); } } for room in self.rooms.iter() { if let Some(room) = room { if room.clients.contains(&Some(id)) { return room.clients.iter().filter(|c| c.is_some()).map(|c| c.unwrap()).collect(); } } } panic!() } }