chiark / gitweb /
movehist: Move into its own module
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 2 Apr 2021 19:03:05 +0000 (20:03 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 2 Apr 2021 19:15:32 +0000 (20:15 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/gamestate.rs
src/movehist.rs [new file with mode: 0644]
src/prelude.rs
src/updates.rs

index eef433826b03d3441e016ccef726a0e3114d0868..5a0aabec50bd7cddcddd3b89e8735d115f364cc5 100644 (file)
@@ -55,8 +55,8 @@ pub struct GPlayer { // usual variable: gpl
   pub nick: String,
   pub layout: PresentationLayout,
   pub idmap: PerPlayerIdMap,
-  #[serde(default)] pub moveheld: SparseSecondaryMap<PieceId, GMoveHistLast>,
-  #[serde(default)] pub movehist: VecDeque<MoveHistEnt>,
+  #[serde(default)] pub moveheld: GMoveHeld,
+  #[serde(default)] pub movehist: GMoveHist,
 }
 
 #[derive(Debug,Serialize,Deserialize)]
@@ -75,25 +75,6 @@ pub struct GPiece {  // usual variable: gpc
   pub moveable: PieceMoveable,
 }
 
-#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
-pub struct MoveHistPosx { // usual variable: posx
-  pub pos: Pos,
-  pub angle: CompassAngle,
-  pub facehint: Option<FaceId>,
-}
-
-#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
-pub struct GMoveHistLast {
-  pub held: PlayerId,
-  pub posx: MoveHistPosx,
-}
-
-#[derive(Debug,Clone,Serialize,Deserialize)]
-pub struct MoveHistEnt {
-  pub held: PlayerId,
-  pub posx: OldNew<MoveHistPosx>,
-}
-
 pub type PieceXDataState = Option<Box<dyn PieceXData>>;
 
 #[derive(Debug,Serialize,Deserialize)]
diff --git a/src/movehist.rs b/src/movehist.rs
new file mode 100644 (file)
index 0000000..85baca4
--- /dev/null
@@ -0,0 +1,87 @@
+// Copyright 2020-2021 Ian Jackson and contributors to Otter
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// There is NO WARRANTY.
+
+use super::*; // we are otter::updates::movehist
+
+#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
+pub struct MoveHistPosx { // usual variable: posx
+  pub pos: Pos,
+  pub angle: CompassAngle,
+  pub facehint: Option<FaceId>,
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct MoveHistEnt {
+  pub held: PlayerId,
+  pub posx: OldNew<MoveHistPosx>,
+}
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+pub struct GMoveHist {
+  pub hist: VecDeque<MoveHistEnt>,
+}
+
+// ---------- non-public structs ----------
+
+#[derive(Debug,Clone,Serialize,Deserialize,Default)]
+pub struct GMoveHeld {
+  held: SparseSecondaryMap<VisiblePieceId, GMoveHistLast>,
+}
+
+#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
+struct GMoveHistLast {
+  held: PlayerId,
+  posx: MoveHistPosx,
+}
+
+impl Default for GMoveHist {
+  fn default() -> GMoveHist { GMoveHist {
+    hist: VecDeque::with_capacity(MOVEHIST_LEN_MAX),
+  } }
+}
+
+// We're track this on behalf of the client, based on the updates
+// we are sending.  That means we don't ahve to worry about
+// occultation, etc. etc.
+pub fn peek_prep_update(gs: &mut GameState, peek: &PreparedUpdateEntry)
+                        -> Option<PreparedUpdateEntry> {
+  if_let!{ PUE::Piece(PUE_P { ops,.. }) = peek; else return None; }
+
+  let mut pu = SecondarySlotMap::new();
+  for (player, &PreparedPieceUpdate { ref op, piece,.. }) in ops { if_chain! {
+    if let Some(ns) = op.new_state();
+    if let Some(gpl) = wants!( gs.players.get_mut(player), ?player);
+    if let Some(mut ent) = wants!( gpl.moveheld.held.entry(piece), ?piece);
+    let &PreparedPieceState { pos, angle, facehint, .. } = ns;
+    let new_posx = MoveHistPosx { pos, angle, facehint };
+
+    then {
+      if let slotmap::sparse_secondary::Entry::Occupied(ref mut oe) = ent {
+        let last = oe.get();
+        if ns.held == Some(last.held) { continue }
+
+        // Generate an update
+        let histent = MoveHistEnt {
+          held: last.held,
+          posx: OldNew::from([last.posx, new_posx]),
+        };
+        if gpl.movehist.hist.len() == MOVEHIST_LEN_MAX {
+          gpl.movehist.hist.pop_front();
+        }
+        gpl.movehist.hist.push_back(histent.clone());
+        pu.insert(player, histent);
+      }
+
+      if let Some(held) = ns.held {
+        ent.insert(GMoveHistLast { held: held, posx: new_posx });
+      } else {
+        ent.remove();
+      }
+    }
+  } }
+
+  if pu.is_empty() { return None }
+
+  Some(PUE::MoveHistEnt(pu))
+}
index caeeaf04d52119ce02514ca9e14f7da27a3f4206..aa10014fe474c9e7378e33ce2654fd8542ca2f13 100644 (file)
@@ -145,6 +145,7 @@ pub use crate::sse;
 pub use crate::toml_de;
 pub use crate::tz::*;
 pub use crate::updates::*;
+pub use crate::updates::movehist::{self, GMoveHeld, GMoveHist, MoveHistEnt};
 pub use crate::utils::*;
 pub use crate::ui::*;
 
index 289ff5a2a45c2399d7ceb4d0f59e0970a81381fe..e939268bb5fcf838a81560f6a53e8ddc19a62d30 100644 (file)
@@ -6,6 +6,8 @@
 
 use crate::prelude::*;
 
+#[path="movehist.rs"] pub mod movehist;
+
 #[allow(non_camel_case_types)] type TUE_P<'u> = TransmitUpdateEntry_Piece<'u>;
 #[allow(non_camel_case_types)] type PUE_I = PreparedUpdateEntry_Image;
 #[allow(non_camel_case_types)] type TUE_I<'u> = TransmitUpdateEntry_Image<'u>;
@@ -757,52 +759,8 @@ impl<'r> PrepareUpdatesBuffer<'r> {
         PreparedUpdateEntry::Error(ErrorSignaledViaUpdate::InternalError)
       });
 
-    // We're track this on behalf of the client, based on the updates
-    // we are sending.  That means we don't ahve to worry about
-    // occultation, etc. etc.
-    let movehist_update = if let PUE::Piece(PUE_P { ops,.. }) = &update {
-      let mut pu = SecondarySlotMap::new();
-      for (player, PreparedPieceUpdate { op,.. }) in ops { if_chain! {
-        if let Some(ns) = op.new_state();
-        if let Some(gpl) = wants!( self.g.gs.players.get_mut(player), ?player);
-        if let Some(mut ent) = wants!( gpl.moveheld.entry(piece),     ?piece);
-        let &PreparedPieceState { pos, angle, facehint, .. } = ns;
-        let new_posx = MoveHistPosx { pos, angle, facehint };
-
-        then {
-          if let slotmap::sparse_secondary::Entry::Occupied(ref mut oe) = ent {
-            let last = oe.get();
-            if ns.held == Some(last.held) { continue }
-
-            // Generate an update
-            let histent = MoveHistEnt {
-              held: last.held,
-              posx: OldNew::from([last.posx, new_posx]),
-            };
-            gpl.movehist.reserve(MOVEHIST_LEN_MAX);
-            if gpl.movehist.len() == MOVEHIST_LEN_MAX {
-              gpl.movehist.pop_front();
-            }
-            gpl.movehist.push_back(histent.clone());
-            pu.insert(player, histent);
-          }
-
-          if let Some(held) = ns.held {
-            ent.insert(GMoveHistLast { held: held, posx: new_posx });
-          } else {
-            ent.remove();
-          }
-        }
-      } }
+    let movehist_update = movehist::peek_prep_update(&mut self.g.gs, &update);
 
-      if pu.is_empty() {
-        None
-      } else {
-        Some(PUE::MoveHistEnt(pu))
-      }
-    } else {
-      None
-    };
     self.us.push(update);
     self.us.extend(movehist_update);
   }