chiark / gitweb /
reworked angle
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 5 Jan 2021 01:33:47 +0000 (01:33 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 5 Jan 2021 01:33:47 +0000 (01:33 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
daemon/session.rs
src/gamestate.rs
src/lens.rs
src/spec.rs
templates/macros.tera
zcoord/misc.rs

index 06e8dbc3a0ca8b8bbbabd1e7780d29bf105eeb0b..b00fe990e127dd993fae330c9e93af634a16fe29 100644 (file)
@@ -322,6 +322,34 @@ impl ApiPieceOp for ApiPieceMove {
   }
 }
 
+/*
+#[derive(Debug,Serialize,Deserialize)]
+struct ApiPieceRotate (bool);
+#[post("/_/api/r", format="json", data="<form>")]
+#[throws(OE)]
+fn api_rotate(form : Json<ApiPiece<ApiPieceRotate>>) -> impl response::Responder<'static> {
+  api_piece_op(form)
+}
+impl ApiPieceOp for ApiPieceRotate {
+  #[throws(ApiPieceOpError)]
+  fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp {
+    let ApiPieceOpArgs { gs,piece, .. } = a;
+    let pc = gs.pieces.byid_mut(piece).unwrap();
+    let (pos, clamped) = self.0.clamped(gs.table_size);
+    let logents = vec![];
+    pc.pos = pos;
+    if clamped {
+      throw!(ApiPieceOpError::PartiallyProcessed(
+        PieceOpError::PosOffTable,
+        logents,
+      ));
+    }
+    let update = PieceUpdateOp::Move(self.0);
+    (WhatResponseToClientOp::Predictable,
+     update, logents)
+  }
+}*/
+
 #[derive(Debug,Serialize,Deserialize)]
 struct ApiPiecePin (bool);
 #[post("/_/api/pin", format="json", data="<form>")]
index 37ef11fffbfb1246a049ab9bb83030b68239bc79..56cf652f68080d7e4741a17fa63783152bd898ae 100644 (file)
@@ -31,7 +31,6 @@ struct SessionFormattedLogEntry {
 struct SessionPieceContext {
   id: VisiblePieceId,
   pos: Pos,
-  transform: VisibleAngleTransform,
   info: String, // SessionPieceLoadJson as JSON
 }
 
@@ -41,6 +40,7 @@ struct SessionPieceLoadJson<'r> {
   z: ZCoord,
   zg: Generation,
   pinned: bool,
+  angle: VisiblePieceAngle,
   uos: &'r [UoDescription],
 }
 
@@ -104,25 +104,25 @@ fn session_inner(form : Json<SessionForm>,
 
     for (gpid, pr) in pieces {
       let pri = PieceRenderInstructions {
-        id : make_pieceid_visible(gpid),
-        face : pr.face,
+        id: make_pieceid_visible(gpid),
+        angle: make_angle_visible(pr.angle),
+        face: pr.face,
       };
       let p = if let Some(p) = ig.ipieces.get(gpid) { p }
       else { continue /* was deleted */ };
       let defs = p.make_defs(&pri)?;
       alldefs.push((pri.id, defs));
-      let transform = make_angle_visible(pr.angle, pr.pos);
 
       let for_info = SessionPieceLoadJson {
-        held : &pr.held,
-        z  : pr.zlevel.z.clone(),
-        zg : pr.zlevel.zg,
-        pinned : pr.pinned,
-        uos : &p.ui_operations()?,
+        held: &pr.held,
+        z: pr.zlevel.z.clone(),
+        zg: pr.zlevel.zg,
+        pinned: pr.pinned,
+        angle: pri.angle,
+        uos: &p.ui_operations()?,
       };
 
       let for_piece = SessionPieceContext {
-        transform,
         id: pri.id,
         pos: pr.pos,
         info: serde_json::to_string(&for_info)
index d68be53e3cb8109c2b57d34466967442f2147300..19f1851d709dc275bc8bcebe1842da9a704c9abb 100644 (file)
@@ -23,6 +23,11 @@ pub struct Generation(pub u64);
 
 visible_slotmap_key!{ VisiblePieceId('.') }
 
+#[derive(Clone,Copy,Debug)]
+#[derive(Serialize,Deserialize)]
+#[serde(transparent)]
+pub struct VisiblePieceAngle(PieceAngle);
+
 #[derive(Clone,Debug)]
 #[derive(Serialize,Deserialize)]
 #[serde(transparent)]
@@ -141,9 +146,10 @@ pub trait Piece: Outline + Send + Debug {
   fn itemname(&self) -> &str;
 }
 
-#[derive(Debug,Copy,Clone)]
+#[derive(Debug,Clone)]
 pub struct PieceRenderInstructions {
   pub id: VisiblePieceId,
+  pub angle: VisiblePieceAngle,
   pub face: FaceId,
 }
 
@@ -226,6 +232,18 @@ impl Debug for Html {
   }
 }
 
+impl VisiblePieceAngle {
+  pub fn to_transform(self) -> VisibleAngleTransform {
+    match self.0 {
+      PieceAngle::Compass(angle) => VisibleAngleTransform(
+        zcoord::misc::raw_angle_transform(
+          angle.into()
+        )
+      ),
+    }
+  }
+}
+
 // ---------- game state - rendering etc. ----------
 
 impl PieceState {
@@ -259,9 +277,10 @@ impl<T> PieceExt for T where T: Piece + ?Sized {
       Some(n) => n,
       None => -1,
     };
+    let transform = pri.angle.to_transform();
     write!(&mut defs.0,
-           r##"<g id="piece{}" data-dragraise="{}">"##,
-           pri.id, dragraise)?;
+           r##"<g id="piece{}" transform="{}" data-dragraise="{}">"##,
+           pri.id, &transform.0, dragraise)?;
     self.svg_piece(&mut defs, &pri)?;
     write!(&mut defs.0, r##"</g>"##)?;
     write!(&mut defs.0,
@@ -328,8 +347,7 @@ pub fn make_pieceid_visible(p: PieceId) -> VisiblePieceId {
   VisiblePieceId(kd)
 }
 
-pub fn make_angle_visible(angle: PieceAngle, pos: Pos)
-                          -> VisibleAngleTransform {
+pub fn make_angle_visible(angle: PieceAngle) -> VisiblePieceAngle {
   // todo-lens need to do censorship mapping here
-  VisibleAngleTransform(angle.to_transform(pos))
+  VisiblePieceAngle(angle)
 }
index f5bd2f3820010468cc0ee4a1572b507bc5a1616d..3b22a69cfe6295e30e6465693186234be190c7e2 100644 (file)
@@ -27,7 +27,8 @@ impl Lens for TransparentLens {
   fn log_pri(&self, piece: PieceId, pc: &PieceState)
              -> PieceRenderInstructions {
     let id = self.pieceid2visible(piece);
-    PieceRenderInstructions { id, face : pc.face }
+    let angle = make_angle_visible(pc.angle);
+    PieceRenderInstructions { id, angle, face: pc.face }
   }
   fn svg_pri(&self, piece: PieceId, pc: &PieceState, _player: PlayerId)
              -> PieceRenderInstructions {
index 23712b370a80ef81f42baf1bca209fdb05d3ab7e..2c01f0141f9e3dade2ca511e6ad1adcbaf34789d 100644 (file)
@@ -315,19 +315,6 @@ pub mod implementation {
     }
   }
 
-  impl PieceAngle {
-    pub fn to_transform(self, pos: Pos) -> String {
-      match self {
-        PieceAngle::Compass(CompassAngle(angle)) => {
-          if angle == 0 { default() }
-          else { format!("rotate({}, {}, {})",
-                         -45 * (angle as i16),
-                         pos.0[0], pos.0[1]) }
-        }
-      }
-    }
-  }
-
   impl<P: Eq + Hash> Default for Acl<P> {
     fn default() -> Self { Acl { ents: default() } }
   }
index 32f8eac50d9105eb6d1377352a77bdbbfabba7ca..48dfa885faa199e226ab84f0dfe941d0dd69be73 100644 (file)
@@ -61,7 +61,6 @@ Hi {{nick | escape}}
 {%- for piece in uses %}
       <use id="use{{ piece.id }}" href="#piece{{ piece.id }}"
           x="{{ piece.pos[0] }}" y="{{ piece.pos[1] }}"
-           transform="{{ piece.transform }}"
           data-piece="{{ piece.id }}" data-info="{{ piece.info | escape }}" />
 {%- endfor %}
       <g id="defs_marker"></g>
index 842273ea4fa61b55a62d2fbd48dca6aa20a5229a..3f0057c7aade539181ce7e779afa30a00d8334e9 100644 (file)
@@ -24,3 +24,9 @@ pub fn timestring_abbreviate<'x>(base: &str, this: &'x str)
     else { (this, false) }
   }
 }
+
+pub fn raw_angle_transform(compass: u8) -> String {
+  assert!(compass < 8);
+  if compass == 0 { Default::default() }
+  else { format!("rotate({})", -45 * (compass as i16)) }
+}