chiark / gitweb /
refactor: move PieceExt methods into PieceRenderInstructions
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 28 Feb 2021 12:56:24 +0000 (12:56 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 28 Feb 2021 12:56:24 +0000 (12:56 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
daemon/cmdlistener.rs
daemon/session.rs
src/bin/otterlib.rs
src/gamestate.rs
src/hidden.rs
src/updates.rs

index 84d8f32584f74add80e9ae8d2ee17cb18331bafe..5628af90e219423669924f963b5f2e30b03438f2 100644 (file)
@@ -267,7 +267,7 @@ api_route!{
 
       let gpl = players.byid_mut(player)?;
       let pri = piece_pri(&gs.occults, player, gpl, piece, pc);
-      let pcs = p.describe_pri(pc, &pri).0;
+      let pcs = pri.describe(pc, &p).0;
 
       pc.held = Some(player);
 
index 2d04c1044a41fa75c404de7d0006fe7385aeb3a7..b3d96715a9da95162395f4c0fe68fd2023fee558 100644 (file)
@@ -379,16 +379,23 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
         |(piece,p)| (|| Ok::<_,MgmtError>(if_chain!{
           let &GPiece { pos, face, .. } = p;
           if let Some(pinfo) = ig.ipieces.get(piece);
-          let desc_html = pinfo.describe_html_infallible(None, p);
-          let itemname = pinfo.itemname().to_string();
-          let bbox = pinfo.bbox_approx()?;
           let visible = if ! piece_at_all_occluded(&ig.gs.occults, piece) {
+            // todo: something more sophisticated would be nice
+            let pri = PieceRenderInstructions {
+              id: VisiblePieceId(piece.data()),
+              angle: VisiblePieceAngle(p.angle), // xxx
+              face: default(),
+              occluded: PriOccluded::Visible,
+            };
+            let bbox = pinfo.bbox_approx()?;
+            let desc_html = pri.describe(p, pinfo);
             Some(MgmtGamePieceVisibleInfo {
               pos, face, desc_html, bbox
             })
           } else {
             None
           };
+          let itemname = pinfo.itemname().to_string();
           then {
             Some(MgmtGamePieceInfo {
               piece, itemname,
@@ -559,7 +566,13 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
       let gs = &mut ig.gs;
       let pc = gs.pieces.as_mut(modperm).remove(piece);
       let desc_html = if let Some(pc) = &pc {
-        p.describe_html_infallible(Some(default()), pc)
+        let pri = PieceRenderInstructions {
+          id: default(),
+          face: default(),
+          angle: VisiblePieceAngle(pc.angle), // xxx
+          occluded: PriOccluded::Visible,
+        };
+        pri.describe(pc, &p)
       } else {
         Html::lit("<piece partially missing from game state!>")
       };
index f5e23d25f2c4e40230886ee8b6b70c512abc57c4..c6359e9213e8803b163044bceb832e69779f9d0a 100644 (file)
@@ -114,9 +114,9 @@ fn session_inner(form: Json<SessionForm>,
       let pri = piece_pri(&ig.gs.occults, player, gpl, gpid, pr);
       let p = if let Some(p) = ig.ipieces.get(gpid) { p }
       else { continue /* was deleted */ };
-      let defs = p.make_defs(pr, &pri)?;
+      let defs = pri.make_defs(pr, p)?;
       alldefs.push((pri.id, defs));
-      let desc = p.describe_pri(&pr, &pri);
+      let desc = pri.describe(&pr, p);
 
       let vangle = match pri.angle {
         VisiblePieceAngle(PieceAngle::Compass(vangle)) => vangle,
@@ -129,7 +129,7 @@ fn session_inner(form: Json<SessionForm>,
         pinned: pr.pinned,
         angle: vangle,
         desc,
-        uos: &p.ui_operations(pr)?,
+        uos: &pri.ui_operations(pr, p.as_ref())?,
       };
 
       let for_piece = SessionPieceContext {
index 9ac611c48cfa44fb7052c5bd86bd7d701f073a3e..e55ece7e179c3eec4ccfa2dbb2460e12e74b492f 100644 (file)
@@ -137,7 +137,8 @@ fn preview(items: Vec<ItemForOutput>) {
     let getpri = |face: FaceId| PieceRenderInstructions {
       id: default(),
       angle: VisiblePieceAngle(default()),
-      face
+      face,
+      occluded: PriOccluded::Visible,
     };
 
     for facecol in 0..(if only1 { 1 } else { max_facecols }) {
index 130f1caab6caf9111f1e412af04306c1e7cd1675..cdb7ed6466f77f96b5a188279cf482a1896ed1b3 100644 (file)
@@ -177,13 +177,6 @@ pub struct ApiPieceOpArgs<'a> {
   pub p: &'a dyn PieceTrait,
 }
 
-#[derive(Debug,Clone)]
-pub struct PieceRenderInstructions {
-  pub id: VisiblePieceId,
-  pub angle: VisiblePieceAngle,
-  pub face: FaceId,
-}
-
 #[typetag::serde(tag="type")]
 pub trait PieceSpec: Debug {
   fn count(&self) -> usize { 1 }
@@ -286,11 +279,11 @@ impl GPiece {
     PreparedPieceState {
       pos        : self.pos,
       held       : self.held,
-      svg        : p.make_defs(self, pri)?,
+      svg        : pri.make_defs(self, &p)?,
       z          : self.zlevel.z.clone(),
       zg         : self.zlevel.zg,
       pinned     : self.pinned,
-      uos        : p.ui_operations(self)?,
+      uos        : pri.ui_operations(self, p)?,
     }
   }
 
@@ -363,22 +356,30 @@ impl PieceXDataExt for PieceXDataState {
   }
 }
 
-pub trait PieceExt {
-  fn make_defs(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
-               -> Result<Html, IE>;
-  fn describe_html_infallible(&self, face: Option<FaceId>, gpc: &GPiece)
-                              -> Html;
-  fn describe_pri(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
-                  -> Html;
-  fn ui_operations(&self, gpc: &GPiece) -> Result<Vec<UoDescription>, IE>;
+#[derive(Debug,Clone)]
+pub struct PieceRenderInstructions {
+  pub id: VisiblePieceId,
+  pub angle: VisiblePieceAngle,
+  pub face: FaceId,
+  pub occluded: PriOccluded,
 }
 
-impl<T> PieceExt for T where T: PieceTrait + ?Sized {
+#[derive(Debug,Clone,Copy)]
+pub enum PriOccluded { Visible /*, Occluded*/ }
+
+impl PieceRenderInstructions {
   #[throws(IE)]
-  fn make_defs(&self,  gpc: &GPiece, pri: &PieceRenderInstructions)
-               -> Html {
+  pub fn make_defs<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
+    where P:Borrow<dyn PieceTrait + 'p>
+  {
+    #[throws(IE)]
+    fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
+             -> Html
+  {
+    let PriOccluded::Visible = pri.occluded;
+
     let mut defs = Html(String::new());
-    let dragraise = match self.thresh_dragraise(pri)? {
+    let dragraise = match p.thresh_dragraise(pri)? {
       Some(n) if n < 0 => throw!(SvgE::NegativeDragraise),
       Some(n) => n,
       None => -1,
@@ -387,34 +388,47 @@ impl<T> PieceExt for T where T: PieceTrait + ?Sized {
     write!(&mut defs.0,
            r##"<g id="piece{}" transform="{}" data-dragraise="{}">"##,
            pri.id, &transform.0, dragraise)?;
-    self.svg_piece(&mut defs, gpc, &pri)?;
+    p.svg_piece(&mut defs, gpc, pri)?;
     write!(&mut defs.0, r##"</g>"##)?;
     write!(&mut defs.0,
            r##"<path id="surround{}" d="{}"/>"##,
-           pri.id, self.surround_path(&pri)?.0)?;
+           pri.id, p.surround_path(pri)?.0)?;
     defs
   }
+  inner(self, gpc, p.borrow())?
+  }
+
+  pub fn describe<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
+    where P:Borrow<dyn PieceTrait + 'p>
+  {
+    fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
+             -> Html
+  {
+    let PriOccluded::Visible = pri.occluded;
 
-  fn describe_html_infallible(&self, face: Option<FaceId>, gpc: &GPiece)
-                              -> Html {
-    self.describe_html(face, gpc)
+    pri.describe_fallible(gpc, p)
       .unwrap_or_else(|e| {
         error!("error describing piece: {:?}", e);
         Html::lit("<internal error describing piece>")
       })
   }
+  inner(self, gpc, p.borrow())
+  }
 
-  fn describe_pri(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
-                  -> Html {
-    self.describe_html_infallible(Some(pri.face), gpc)
+  #[throws(IE)]
+  pub fn describe_fallible(&self, gpc: &GPiece, p: &dyn PieceTrait) -> Html {
+    p.describe_html(Some(gpc.face), gpc)?
   }
 
   #[throws(InternalError)]
-  fn ui_operations(&self, gpc: &GPiece) -> Vec<UoDescription> {
+  pub fn ui_operations(&self, gpc: &GPiece, p: &dyn PieceTrait)
+                   -> Vec<UoDescription>
+  {
+    let PriOccluded::Visible = self.occluded;
     type WRC = WhatResponseToClientOp;
 
     let mut out = vec![];
-    if self.nfaces() > 1 {
+    if p.nfaces() > 1 {
       out.push(UoDescription {
         wrc: WRC::UpdateSvg,
         kind: UoKind::Global,
@@ -423,7 +437,7 @@ impl<T> PieceExt for T where T: PieceTrait + ?Sized {
         desc: Html::lit("flip"),
       })
     }
-    self.add_ui_operations(&mut out, gpc)?;
+    p.add_ui_operations(&mut out, gpc)?;
     out
   }
 }
index da3a757b7fbf1bc7ddb6ff50e4f837df8106c5d3..1e2b1b42dc4841cf640e46c5c17eae973473b106 100644 (file)
@@ -183,9 +183,10 @@ pub fn piece_pri(
   let vpiece = gpl.idmap.fwd_or_insert(piece);
   let angle = VisiblePieceAngle(pc.angle);
   let face = pc.face;
+  let occluded = PriOccluded::Visible; // xxx
   trace!("{} {:?} => {} face={:?} angle={:?}",
          player, piece, vpiece, face, angle);
-  PieceRenderInstructions { id: vpiece, angle, face }
+  PieceRenderInstructions { id: vpiece, angle, face, occluded }
 }
 
 pub fn piece_at_all_occluded(
index 6ce4b993696beb6e60d526ea5c124ffa943a5357..41297a2eaca4e66ea1641f7a023fac840ed1e0af 100644 (file)
@@ -211,7 +211,7 @@ pub fn log_did_to_piece_whoby(
     "{} {} {}",
     &who_by.0,
     did,
-    p.describe_pri(pc, &pri).0,
+    pri.describe(pc, &p).0,
   ))}];
   (log, who_by)
 }