From: Ian Jackson Date: Sat, 30 Jan 2021 22:36:41 +0000 (+0000) Subject: hidden: wip per-player id map X-Git-Tag: otter-0.4.0~596 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=3d3aee4f73474e9c7434a4c5547da1cb7810b257;p=otter.git hidden: wip per-player id map Signed-off-by: Ian Jackson --- diff --git a/src/hidden.rs b/src/hidden.rs new file mode 100644 index 00000000..d5fbf8a5 --- /dev/null +++ b/src/hidden.rs @@ -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, + r: DenseSlotMap, +} + +impl PerPlayerIdMap { + pub fn fwd(&self, piece: PieceId) -> Option { + Some(*self.f.get(piece)?) + } + pub fn rev(&self, vis: VisiblePieceId) -> Option { + Some(*self.r.get(vis)?) + } + + fn _fwd_or_insert(&mut self, piece: PieceId, vf: VF, of: OF) -> R + where VF: FnOnce(VisiblePieceId) -> R, + OF: FnOnce(secondary::OccupiedEntry) -> 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()) + } +} +