1use std::sync::Arc;
2use tokio::{
3 sync::{mpsc::UnboundedSender, Mutex},
4 time::sleep,
5};
6
7use crate::{HandleResult, Handler, RoomId, Task, Tasks};
8
9pub enum TaskMessage<H: Handler> {
11 Result(RoomId, HandleResult<H::Param>),
12}
13
14pub fn handle_tasks<H: Handler>(
16 room_id: RoomId,
17 tasks: Tasks<H>,
18 handler: Arc<Mutex<H>>,
19 sender: UnboundedSender<TaskMessage<H>>,
20) {
21 for task in tasks {
22 tokio::spawn(running(room_id, task, handler.clone(), sender.clone()));
23 }
24}
25
26async fn running<H: Handler>(
28 room_id: RoomId,
29 mut task: Box<dyn Task<H = H>>,
30 handler: Arc<Mutex<H>>,
31 sender: UnboundedSender<TaskMessage<H>>,
32) {
33 loop {
34 sleep(std::time::Duration::from_secs(task.timer())).await;
35
36 let mut handler_lock = handler.lock().await;
37 if let Ok(res) = task.run(&mut handler_lock).await {
38 let over = res.over;
39 let _ = sender.send(TaskMessage::Result(room_id, res));
40 if over {
41 drop(handler_lock);
42 break;
43 }
44 } else {
45 drop(handler_lock);
46 break;
47 }
48 drop(handler_lock);
49 }
50}