From dca8d756cd321257bbce4712d7aa3539ca8bc13c Mon Sep 17 00:00:00 2001 From: bel Date: Sun, 3 May 2020 09:22:23 -0600 Subject: [PATCH] update mockrooms so join emits join message --- .../src/controller/gamemaster/gamemaster.rs | 45 ++++--- .../src/controller/gamemaster/lobby.rs | 19 ++- .../src/controller/gamemaster/mod.rs | 1 + .../src/controller/gamemaster/player.rs | 9 ++ .../src/controller/gamemaster/role.rs | 90 ++++++++++++++ secert-hitler/src/model/state/event.rs | 6 +- secert-hitler/src/model/state/mockroom.rs | 110 ++++++++++++------ secert-hitler/src/model/state/mockrooms.rs | 8 +- secert-hitler/src/model/state/room.rs | 2 + 9 files changed, 233 insertions(+), 57 deletions(-) diff --git a/secert-hitler/src/controller/gamemaster/gamemaster.rs b/secert-hitler/src/controller/gamemaster/gamemaster.rs index 53b6b48..2cdc170 100644 --- a/secert-hitler/src/controller/gamemaster/gamemaster.rs +++ b/secert-hitler/src/controller/gamemaster/gamemaster.rs @@ -1,32 +1,45 @@ -/* use super::super::super::model::state::room::Room; +use super::lobby::Lobby; pub struct GameMaster { room: Box, + lobby: Lobby, } impl GameMaster { fn new(room: Box) -> GameMaster { GameMaster{ room: room, + lobby: Lobby::new(), } } - fn run(&self) -> Result { + fn run(&mut self) -> Result { self.run_lobby()?; self.run_game_setup()?; self.run_game() } - fn run_lobby(&self) -> Result { + fn run_lobby(&mut self) -> Result { + println!(". run lobby"); + loop { + let rollback = self.room.since(); + let events = self.room.sync(); + println!(". rollback: {:?}", rollback); + for e in &events { + println!("e: {:?}", e); + } + self.room.rollback(rollback); + break + } Err("not impl".to_string()) } - fn run_game_setup(&self) -> Result { + fn run_game_setup(&mut self) -> Result { Err("not impl".to_string()) } - fn run_game(&self) -> Result { + fn run_game(&mut self) -> Result { Err("not impl".to_string()) } } @@ -63,21 +76,25 @@ mod tests { } #[test] - fn gm_run_lobby_fail() { + fn run_lobby() { + let mut mrs = MockRooms::new(); + let mut r1 = mrs.create(); + let room_id = r1.room_id(); + let mut gm = GameMaster::new(r1); + let mut r2 = mrs.join(room_id).unwrap(); + gm.run_lobby(); + assert!(gm.lobby.players.len() == 1, "players: {:?}, sync: {:?}", gm.lobby.players, gm.room.sync()); + } + + #[test] + fn run_game_setup_fail() { let gm = GameMaster::new(Box::new(MockRoom::create())); panic!("not impl"); } #[test] - fn gm_run_game_setup_fail() { - let gm = GameMaster::new(Box::new(MockRoom::create())); - panic!("not impl"); - } - - #[test] - fn gm_run_game_fail() { + fn run_game_fail() { let gm = GameMaster::new(Box::new(MockRoom::create())); panic!("not impl"); } } -*/ diff --git a/secert-hitler/src/controller/gamemaster/lobby.rs b/secert-hitler/src/controller/gamemaster/lobby.rs index 5ba5d7e..9c25896 100644 --- a/secert-hitler/src/controller/gamemaster/lobby.rs +++ b/secert-hitler/src/controller/gamemaster/lobby.rs @@ -4,17 +4,22 @@ use super::super::super::model::state::event::Event; use std::collections::HashMap; pub struct Lobby { - players: HashMap, + pub players: HashMap, + locked: bool, } impl Lobby { - fn new() -> Lobby { + pub fn new() -> Lobby { Lobby{ players: HashMap::new(), + locked: false, } } - - fn eat(&mut self, message: Event) { + + pub fn eat(&mut self, message: Event) { + if self.locked { + return; + } let j = message.join(); if j.is_none() { return; @@ -22,6 +27,10 @@ impl Lobby { let id = j.unwrap(); self.players.insert(id.clone(), Player::new(id)); } + + pub fn lock(&mut self) { + self.locked = true; + } } #[cfg(test)] @@ -31,7 +40,7 @@ mod tests { fn _dummy_event(m: &str) -> Event { Event{ body: m.to_string(), - next: "a".to_string(), + since: "a".to_string(), sender: "b".to_string(), } } diff --git a/secert-hitler/src/controller/gamemaster/mod.rs b/secert-hitler/src/controller/gamemaster/mod.rs index bcb677e..32b9e75 100644 --- a/secert-hitler/src/controller/gamemaster/mod.rs +++ b/secert-hitler/src/controller/gamemaster/mod.rs @@ -1,3 +1,4 @@ pub mod gamemaster; pub mod player; +pub mod role; pub mod lobby; diff --git a/secert-hitler/src/controller/gamemaster/player.rs b/secert-hitler/src/controller/gamemaster/player.rs index cd96c6a..d1ccacd 100644 --- a/secert-hitler/src/controller/gamemaster/player.rs +++ b/secert-hitler/src/controller/gamemaster/player.rs @@ -1,14 +1,23 @@ +use super::role::Role; +use super::role::Roles; + #[derive(Clone, Debug)] pub struct Player { id: String, + role: Role, } impl Player { pub fn new(id: String) -> Player { Player { id: id, + role: Role::new(), } } + + fn set_role(&mut self, role: Roles) { + self.role.set(role); + } } #[cfg(test)] diff --git a/secert-hitler/src/controller/gamemaster/role.rs b/secert-hitler/src/controller/gamemaster/role.rs index efb6fe8..9077e2f 100644 --- a/secert-hitler/src/controller/gamemaster/role.rs +++ b/secert-hitler/src/controller/gamemaster/role.rs @@ -3,8 +3,12 @@ pub struct Role { role: Roles, } +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Roles { Null, + Facist, + Hitler, + Liberal, } impl Role { @@ -13,6 +17,22 @@ impl Role { role: Roles::Null, } } + + pub fn set(&mut self, role: Roles) { + self.role = role + } + + pub fn is_hitler(&self) -> bool { + self.role == Roles::Hitler + } + + pub fn is_facist(&self) -> bool { + self.role == Roles::Facist || self.is_hitler() + } + + pub fn is_liberal(&self) -> bool { + self.role == Roles::Liberal + } } #[cfg(test)] @@ -23,4 +43,74 @@ mod tests { fn new_role() { let _ = Role::new(); } + + #[test] + fn set() { + let mut r = Role::new(); + r.set(Roles::Facist); + assert!(r.role == Roles::Facist); + } + + #[test] + fn is_hitler_liberal() { + let mut r = Role::new(); + r.set(Roles::Liberal); + assert!(!r.is_hitler()); + } + + #[test] + fn is_hitler_facist() { + let mut r = Role::new(); + r.set(Roles::Facist); + assert!(!r.is_hitler()); + } + + #[test] + fn is_hitler_yes() { + let mut r = Role::new(); + r.set(Roles::Hitler); + assert!(r.is_hitler()); + } + + #[test] + fn is_facist_liberal() { + let mut r = Role::new(); + r.set(Roles::Liberal); + assert!(!r.is_facist()); + } + + #[test] + fn is_facist_facist() { + let mut r = Role::new(); + r.set(Roles::Facist); + assert!(r.is_facist()); + } + + #[test] + fn is_facist_hitler() { + let mut r = Role::new(); + r.set(Roles::Hitler); + assert!(r.is_facist()); + } + + #[test] + fn is_liberal_liberal() { + let mut r = Role::new(); + r.set(Roles::Liberal); + assert!(r.is_liberal()); + } + + #[test] + fn is_liberal_facist() { + let mut r = Role::new(); + r.set(Roles::Facist); + assert!(!r.is_liberal()); + } + + #[test] + fn is_liberal_hitler() { + let mut r = Role::new(); + r.set(Roles::Hitler); + assert!(!r.is_liberal()); + } } diff --git a/secert-hitler/src/model/state/event.rs b/secert-hitler/src/model/state/event.rs index e4f6a61..883e984 100644 --- a/secert-hitler/src/model/state/event.rs +++ b/secert-hitler/src/model/state/event.rs @@ -4,7 +4,7 @@ use json; pub struct Event { pub sender: String, pub body: String, - pub next: String, + pub since: String, } #[derive(PartialEq, Eq, Debug)] @@ -58,7 +58,7 @@ mod tests { Event{ sender: "sender".to_string(), body: r#"{}"#.to_string(), - next: "next".to_string(), + since: "since".to_string(), } } @@ -67,7 +67,7 @@ mod tests { let e = Event{ sender: "sender".to_string(), body: "body".to_string(), - next: "next".to_string(), + since: "since".to_string(), }; println!("{:?}", e); } diff --git a/secert-hitler/src/model/state/mockroom.rs b/secert-hitler/src/model/state/mockroom.rs index 82f08fa..fd6c3c4 100644 --- a/secert-hitler/src/model/state/mockroom.rs +++ b/secert-hitler/src/model/state/mockroom.rs @@ -7,7 +7,7 @@ use crossbeam_channel::{unbounded, Sender, Receiver}; #[derive(Clone, Debug)] pub struct MockRoom { - last: String, + since: String, room_id: String, events_s: Sender>, events_r: Receiver>, @@ -21,41 +21,28 @@ impl MockRoom { pub fn join(room_id: String) -> MockRoom { let (s, r) = unbounded(); s.send(vec![]).ok().unwrap(); - MockRoom { - last: "".to_string(), - room_id: room_id, + let mut mr = MockRoom { + since: "".to_string(), + room_id: room_id.clone(), events_s: s, events_r: r, - } + }; + let id = rands(); + mr.send_as(id.clone(), format!(r#"{{ + "displayname": "{}", + "membership": "join" + }}"#, id.clone())).unwrap(); + mr } pub fn room(&self) -> impl Room { self.clone() } -} -impl Room for MockRoom { - fn sync(&mut self) -> Vec { - let mut unseen: Vec = vec![]; - let mut last = self.last.clone(); - let events = self.events_r.recv().ok().unwrap(); - for e in &events { - if e.next == self.last { - unseen.clear(); - } else { - unseen.push(e.clone()); - last = e.next.clone(); - } - } - self.events_s.send(events).ok().unwrap(); - self.last = last; - return unseen; - } - - fn send(&mut self, message: String) -> Result<&str, &str> { + pub fn send_as(&mut self, id: String, message: String) -> Result<&str, &str> { let e = Event{ - sender: rands(), - next: rands(), + sender: id, + since: rands(), body: message, }; let mut events = self.events_r.recv().ok().unwrap(); @@ -64,9 +51,41 @@ impl Room for MockRoom { Ok("ok") } +} + +impl Room for MockRoom { + fn sync(&mut self) -> Vec { + let mut unseen: Vec = vec![]; + let mut since = self.since.clone(); + let events = self.events_r.recv().ok().unwrap(); + for e in &events { + if e.since == self.since { + unseen.clear(); + } else { + unseen.push(e.clone()); + since = e.since.clone(); + } + } + self.events_s.send(events).ok().unwrap(); + self.since = since; + return unseen; + } + + fn send(&mut self, message: String) -> Result<&str, &str> { + self.send_as(rands(), message) + } + fn room_id(&self) -> String { self.room_id.clone() } + + fn rollback(&mut self, since: String) { + self.since = since; + } + + fn since(&self) -> String { + self.since.clone() + } } impl Drop for MockRoom { @@ -91,12 +110,12 @@ mod tests { fn _dummy() -> MockRoom { let mut r = MockRoom::create(); - r.last = "1".to_string(); + r.since = "1".to_string(); let mut events = r.events_r.recv().ok().unwrap(); for i in 0..5 { events.push(Event{ sender: i.to_string(), - next: i.to_string(), + since: i.to_string(), body: i.to_string(), }); } @@ -120,8 +139,17 @@ mod tests { #[test] fn join() { let rid = "a".to_string(); - let r: MockRoom = MockRoom::join(rid.to_string()); + let mut r: MockRoom = MockRoom::join(rid.to_string()); assert!(r.room_id == rid); + let events = r.sync(); + let mut found = false; + for e in &events { + let j = e.join(); + if j.is_some() { + found = true; + } + } + assert!(found); } #[test] @@ -131,8 +159,8 @@ mod tests { assert!(events.len() == 3, "want {}, got {}: {:?}", 3, events.len(), events); assert!(events[0].sender == "2"); assert!(events[0].body == "2"); - assert!(events[0].next == "2"); - assert!(r.last == "4", "want last==4, got {}", r.last); + assert!(events[0].since == "2"); + assert!(r.since == "4", "want since==4, got {}", r.since); } #[test] @@ -141,10 +169,24 @@ mod tests { let message = "message".to_string(); r.sync(); assert!(r.send(message.clone()).ok().unwrap() == "ok"); - assert!(r.last == "4"); + assert!(r.since == "4"); let events = r.sync(); assert!(events.len() == 1); assert!(events[0].body == message, "want {}, got {}: {:?}", message, events[0].body, events); - assert!(r.last != "4"); + assert!(r.since != "4"); + } + + #[test] + fn rollback() { + let mut r = _dummy(); + let was = r.since.to_string(); + let events = r.sync(); + assert!(events.len() == 3); + assert!(r.since == "4"); + r.rollback(was.to_string()); + assert!(r.since == was); + let events = r.sync(); + assert!(events.len() == 3); + assert!(r.since == "4"); } } diff --git a/secert-hitler/src/model/state/mockrooms.rs b/secert-hitler/src/model/state/mockrooms.rs index 9b1f042..b71feb2 100644 --- a/secert-hitler/src/model/state/mockrooms.rs +++ b/secert-hitler/src/model/state/mockrooms.rs @@ -1,6 +1,7 @@ use super::rooms::Rooms; use super::room::Room; use super::mockroom::MockRoom; +use super::mockroom::rands; // #[derive(Clone, Debug)] pub struct MockRooms { @@ -26,7 +27,12 @@ impl Rooms for MockRooms { fn join(&self, room_id: String) -> Result, &str> { for r in &self.rooms { if r.room_id() == room_id { - return Ok(Box::new(r.room())); + let mut r = r.room(); + r.send(format!(r#"{{ + "displayname": "{}", + "membership": "join" + }}"#, rands())); + return Ok(Box::new(r)); } } Err("not found") diff --git a/secert-hitler/src/model/state/room.rs b/secert-hitler/src/model/state/room.rs index 9102d5f..4771ef3 100644 --- a/secert-hitler/src/model/state/room.rs +++ b/secert-hitler/src/model/state/room.rs @@ -1,9 +1,11 @@ use super::event; pub trait Room { + fn rollback(&mut self, since: String); fn sync(&mut self) -> Vec; fn send(&mut self, message: String) -> Result<&str, &str>; fn room_id(&self) -> String; + fn since(&self) -> String; } #[cfg(test)]