|
|
@ -147,7 +147,7 @@ pub enum RoomLobby { |
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct ClientLocation {
|
|
|
|
lobbies: [Arc<RwLock<Lobby>>; 15],
|
|
|
|
rooms: [Option<Arc<RwLock<Room>>>; MAX_ROOMS],
|
|
|
|
rooms: [Arc<RwLock<Option<Room>>>; MAX_ROOMS],
|
|
|
|
client_location: Arc<RwLock<HashMap<ClientId, RoomLobby>>>,
|
|
|
|
}
|
|
|
|
|
|
|
@ -155,7 +155,7 @@ impl Default for ClientLocation { |
|
|
|
fn default() -> ClientLocation {
|
|
|
|
ClientLocation {
|
|
|
|
lobbies: core::array::from_fn(|_| Arc::new(RwLock::new(Lobby([None; 12])))),
|
|
|
|
rooms: core::array::from_fn(|_| None),
|
|
|
|
rooms: core::array::from_fn(|_| Arc::new(RwLock::new(None))),
|
|
|
|
client_location: Arc::new(RwLock::new(HashMap::new())),
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -210,15 +210,16 @@ impl ClientLocation { |
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn create_new_room(&mut self, id: ClientId) -> Result<RoomId, CreateRoomError> {
|
|
|
|
let (index, empty_slot) = self.rooms.iter_mut()
|
|
|
|
let (index, empty_slot) = Box::pin(stream::iter(self.rooms.iter())
|
|
|
|
.enumerate()
|
|
|
|
.find(|(_, r)| r.is_none())
|
|
|
|
.filter(|(_, r)| async {r.read().await.is_none()}))
|
|
|
|
.next()
|
|
|
|
.await
|
|
|
|
.ok_or(CreateRoomError::NoOpenSlots)?;
|
|
|
|
*empty_slot = Some(Arc::new(RwLock::new(Room([None; 4]))));
|
|
|
|
*empty_slot.write().await = Some(Room([None; 4]));
|
|
|
|
self.add_client_to_room(id, RoomId(index))
|
|
|
|
.await
|
|
|
|
.map_err(|_err| CreateRoomError::JoinError)?;
|
|
|
|
|
|
|
|
Ok(RoomId(index))
|
|
|
|
}
|
|
|
|
|
|
|
@ -226,9 +227,10 @@ impl ClientLocation { |
|
|
|
let mut r = self.rooms.get(room.0)
|
|
|
|
.ok_or(JoinRoomError::RoomDoesNotExist)?
|
|
|
|
.as_ref()
|
|
|
|
.ok_or(JoinRoomError::RoomDoesNotExist)?
|
|
|
|
.write()
|
|
|
|
.await;
|
|
|
|
let r = r.as_mut()
|
|
|
|
.ok_or(JoinRoomError::RoomDoesNotExist)?;
|
|
|
|
let (index, empty_slot) = r.0.iter_mut()
|
|
|
|
.enumerate()
|
|
|
|
.find(|(_, k)| k.is_none())
|
|
|
@ -293,9 +295,9 @@ impl ClientLocation { |
|
|
|
pub async fn get_room_leader(&self, room: RoomId) -> Result<AreaClient, GetLeaderError> {
|
|
|
|
let r = self.rooms[room.0]
|
|
|
|
.as_ref()
|
|
|
|
.ok_or(GetLeaderError::InvalidArea)?
|
|
|
|
.read()
|
|
|
|
.await;
|
|
|
|
.await
|
|
|
|
.ok_or(GetLeaderError::InvalidArea)?;
|
|
|
|
let mut r = r
|
|
|
|
.0
|
|
|
|
.iter()
|
|
|
@ -368,9 +370,9 @@ impl ClientLocation { |
|
|
|
Ok(self.rooms.get(room.0)
|
|
|
|
.ok_or(GetClientsError::InvalidArea)?
|
|
|
|
.as_ref()
|
|
|
|
.ok_or(GetClientsError::InvalidArea)?
|
|
|
|
.read()
|
|
|
|
.await
|
|
|
|
.ok_or(GetClientsError::InvalidArea)?
|
|
|
|
.0
|
|
|
|
.iter()
|
|
|
|
.filter_map(|client| {
|
|
|
@ -456,9 +458,13 @@ impl ClientLocation { |
|
|
|
.ok_or(ClientRemovalError::ClientNotInArea)?;
|
|
|
|
match area {
|
|
|
|
RoomLobby::Room(room) => {
|
|
|
|
let r = self.rooms.get(room.0).ok_or(ClientRemovalError::InvalidArea)?;
|
|
|
|
if let Some(r) = r {
|
|
|
|
remove_client(id, &mut r.write().await.0)
|
|
|
|
let mut r = self.rooms.get(room.0)
|
|
|
|
.ok_or(ClientRemovalError::InvalidArea)?
|
|
|
|
.as_ref()
|
|
|
|
.write()
|
|
|
|
.await;
|
|
|
|
if let Some(r) = r.as_mut() {
|
|
|
|
remove_client(id, &mut r.0)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Err(ClientRemovalError::InvalidArea)
|
|
|
|