chiark / gitweb /
hidden: wip per-player id map
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 30 Jan 2021 22:36:41 +0000 (22:36 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 31 Jan 2021 18:38:28 +0000 (18:38 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/hidden.rs [new file with mode: 0644]

diff --git a/src/hidden.rs b/src/hidden.rs
new file mode 100644 (file)
index 0000000..d5fbf8a
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2020-2021 Ian Jackson and contributors to Otter
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// There is NO WARRANTY.
+
+use crate::imports::*;
+
+use slotmap::secondary;
+
+pub struct PerPlayerIdMap {
+  f: SecondarySlotMap<PieceId, VisiblePieceId>,
+  r: DenseSlotMap<VisiblePieceId, PieceId>,
+}
+
+impl PerPlayerIdMap {
+  pub fn fwd(&self, piece: PieceId) -> Option<VisiblePieceId> {
+    Some(*self.f.get(piece)?)
+  }
+  pub fn rev(&self, vis: VisiblePieceId) -> Option<PieceId> {
+    Some(*self.r.get(vis)?)
+  }
+
+  fn _fwd_or_insert<R, VF, OF>(&mut self, piece: PieceId, vf: VF, of: OF) -> R
+  where VF: FnOnce(VisiblePieceId) -> R,
+        OF: FnOnce(secondary::OccupiedEntry<PieceId,VisiblePieceId>) -> R,
+  {
+    match self.f.entry(piece).expect("stale PieceId !") {
+      secondary::Entry::Vacant(mut vac) => {
+        if let Some((_, stale_vis)) = vac.remove_stale_entry() {
+          self.r.remove(stale_vis);
+        }
+        let vis = self.r.insert(piece);
+        vac.insert(vis);
+        vf(vis)
+      }
+      secondary::Entry::Occupied(occ) => {
+        of(occ)
+      }
+    }
+  }
+
+  pub fn insert(&mut self, piece: PieceId) {
+    self._fwd_or_insert(piece, |_vis|(), |vis|{
+      panic!("duplicate insert of {:?} {:?}", piece, vis)
+    })
+  }
+
+  pub fn fwd_or_insert(&mut self, piece: PieceId) -> VisiblePieceId {
+    self._fwd_or_insert(piece, |vis|vis, |occ| *occ.get())
+  }
+}
+