chiark / gitweb /
Move magic into own module, so it can inerit from hidden
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 17 Feb 2021 00:36:58 +0000 (00:36 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 17 Feb 2021 00:36:58 +0000 (00:36 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/hidden.rs
src/magic.rs [new file with mode: 0644]
src/pieces.rs

index b2db9da7cf2563157f18cdc178c8e366c9a1c03f..3a1e9aab2dcbb836f0bf78b15e8ffdc1bb2fd72e 100644 (file)
@@ -2,6 +2,9 @@
 // SPDX-License-Identifier: AGPL-3.0-or-later
 // There is NO WARRANTY.
 
+#[path="magic.rs"]
+mod magic;
+
 use crate::prelude::*;
 
 use slotmap::secondary;
diff --git a/src/magic.rs b/src/magic.rs
new file mode 100644 (file)
index 0000000..cfeb874
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright 2020-2021 Ian Jackson and contributors to Otter
+// SPDX-License-Identifier: AGPL-3.0-or-later
+// There is NO WARRANTY.
+
+// This is otter::hidden::magic
+
+use crate::prelude::*;
+//use super::*;
+
+#[derive(Debug,Clone,Serialize,Deserialize)]
+struct MagicOwner {
+  player: PlayerId,
+  desc: Html,
+  dasharray: Html,
+}
+
+#[derive(Debug,Serialize,Deserialize)]
+struct Hand {
+  shape: SimpleShape,
+}
+
+#[derive(Debug,Clone,Default,Serialize,Deserialize)]
+struct HandState {
+  owner: Option<MagicOwner>,
+}
+
+#[typetag::serde(name="Hand")]
+impl PieceXData for HandState { }
+
+#[typetag::serde]
+impl Outline for Hand {
+  delegate!{
+    to self.shape {
+      fn surround_path(&self, _pri: &PieceRenderInstructions)
+                       -> Result<Html,IE>;
+      fn thresh_dragraise(&self, _pri: &PieceRenderInstructions)
+                          -> Result<Option<Coord>,IE>;
+      fn bbox_approx(&self) -> [Pos;2];
+    }
+  }
+}
+
+#[typetag::serde]
+impl PieceSpec for piece_specs::Hand {
+  #[throws(SpecError)]
+  fn load(&self, _: usize) -> Box<dyn Piece> {
+    let (mut shape, common) = self.shape.load_raw()?;
+    if common.itemname.is_some() {
+      throw!(SpecError::ItemnameSpecifiedWhereForbidden);
+    }
+    if shape.nfaces() != 1 {
+      throw!(SpecError::MultifacetedMagic);
+    }
+    shape.itemname = "magic-hand".to_string();
+    Box::new(Hand {
+      shape,
+    }) as Box<dyn Piece>
+  }
+}
+
+impl Hand {
+  fn describe_html_inner(&self, xdata: Option<&HandState>) -> Html {
+    if_chain! {
+      if let Some(xdata) = xdata;
+      if let Some(owner) = &xdata.owner;
+      then { owner.desc.clone() }
+      else { Html(format!("a hand repository")) }
+    }
+  }
+}
+
+#[typetag::serde]
+impl Piece for Hand {
+  fn nfaces(&self) -> RawFaceId { 1 }
+  #[throws(IE)]
+  fn svg_piece(&self, f: &mut Html, gpc: &PieceState,
+               pri: &PieceRenderInstructions) {
+    self.shape.svg_piece_raw(f, pri, &mut |f: &mut String| {
+      if_chain!{
+        if let Some(xdata) = gpc.xdata.get::<HandState>()?;
+        if let Some(owned) = &xdata.owner;
+        then { write!(f, r##" stroke-dasharray="{}" "##,
+                      &owned.dasharray.0)?; }
+      }
+      Ok(())
+    })?;
+  }
+
+  #[throws(IE)]
+  fn describe_html(&self, _face: Option<FaceId>, gpc: &PieceState) -> Html {
+    let xdata = gpc.xdata.get()?;
+    self.describe_html_inner(xdata)
+  }
+
+  delegate!{
+    to self.shape {
+      fn itemname(&self) -> &str;
+    }
+  }
+
+  #[throws(InternalError)]
+  fn add_ui_operations(&self, upd: &mut Vec<UoDescription>,
+                       gpc: &PieceState) {
+    upd.push(if_chain! {
+      if let Some(xdata) = gpc.xdata.get::<HandState>()?;
+      if let Some(_owner) = &xdata.owner;
+      then { UoDescription {
+        kind: UoKind:: Piece,
+        def_key: 'C',
+        opname: "deactivate".to_owned(),
+        desc: Html::lit("Deactivate hand"),
+        wrc: WRC::Unpredictable,
+      }}
+      else { UoDescription {
+        kind: UoKind:: Piece,
+        def_key: 'C',
+        opname: "claim".to_owned(),
+        desc: Html::lit("Claim this as your hand"),
+        wrc: WRC::Unpredictable,
+      }}
+    })
+  }
+
+  fn ui_operation(&self, gs: &mut GameState, player: PlayerId,
+                  piece: PieceId, opname: &str, wrc: WhatResponseToClientOp)
+                  -> PieceUpdateResult {
+    let gplayers = &mut gs.players;
+    let gpc = gs.pieces.byid_mut(piece)?;
+    let xdata = gpc.xdata.get_mut::<HandState>()
+      .map_err(|e| APOE::ReportViaResponse(e.into()))?;
+    let old_desc = self.describe_html_inner(Some(xdata));
+
+    let dasharray = player_dasharray(gplayers, player);
+    let gpl = gplayers.byid_mut(player)?;
+    let _occults = &mut gs.occults;
+
+    let did;
+    match (opname, xdata.owner.is_some()) {
+      ("claim", false) => {
+        let nick = Html(htmlescape::encode_minimal(&gpl.nick));
+        let new_desc = Html(format!("{}'s hand", &nick.0));
+        xdata.owner = Some(MagicOwner {
+          player,
+          dasharray,
+          desc: new_desc,
+        });
+        // xxx recalculate occultations
+        did = format!("claimed {}", &old_desc.0);
+      }
+      ("deactivate", true) => {
+        xdata.owner = None;
+        // xxx recalculate occultations
+        did = format!("deactivated {}", &old_desc.0);
+      }
+      ("claim", true) |
+      ("deactivate", false) => {
+        throw!(OE::PieceHeld);
+      }
+      _ => {
+        throw!(OE::BadOperation);
+      }
+    }
+
+    let who_by = Html(htmlescape::encode_minimal(&gpl.nick));
+    let log = vec![ LogEntry { html: Html(format!("{} {}", who_by.0, did)) }];
+    Ok(PieceUpdate {
+      wrc, log,
+      ops: PUOs::Simple(PUO::Modify(())), // xxx
+      // xxx want PUU::RecalculateOccultations
+    })
+  }
+}
index b5ccd816c2186f656cb8bc468c785954983e8e93..e0d9bc6a97917e121f376a9f54f5b867ce10edf8 100644 (file)
@@ -13,13 +13,13 @@ type ColourMap = IndexVec<FaceId, Colour>;
 #[derive(Debug,Serialize,Deserialize)]
 // todo: this serialisation is rather large
 pub struct SimpleShape {
-  desc: Html,
-  path: Html,
+  pub desc: Html,
+  pub path: Html,
   colours: ColourMap,
-  #[serde(default)] edges: ColourMap,
-  #[serde(default="default_edge_width")] edge_width: f64,
-  itemname: String,
-  outline: Box<dyn Outline>,
+  #[serde(default)] pub edges: ColourMap,
+  #[serde(default="default_edge_width")] pub edge_width: f64,
+  pub itemname: String,
+  pub outline: Box<dyn Outline>,
 }
 
 pub const SELECT_SCALE: f64 = 1.1;
@@ -192,7 +192,7 @@ impl SimpleShape {
   }
 
   #[throws(IE)]
-  fn svg_piece_raw(
+  pub fn svg_piece_raw(
     &self, f: &mut Html, pri: &PieceRenderInstructions,
     stroke_attrs_hook: &mut dyn FnMut(&mut String) -> Result<(),IE>,
   ) {
@@ -282,167 +282,3 @@ impl PieceSpec for piece_specs::Square {
   #[throws(SpecError)]
   fn load(&self, _: usize) -> Box<dyn Piece> { SimplePieceSpec::load(self)? }
 }
-
-#[derive(Debug,Clone,Serialize,Deserialize)]
-struct MagicOwner {
-  player: PlayerId,
-  desc: Html,
-  dasharray: Html,
-}
-
-#[derive(Debug,Serialize,Deserialize)]
-struct Hand {
-  shape: SimpleShape,
-}
-
-#[derive(Debug,Clone,Default,Serialize,Deserialize)]
-struct HandState {
-  owner: Option<MagicOwner>,
-}
-
-#[typetag::serde(name="Hand")]
-impl PieceXData for HandState { }
-
-#[typetag::serde]
-impl Outline for Hand {
-  delegate!{
-    to self.shape {
-      fn surround_path(&self, _pri: &PieceRenderInstructions)
-                       -> Result<Html,IE>;
-      fn thresh_dragraise(&self, _pri: &PieceRenderInstructions)
-                          -> Result<Option<Coord>,IE>;
-      fn bbox_approx(&self) -> [Pos;2];
-    }
-  }
-}
-
-#[typetag::serde]
-impl PieceSpec for piece_specs::Hand {
-  #[throws(SpecError)]
-  fn load(&self, _: usize) -> Box<dyn Piece> {
-    let (mut shape, common) = self.shape.load_raw()?;
-    if common.itemname.is_some() {
-      throw!(SpecError::ItemnameSpecifiedWhereForbidden);
-    }
-    if shape.nfaces() != 1 {
-      throw!(SpecError::MultifacetedMagic);
-    }
-    shape.itemname = "magic-hand".to_string();
-    Box::new(Hand {
-      shape,
-    }) as Box<dyn Piece>
-  }
-}
-
-impl Hand {
-  fn describe_html_inner(&self, xdata: Option<&HandState>) -> Html {
-    if_chain! {
-      if let Some(xdata) = xdata;
-      if let Some(owner) = &xdata.owner;
-      then { owner.desc.clone() }
-      else { Html(format!("a hand repository")) }
-    }
-  }
-}
-
-#[typetag::serde]
-impl Piece for Hand {
-  fn nfaces(&self) -> RawFaceId { 1 }
-  #[throws(IE)]
-  fn svg_piece(&self, f: &mut Html, gpc: &PieceState,
-               pri: &PieceRenderInstructions) {
-    self.shape.svg_piece_raw(f, pri, &mut |f: &mut String| {
-      if_chain!{
-        if let Some(xdata) = gpc.xdata.get::<HandState>()?;
-        if let Some(owned) = &xdata.owner;
-        then { write!(f, r##" stroke-dasharray="{}" "##,
-                      &owned.dasharray.0)?; }
-      }
-      Ok(())
-    })?;
-  }
-
-  #[throws(IE)]
-  fn describe_html(&self, _face: Option<FaceId>, gpc: &PieceState) -> Html {
-    let xdata = gpc.xdata.get()?;
-    self.describe_html_inner(xdata)
-  }
-
-  delegate!{
-    to self.shape {
-      fn itemname(&self) -> &str;
-    }
-  }
-
-  #[throws(InternalError)]
-  fn add_ui_operations(&self, upd: &mut Vec<UoDescription>,
-                       gpc: &PieceState) {
-    upd.push(if_chain! {
-      if let Some(xdata) = gpc.xdata.get::<HandState>()?;
-      if let Some(_owner) = &xdata.owner;
-      then { UoDescription {
-        kind: UoKind:: Piece,
-        def_key: 'C',
-        opname: "deactivate".to_owned(),
-        desc: Html::lit("Deactivate hand"),
-        wrc: WRC::Unpredictable,
-      }}
-      else { UoDescription {
-        kind: UoKind:: Piece,
-        def_key: 'C',
-        opname: "claim".to_owned(),
-        desc: Html::lit("Claim this as your hand"),
-        wrc: WRC::Unpredictable,
-      }}
-    })
-  }
-
-  fn ui_operation(&self, gs: &mut GameState, player: PlayerId,
-                  piece: PieceId, opname: &str, wrc: WhatResponseToClientOp)
-                  -> PieceUpdateResult {
-    let gplayers = &mut gs.players;
-    let gpc = gs.pieces.byid_mut(piece)?;
-    let xdata = gpc.xdata.get_mut::<HandState>()
-      .map_err(|e| APOE::ReportViaResponse(e.into()))?;
-    let old_desc = self.describe_html_inner(Some(xdata));
-
-    let dasharray = player_dasharray(gplayers, player);
-    let gpl = gplayers.byid_mut(player)?;
-    let _occults = &mut gs.occults;
-
-    let did;
-    match (opname, xdata.owner.is_some()) {
-      ("claim", false) => {
-        let nick = Html(htmlescape::encode_minimal(&gpl.nick));
-        let new_desc = Html(format!("{}'s hand", &nick.0));
-        xdata.owner = Some(MagicOwner {
-          player,
-          dasharray,
-          desc: new_desc,
-        });
-        // xxx recalculate occultations
-        did = format!("claimed {}", &old_desc.0);
-      }
-      ("deactivate", true) => {
-        xdata.owner = None;
-        // xxx recalculate occultations
-        did = format!("deactivated {}", &old_desc.0);
-      }
-      ("claim", true) |
-      ("deactivate", false) => {
-        throw!(OE::PieceHeld);
-      }
-      _ => {
-        throw!(OE::BadOperation);
-      }
-    }
-
-    let who_by = Html(htmlescape::encode_minimal(&gpl.nick));
-    let log = vec![ LogEntry { html: Html(format!("{} {}", who_by.0, did)) }];
-    Ok(PieceUpdate {
-      wrc, log,
-      ops: PUOs::Simple(PUO::Modify(())), // xxx
-      // xxx want PUU::RecalculateOccultations
-    })
-  }
-}