107 lines
2.7 KiB
Rust
Raw Normal View History

2019-11-23 19:01:03 -08:00
use crate::common::serverstate::ClientId;
// TODO: room passwords?
#[derive(Copy, Clone)]
pub struct ClientArea<const N: usize> {
clients: [Option<ClientId>; N],
}
impl<const N: usize> ClientArea<{N}> {
pub fn new() -> ClientArea<{N}> {
let mut clients: [std::mem::MaybeUninit<Option<ClientId>>; 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<ClientId>; N]).read()}
}
}
fn add(&mut self, id: ClientId) -> Option<usize> {
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<Room>; 128],
}
enum JoinRoomError {
RoomDoesNotExist,
RoomFull,
}
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<usize, JoinLobbyError> {
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<usize, JoinRoomError> {
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<ClientId> {
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!()
}
}