diff -r 8ba2b5007c29 -r e915ed28726e rust/hedgewars-server/src/core/server.rs --- a/rust/hedgewars-server/src/core/server.rs Wed Mar 27 02:19:44 2024 +0300 +++ b/rust/hedgewars-server/src/core/server.rs Wed Mar 27 02:57:44 2024 +0300 @@ -270,7 +270,7 @@ } #[inline] - pub fn get_room_control(&mut self, client_id: ClientId) -> Option { + pub fn get_room_control(&mut self, client_id: ClientId) -> HwRoomOrServer { HwRoomControl::new(self, client_id) } @@ -345,7 +345,15 @@ client_id: ClientId, room_id: RoomId, room_password: Option<&str>, - ) -> Result<(&HwClient, Option<&HwClient>, &HwRoom, impl Iterator + Clone), JoinRoomError> { + ) -> Result< + ( + &HwClient, + Option<&HwClient>, + &HwRoom, + impl Iterator + Clone, + ), + JoinRoomError, + > { use JoinRoomError::*; let room = &mut self.rooms[room_id]; let client = &mut self.clients[client_id]; @@ -382,7 +390,15 @@ client_id: ClientId, room_name: &str, room_password: Option<&str>, - ) -> Result<(&HwClient, Option<&HwClient>, &HwRoom, impl Iterator + Clone), JoinRoomError> { + ) -> Result< + ( + &HwClient, + Option<&HwClient>, + &HwRoom, + impl Iterator + Clone, + ), + JoinRoomError, + > { use JoinRoomError::*; let room = self.rooms.iter().find(|(_, r)| r.name == room_name); if let Some((_, room)) = room { @@ -548,6 +564,21 @@ } } +pub enum HwRoomOrServer<'a> { + Room(HwRoomControl<'a>), + Server(&'a mut HwServer), +} + +impl<'a> HwRoomOrServer<'a> { + #[inline] + pub fn into_room(self) -> Option> { + match self { + HwRoomOrServer::Room(control) => Some(control), + HwRoomOrServer::Server(_) => None, + } + } +} + pub struct HwRoomControl<'a> { server: &'a mut HwServer, client_id: ClientId, @@ -557,23 +588,16 @@ impl<'a> HwRoomControl<'a> { #[inline] - pub fn new(server: &'a mut HwServer, client_id: ClientId) -> Option { + pub fn new(server: &'a mut HwServer, client_id: ClientId) -> HwRoomOrServer { if let Some(room_id) = server.clients[client_id].room_id { - Some(Self { + HwRoomOrServer::Room(Self { server, client_id, room_id, is_room_removed: false, }) } else { - None - } - } - - #[inline] - pub fn cleanup_room(self) { - if self.is_room_removed { - self.server.rooms.remove(self.room_id); + HwRoomOrServer::Server(server) } } @@ -615,11 +639,6 @@ ) } - pub fn change_client<'b: 'a>(self, client_id: ClientId) -> Option> { - let room_id = self.room_id; - HwRoomControl::new(self.server, client_id).filter(|c| c.room_id == room_id) - } - fn remove_from_room(&mut self, client_id: ClientId) -> LeaveRoomResult { let (client, room) = self .server @@ -1132,6 +1151,15 @@ } } +impl<'a> Drop for HwRoomControl<'a> { + #[inline] + fn drop(&mut self) { + if self.is_room_removed { + self.server.rooms.remove(self.room_id); + } + } +} + fn allocate_room(rooms: &mut Slab) -> &mut HwRoom { let entry = rooms.vacant_entry(); let room = HwRoom::new(entry.key());