chiark / gitweb /
add wrc to piece op api
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 30 Sep 2020 22:40:15 +0000 (23:40 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 30 Sep 2020 22:40:15 +0000 (23:40 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/api.rs
src/gamestate.rs
src/updates.rs

index 7ef93980f21a83a887f6c3c9ac4e7153932958e5..eefecdd40d09c17c9ff4a2c83c72d2cc404a8ad4 100644 (file)
@@ -4,6 +4,8 @@
 
 use crate::imports::*;
 
+type WRC = WhatResponseToClientOp;
+
 #[derive(Debug,Serialize,Deserialize)]
 struct ApiPiece<O : ApiPieceOp> {
   ctoken : RawToken,
@@ -120,8 +122,8 @@ fn api_piece_op<O: ApiPieceOp>(form : Json<ApiPiece<O>>)
     if pc.held != None && pc.held != Some(player) {
       throw!(OnlineError::PieceHeld)
     };
-    let (update, logents) = form.op.op(gs,player,piece,p.as_ref(),&lens)?;
-    Ok::<_,ApiPieceOpError>((update, logents))
+    let (wrc, update, logents) = form.op.op(gs,player,piece,p.as_ref(),&lens)?;
+    Ok::<_,ApiPieceOpError>((wrc, update, logents))
   })() {
     Err(ReportViaUpdate(poe)) => {
       PrepareUpdatesBuffer::piece_report_error(
@@ -139,9 +141,9 @@ fn api_piece_op<O: ApiPieceOp>(form : Json<ApiPiece<O>>)
       warn!("api_piece_op ERROR {:?}: {:?}", &form, &err);
       Err(err)?;
     },
-    Ok((update, logents)) => {
+    Ok((wrc, update, logents)) => {
       let mut buf = PrepareUpdatesBuffer::new(g,
-          Some((WhatResponseToClientOp::Predictable, client, form.cseq)),
+                                              Some((wrc, client, form.cseq)),
                                               Some(1 + logents.len()));
       
       buf.piece_update(piece, update, &lens);
@@ -165,8 +167,7 @@ fn api_grab(form : Json<ApiPiece<ApiPieceGrab>>)
 impl ApiPieceOp for ApiPieceGrab {
   #[throws(ApiPieceOpError)]
   fn op(&self, gs: &mut GameState, player: PlayerId, piece: PieceId,
-        p: &dyn Piece, lens: &dyn Lens)
-        -> (PieceUpdateOp<()>, Vec<LogEntry>) {
+        p: &dyn Piece, lens: &dyn Lens) -> PieceUpdateFromOp {
     let pl = gs.players.byid(player)?;
     let pc = gs.pieces.byid_mut(piece)?;
 
@@ -181,7 +182,8 @@ impl ApiPieceOp for ApiPieceGrab {
                      p.describe_pri(&lens.log_pri(piece, pc)).0)),
     };
 
-    (update, vec![logent])
+    (WhatResponseToClientOp::Predictable,
+     update, vec![logent])
   }
 }
 
@@ -197,8 +199,7 @@ fn api_ungrab(form : Json<ApiPiece<ApiPieceUngrab>>)
 impl ApiPieceOp for ApiPieceUngrab {
   #[throws(ApiPieceOpError)]
   fn op(&self, gs: &mut GameState, player: PlayerId, piece: PieceId,
-        p: &dyn Piece, lens: &dyn Lens)
-        -> (PieceUpdateOp<()>, Vec<LogEntry>) {
+        p: &dyn Piece, lens: &dyn Lens) -> PieceUpdateFromOp {
     let pl = gs.players.byid(player).unwrap();
     let pc = gs.pieces.byid_mut(piece).unwrap();
 
@@ -213,7 +214,8 @@ impl ApiPieceOp for ApiPieceUngrab {
                      p.describe_pri(&lens.log_pri(piece, pc)).0)),
     };
 
-    (update, vec![logent])
+    (WhatResponseToClientOp::Predictable,
+     update, vec![logent])
   }
 }
 
@@ -230,12 +232,12 @@ fn api_raise(form : Json<ApiPiece<ApiPieceRaise>>)
 impl ApiPieceOp for ApiPieceRaise {
   #[throws(ApiPieceOpError)]
   fn op(&self, gs: &mut GameState, _: PlayerId, piece: PieceId,
-        _p: &dyn Piece, _: &dyn Lens)
-        -> (PieceUpdateOp<()>, Vec<LogEntry>) {
+        _p: &dyn Piece, _: &dyn Lens) -> PieceUpdateFromOp {
     let pc = gs.pieces.byid_mut(piece).unwrap();
     pc.zlevel = ZLevel { z : self.z, zg : gs.gen };
     let update = PieceUpdateOp::SetZLevel(pc.zlevel);
-    (update, vec![])
+    (WhatResponseToClientOp::Predictable,
+     update, vec![])
   }
 }
 
@@ -249,8 +251,7 @@ fn api_move(form : Json<ApiPiece<ApiPieceMove>>) -> impl response::Responder<'st
 impl ApiPieceOp for ApiPieceMove {
   #[throws(ApiPieceOpError)]
   fn op(&self, gs: &mut GameState, _: PlayerId, piece: PieceId,
-        _p: &dyn Piece, _lens: &dyn Lens)
-        -> (PieceUpdateOp<()>, Vec<LogEntry>) {
+        _p: &dyn Piece, _lens: &dyn Lens) -> PieceUpdateFromOp {
     let pc = gs.pieces.byid_mut(piece).unwrap();
     let (pos, clamped) = self.0.clamped(gs.table_size);
     let logents = vec![];
@@ -262,14 +263,15 @@ impl ApiPieceOp for ApiPieceMove {
       ));
     }
     let update = PieceUpdateOp::Move(self.0);
-    (update, logents)
+    (WhatResponseToClientOp::Predictable,
+     update, logents)
   }
 }
 
 const DEFKEY_FLIP : UoKey = 'f';
 
 #[derive(Debug,Serialize,Deserialize)]
-struct ApiPieceUo (UoKey);
+struct ApiPieceUo { opname: String, wrc: WhatResponseToClientOp }
 #[post("/_/api/k", format="json", data="<form>")]
 #[throws(OE)]
 fn api_uo(form : Json<ApiPiece<ApiPieceUo>>) -> impl response::Responder<'static> {
@@ -278,24 +280,23 @@ fn api_uo(form : Json<ApiPiece<ApiPieceUo>>) -> impl response::Responder<'static
 impl ApiPieceOp for ApiPieceUo {
   #[throws(ApiPieceOpError)]
   fn op(&self, gs: &mut GameState, player: PlayerId, piece: PieceId,
-        p: &dyn Piece, lens: &dyn Lens)
-        -> (PieceUpdateOp<()>, Vec<LogEntry>) {
-    let def_key = self.0;
-
+        p: &dyn Piece, lens: &dyn Lens) -> PieceUpdateFromOp {
     '_normal_global_ops__not_loop: loop {
       let pc = gs.pieces.byid_mut(piece)?;
       let pl = gs.players.byid(player)?;
-      let _: Impossible = match def_key {
+      let _: Impossible = match (self.opname.as_str(), self.wrc) {
 
-        DEFKEY_FLIP => {
+        ("flip", wrc@ WRC::UpdateSvg) => {
           let nfaces = p.nfaces();
           pc.face = (RawFaceId::from(pc.face) % nfaces).into();
-          return (PieceUpdateOp::Modify(()),
-                  vec![ LogEntry { html: Html(format!(
-                    "{} flipped {}",
-                    &htmlescape::encode_minimal(&pl.nick),
-                    p.describe_pri(&lens.log_pri(piece, pc)).0
-                  )) }])
+          return (
+            wrc,
+            PieceUpdateOp::Modify(()),
+            vec![ LogEntry { html: Html(format!(
+              "{} flipped {}",
+              &htmlescape::encode_minimal(&pl.nick),
+              p.describe_pri(&lens.log_pri(piece, pc)).0
+            )) }])
         },
 
         _ => break,
@@ -303,13 +304,13 @@ impl ApiPieceOp for ApiPieceUo {
     }
 
     '_abnormal_global_ops__notloop: loop {
-      let _: Impossible = match def_key {
+      let _: Impossible = match self {
 
         _ => break,
       };
     }
 
-    p.ui_operation(gs, player, piece, def_key, lens)?
+    p.ui_operation(gs, player, piece, &self.opname, self.wrc, lens)?
   }
 }
 
index 53b759aab87018a57c11f73d97b2cda795d44c7b..1a0566ba041baf192c86b51bd989bd175a4f19e7 100644 (file)
@@ -99,6 +99,7 @@ pub struct UoDescription {
   pub def_key: UoKey,
   pub opname: String,
   pub desc: Html,
+  pub wrc: WhatResponseToClientOp,
 }
 
 #[typetag::serde]
@@ -110,7 +111,8 @@ pub trait Piece : Outline + Send + Debug {
 
   fn ui_operation(&self,
                   _gs: &mut GameState, _player: PlayerId, _piece: PieceId,
-                  _def_key: char, _lens: &dyn Lens)
+                  _opname: &str, _wrc: WhatResponseToClientOp,
+                  _lens: &dyn Lens)
                   -> PieceUpdateResult {
     throw!(OE::BadOperation)
   }
@@ -265,9 +267,12 @@ impl<T> PieceExt for T where T: Piece + ?Sized {
 
   #[throws(InternalError)]
   fn ui_operations(&self) -> Vec<UoDescription> {
+    type WRC = WhatResponseToClientOp;
+
     let mut out = vec![];
     if self.nfaces() > 1 {
       out.push(UoDescription {
+        wrc: WRC::UpdateSvg,
         kind: UoKind::Global,
         def_key: 'f'.into(),
         opname: "flip".to_string(),
@@ -276,6 +281,7 @@ impl<T> PieceExt for T where T: Piece + ?Sized {
     }
     out.push(UoDescription {
       kind: UoKind::GlobalExtra,
+      wrc: WRC::Predictable,
       def_key: 'l'.into(),
       opname: "lower".to_string(),
       desc: Html::lit("lower (send to bottom)"),
index 5fe1e590f77b27f6d0d9da93fe1c743dc25003ad..b573ae83bc1f3dff999dadd41e60cdfb93c2d167 100644 (file)
@@ -72,7 +72,8 @@ pub enum PieceUpdateOp<NS> {
   SetZLevel(ZLevel),
 }
 
-pub type PieceUpdateFromOp = (PieceUpdateOp<()>, Vec<LogEntry>);
+pub type PieceUpdateFromOp = (WhatResponseToClientOp,
+                              PieceUpdateOp<()>, Vec<LogEntry>);
 pub type PieceUpdateResult = Result<PieceUpdateFromOp, ApiPieceOpError>;
 
 // ---------- for traansmission ----------
@@ -249,7 +250,7 @@ type IsResponseToClientOp = Option<(
   ClientId,
   ClientSequence,
 )>;
-#[derive(Debug,Copy,Clone)]
+#[derive(Debug,Copy,Clone,Serialize,Deserialize)]
 pub enum WhatResponseToClientOp {
   /// In PROTOCOL.md terms, a Client update
   Predictable,