chiark / gitweb /
hidden: Provide OccultIlks
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 11 Mar 2021 10:06:26 +0000 (10:06 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 11 Mar 2021 10:18:32 +0000 (10:18 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/gamestate.rs
src/lib.rs
src/occultmap.rs [new file with mode: 0644]

index 14e5e69d821e1f40f806cc15860242048a027798..4ad94d4baef79dc23e743d95004ab9f910217f52 100644 (file)
@@ -165,6 +165,7 @@ pub trait PieceTrait: OutlineTrait + Send + Debug + 'static {
   fn itemname(&self) -> &str;
 }
 
+#[typetag::serde]
 pub trait OccultedPieceTrait: OutlineTrait + 'static {
   fn svg(&self, f: &mut Html, id: VisiblePieceId) -> Result<(),IE>;
   fn describe_html(&self) -> Result<Html,IE>;
index 1be3cd3ff47c76c2112b24e34b496f1221433d13..09b594d415d698c562a9977e3e5b8828d3409939 100644 (file)
@@ -21,6 +21,7 @@ pub mod hidden;
 pub mod keydata;
 pub mod mgmtchannel;
 pub mod nwtemplates;
+pub mod occultmap;
 pub mod pieces;
 pub mod shapelib;
 pub mod spec;
diff --git a/src/occultmap.rs b/src/occultmap.rs
new file mode 100644 (file)
index 0000000..aedacb7
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright 2020-2021 Ian Jackson and contributors to Otter
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// There is NO WARRANTY.
+
+use crate::prelude::*;
+
+slotmap::new_key_type!{ pub struct OccultIlkId; }
+
+/// Does *not* `impl Drop`.  Don't just drop it.
+#[derive(Debug,Serialize,Deserialize)]
+#[serde(transparent)]
+pub struct OccultIlkOwningId(Id);
+
+#[derive(Debug,Clone,Eq,PartialEq,Ord,PartialOrd,Hash)]
+#[derive(Serialize,Deserialize)]
+#[serde(transparent)]
+pub struct OccultIlkName(pub String);
+
+type Id = OccultIlkId;
+type OId = OccultIlkOwningId;
+type K = OccultIlkName;
+type V = Box<dyn OccultedPieceTrait>;
+type Refcount = u32;
+
+#[derive(Debug,Serialize,Deserialize)]
+pub struct OccultIlks {
+  lookup: HashMap<K, Id>,
+  table: DenseSlotMap<Id, Data>,
+}
+
+#[derive(Debug,Serialize,Deserialize)]
+pub struct Data {
+  k: K, // duplicated, ah well
+  v: V,
+  refcount: Refcount,
+}
+
+impl OccultIlks {
+  #[throws(as Option)]
+  pub fn get<I: Borrow<Id>>(&self, id: I) -> &V {
+    &self.table.get(*id.borrow())?.v
+  }
+
+  pub fn insert(&mut self, k: K, v: V) -> OId {
+    let OccultIlks { lookup, table } = self;
+    let id = *lookup
+      .entry(k)
+      .or_insert_with_key(|k|{
+        let data = Data {
+          v,
+          k: k.clone(),
+          refcount: 0,
+        };
+        table.insert(data)
+      });
+    table[id].refcount += 1;
+    OccultIlkOwningId(id)
+  }
+
+  pub fn dispose(&mut self, id: OId) {
+    let id: Id = id.0;
+    let data = self.table.remove(id).unwrap();
+    self.lookup.remove(&data.k);
+  }
+}
+
+impl Borrow<Id> for OId {
+  fn borrow(&self) -> &Id { &self.0 }
+}