use super::super::super::model::state::room::Room; use super::lobby::Lobby; use super::player::Player; use super::gameevent::GameEvent; use super::gameevent::GameEventType; use std::thread; use std::time; use log::{info, debug, LevelFilter}; pub struct GameMaster { room: Box, lobby: Lobby, } impl GameMaster { pub fn new(room: Box) -> GameMaster { info!("created for room {}", room.room_id()); GameMaster{ room: room, lobby: Lobby::new(), } } pub fn run(&mut self) -> Result { loop { let r = self.run_lobby(); if r.is_ok() { break } } self.run_game_setup()?; self.run_game() } fn run_lobby(&mut self) -> Result { let mut r = self.run_lobby_scrape(); while r.unwrap_or(0) == 0 { //while r.is_ok() && r.unwrap() == 0 { thread::sleep(time::Duration::new(1, 0)); r = self.run_lobby_scrape(); } return Ok(r.unwrap().clone()); /* if r.is_ok() { return Ok(r.unwrap()); } let e = r.err(); Err(e.unwrap()) */ } fn run_lobby_scrape(&mut self) -> Result { let events = self.room.sync(); for e in &events { let ge = GameEvent::new(e.clone()); if ge.mode() == GameEventType::GameStart { self.room.rollback(e.since.clone()); self.lobby.lock(); return self.lobby.ready(); } self.lobby.eat(e.clone()); } Ok(0) } fn run_game_setup(&mut self) -> Result { for player in self.players() { if self.player(player.clone()).is_none() { return Err(format!("missing player {}", player)); } debug!("player = {}", player); } debug!("/players"); Err("not impl".to_string()) } fn run_game(&mut self) -> Result { Err("not impl".to_string()) } fn players(&self) -> Vec { let mut players = vec![]; for k in self.lobby.players.keys() { players.push(k.clone()); } players } fn player(&mut self, id: String) -> Option<&mut Player> { self.lobby.players.get_mut(&id) } } #[cfg(test)] mod tests { use super::*; use super::super::super::super::model::state::mockroom::MockRoom; use super::super::super::super::model::state::mockrooms::MockRooms; use super::super::super::super::model::state::rooms::Rooms; fn init() { let _ = env_logger::builder() .is_test(true) .filter_level(LevelFilter::Trace) .try_init(); } #[test] fn new_mockroom() { let _ = GameMaster::new(Box::new(MockRoom::create())); } #[test] fn new_rooms_mockrooms() { fn get() -> impl Rooms { let mrs = MockRooms::new(); mrs } let mut mrs = get(); let r = mrs.create(); let _ = GameMaster::new(r); } #[test] fn new_mockrooms() { let mut mrs = MockRooms::new(); let r = mrs.create(); let _ = GameMaster::new(r); } #[test] fn run_lobby() { init(); println!("run_lobby 1"); let mut mrs = MockRooms::new(); let r1 = mrs.create(); println!("run_lobby 2"); let room_id = r1.room_id(); let mut gm = GameMaster::new(r1); println!("run_lobby 3"); for i in 0..4 { println!("run_lobby attempt stop #{}", i); let mut r2 = mrs.join(room_id.clone()).unwrap(); r2.send(format!(r#"{{ "msgtype": "m.text", "body": "{{\"GameEventType\": \"GameStart\"}}" }}"#)).unwrap(); let ready = gm.run_lobby(); assert!(ready.is_err() == (i != 3), "want {:?} for ready.is_err #{:?}, which is {:?}", i != 3, i, ready.is_err()); } assert!(gm.lobby.players.len() == 5, "first run_lobby players: {:?}, sync: {:?}", gm.lobby.players, gm.room.sync()); let mut players1 = vec![]; for k in gm.lobby.players.keys() { players1.push(k.clone()); } assert!(gm.run_lobby().is_ok()); assert!(gm.lobby.players.len() == 5, "secnd run_lobby players: {:?}, sync: {:?}", gm.lobby.players, gm.room.sync()); let players2 = gm.lobby.players.keys(); assert!(format!("{:?}", players1) == format!("{:?}", players2)); } #[test] fn run_game_setup_fail() { init(); let mut mrs = MockRooms::new(); let r1 = mrs.create(); let mut gm = GameMaster::new(r1); assert!(gm.run_game_setup().is_ok()); } #[test] fn run_game_fail() { assert!(false, "not impl"); } }