tuxman/src/rooms.rs
2023-06-12 23:47:43 -04:00

60 lines
1.6 KiB
Rust

use std::collections::HashMap;
use axum::extract::ws::WebSocket;
use tokio::sync::mpsc;
use tokio::sync::oneshot;
use super::room;
pub enum RoomServiceRequest {
Exists(String, oneshot::Sender<bool>),
Join(String, WebSocket),
Remove(String),
}
pub type RoomService = mpsc::Sender<RoomServiceRequest>;
type RoomMap = HashMap<String, room::Room>;
async fn handle_room_server_message(rooms: &mut RoomMap, req: RoomServiceRequest, tx: RoomService) {
match req {
// check whether a given room exists
// the sender must provide a tokio::sync::oneshot sender to receive a response
RoomServiceRequest::Exists(code, reply) => {
reply.send(rooms.get(&code).is_some()).ok();
},
// send a websocket into the given room, starting it if it doesn't exist
RoomServiceRequest::Join(code, ws) => {
let room = match rooms.get(&code) {
Some(rm) => rm,
None => {
let rm = room::start_room(code.clone(), tx);
rooms.insert(code.clone(), rm);
&rooms[&code]
}
};
room::add_connection(room, ws).await;
},
// remove a room (called by the room task itself once there are no more connections to it)
RoomServiceRequest::Remove(code) => {
rooms.remove(&code);
}
}
}
// a task to manage a hashmap holding the room task senders
// returns a sender to interface with the task
pub fn start_room_server() -> RoomService {
let (tx, mut rx) = mpsc::channel::<RoomServiceRequest>(10);
let txret = tx.clone();
tokio::spawn(async move {
let mut rooms: RoomMap = HashMap::new();
while let Some(req) = rx.recv().await {
handle_room_server_message(&mut rooms, req, tx.clone()).await;
}
});
txret
}