mahjong_service/
games_loop.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#![allow(clippy::await_holding_lock)]
use crate::common::Storage;
use crate::game_wrapper::GameWrapper;
use crate::http_server::GamesManager;
use crate::socket::{MahjongWebsocketServer, SocketMessageListSessions};
use actix::{spawn, Addr};
use actix_web::rt::time;
use actix_web::web;
use std::sync::{Arc, Mutex};
use std::time::Duration;

pub struct GamesLoop {
    storage: Arc<Box<dyn Storage>>,
    socket: Arc<Mutex<Addr<MahjongWebsocketServer>>>,
    manager: Arc<Mutex<GamesManager>>,
}

impl GamesLoop {
    pub fn new(
        storage: Arc<Box<dyn Storage>>,
        socket: Arc<Mutex<Addr<MahjongWebsocketServer>>>,
        manager: Arc<Mutex<GamesManager>>,
    ) -> Self {
        Self {
            manager,
            socket,
            storage,
        }
    }

    pub fn run(&self) {
        let storage = self.storage.clone();
        let socket = self.socket.clone();
        let manager = self.manager.clone();

        spawn(async move {
            let mut interval = time::interval(Duration::from_millis(1000));

            loop {
                interval.tick().await;
                let message_response;
                {
                    let server = socket.lock();
                    if server.is_err() {
                        continue;
                    }
                    message_response = server.unwrap().send(SocketMessageListSessions);
                }

                let sessions = message_response.await.unwrap();

                for room in sessions.keys() {
                    let game_id = room.split('_').collect::<Vec<&str>>()[0];
                    let game_id = web::Path::from(game_id.to_string());
                    let storage = web::Data::new(storage.clone());
                    let server = web::Data::new(socket.clone());

                    let game_lock = { manager.lock().unwrap().get_game_mutex(&game_id) };
                    let _game_lock = game_lock.lock().unwrap();

                    let game_wrapper =
                        GameWrapper::from_storage(&storage, &game_id, server, None).await;

                    if game_wrapper.is_err() {
                        continue;
                    }

                    let _ = game_wrapper.unwrap().handle_server_ai_continue().await;
                }
            }
        });
    }
}