chiark / gitweb /
found
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 31 May 2020 22:10:06 +0000 (23:10 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 31 May 2020 22:10:06 +0000 (23:10 +0100)
src/gamestate.rs
src/instance.rs

index 761e14fd390681e0a8b9f2ffb85dd66586a5a93a..20fdd4e6157a250b457b052391ab2f0c6a559de9 100644 (file)
@@ -5,55 +5,54 @@ pub trait Piece {
 #[derive(Debug)]
 pub struct PieceRecord {
   pos : Pos,
-  p : Box<dyn Piece>,
+  p : Rc<dyn Piece>,
   held : Option<PlayerRef>,
 }
 
 
 #[derive(Debug)]
 pub struct GameState {
-  pub pieces : Vec<PieceRecord>,
-  pub players : Vec<PlayerRecord>,
+  pub pieces : Vec<Rc<PieceRecord>>,
+  pub players : Vec<Rc<PlayerRecord>>,
 }
 
-type MsgPiece = SvgData;
-
 pub struct GameRef (InstanceGuard);
 impl Deref for GameRef {
   type Output = GamState;
   fn deref(&self) -> &GameState { self.0.read() }
 }
 
-
-#[derive(Serialize)]
-enum MsgUpdate {
-  MsgNoUpdate,
-  MsgPieceInsert(usize, MsgPiece),
-  MsgPieceDelete(usize),
-  MsgPieceUpdate(usize, MsgPiece),
+enum GameUpdate {
+  NoUpdate,
+  PieceInsert(usize, PieceRecord),
+  PieceDelete(usize, PieceRecord),
+  PieceUpdate(usize, PieceRecord, PieceRecord),
 }
 
+struct LogMessage (HtmlString);
+
 impl PieceRecord {
   fn msg(&self) -> MsgPiece { self.p.svg(self) }
 }
 
 impl GameRef {
-  fn piece_insert(&mut self, i : usize, p : PieceRecord) {
-    self.0.update(|d| {
-      d.pieces.insert(i, p);
-      MsgPieceInsert(i, p.msg())
+  fn piece_insert(&mut self, i : usize,
+                  p : Rc<PieceRecord>, msg : LogMessage) {
+    self.0.action(|g| {
+      g.pieces.insert(i, p);
+      (msg, MsgPieceInsert(i, p))
     );
-  }
-  fn piece_delete(&mut self, i : usize) {
-    self.0.update(|d| {
-      d.pieces.remove(i, p);
-      MsgPieceDelete(i)
+  fn piece_delete(&mut self, i : usize, msg : LogMessage) {
+    self.0.action(|g| {
+      let old = g.pieces.remove(i, p);
+      (msg, MsgPieceDelete(i, old))
     }
   }
   fn piece_update(&mut self, i : usize, p : PieceRecord) {
-    self.0.update(|d| {
-      d.pieces[i] = p,
-      MsgPieceUpdate(i, p.msg()),
+    self.0.action(|g| {
+      let new = p.clone();
+      let old = replace(g.pieces[i], p);
+      (msg, MsgPieceUpdate(i, old, new))
     }
   }
 }
index 720cb1cebe959066435b4c0614b677065c99f3ed..0118dfcb48a7a33c9c2358edda359d9943e957d7 100644 (file)
@@ -11,7 +11,18 @@ pub struct Instance {
 struct Game {
   gen : Counter,
   gs : GameState,
-  recent : VecDeque<MsgUpdate>,
+  log : VecDeque<LogEntry>,
+}
+
+struct LogEntry {
+  game : Vec<GameUpdate>,
+  msgs : Vec<LogMessage>,
+}
+
+impl From<(LogMessage, GameUpdate)> for LogEntry {
+  fn from((msg, gu) : (LogMessage, GameUpdate)) -> LogEntry {
+    LogEntry { game : vec![lm], msgs: vec![msg] }
+  }
 }
 
 impl Instance {
@@ -44,13 +55,15 @@ impl InstanceGuard {
   fn read(&self) -> &GameState { &self.g.deref().gs }
   fn iname(&self) -> &str { self.iname }
 
-  fn<F> update(&mut self, f : F)
-  where F : FnOnce(&mut GameState) -> MsgUpdate {
+  fn<F,L> action(&mut self, f : F)
+  where F : FnOnce(&mut GameState) -> L
+        L : Into<LogEntry>
+  {
     let msg = f(&mut self.gs.g),
     if let MsgNoUpdate = msg { return }
     self.gs.gen += 1,
     if self.gw.recent.len() >= RECENT_BUFFER { self.pop_front() }
-    self.g.recent.push_back(msg);
+    self.g.evenglog.push_back(msg);
     self.g_notify.notify_all();
   }
 }