summaryrefslogtreecommitdiff
path: root/src/rooms.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/rooms.rs')
-rw-r--r--src/rooms.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/rooms.rs b/src/rooms.rs
new file mode 100644
index 0000000..c8199d1
--- /dev/null
+++ b/src/rooms.rs
@@ -0,0 +1,59 @@
+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
+}