From: Ian Jackson Date: Sun, 17 May 2020 13:27:23 +0000 (+0100) Subject: wip gamestate before trying to think about what js needs X-Git-Tag: otter-0.2.0~1609 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=76670b3a8f590c5368f5216c342855a629cb061a;p=otter.git wip gamestate before trying to think about what js needs --- diff --git a/src/gamestate.rs b/src/gamestate.rs index c0bea892..994f25de 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -1,5 +1,7 @@ pub trait Piece { + type Msg : Serialize; + fn msg(&self) -> Msg; } #[derive(Debug)] @@ -10,14 +12,16 @@ pub struct PieceRecord { held : Option, } +const RECENT_BUFFER : usize = 10; + #[derive(Debug)] pub struct GameState { gen : Counter, data : GameStateData, - clients, + recent : VecDeque, + notify : Condvar, } - #[derive(Debug)] pub struct GameStateData { pub pieces : Vec, @@ -32,35 +36,53 @@ impl Deref for GameState { impl GameState { fn as_ref(&self) -> (&usize, &GameStateData) { (&self.gen, &self.data) } fn gen(&self) -> usize { self.gen } -} - + fn update(&mut self, f : F) + where F : FnOnce(&mut GameStateData) -> MsgUpdate { + let msg = f(&mut self.data), + if let MsgNoUpdate = msg { return } + self.gen += 1, + if self.recent.len() >= RECENT_BUFFER { self.pop_front() } + self.recent.push_back(msg); + self.notify.notify_all(); + } +} #[derive(Serialize)] enum MsgUpdate { - InsertPiece(usize, MsgPiece), - DeletePiece(usize), - UpdatePiece(usize, MsgPiece), + MsgNoUpdate, + MsgPieceInsert(usize, MsgPiece), + MsgPieceDelete(usize), + MsgPieceUpdate(usize, MsgPiece), } -struct DataGuard<'gs> { - gs : &'gs mut GameState, - msg : MsgUpdate, -} -impl<'gs> Deref for DataGuard<'gs> { - type Output = GameState; - fn deref(&self) -> GameState<'gs> { self.gs } -} -impl<'gs> DerefMut for DataGuard<'gs> { - fn deref_mut(&mut self) -> GameState<'gs> { self.gs } +struct MsgPiece { + } -impl GameState { - fn update(&mut self, msg : MsgUpdate) -> DataGuard<'_> { - DataGuard { gs : self, msg } +impl PieceRecord { + fn msg(&self) -> MsgPiece { + } } -impl Drop for DataGuard { - +impl GameState { + fn piece_insert(&mut self, i : usize, p : PieceRecord) { + self.update(|d| { + d.pieces.insert(i, p); + MsgPieceInsert(i, p.msg()) + ); + } + fn piece_delete(&mut self, i : usize) { + self.update(|d| { + d.pieces.remove(i, p); + MsgPieceDelete(i) + } + } + fn piece_update(&mut self, i : usize, p : PieceRecord) { + self.update(|d| { + d.pieces[i] = p, + MsgPieceUpdate(i, p.msg()), + } + } }