chiark / gitweb /
use PrepareUpdatesBuffer for errors
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 3 Sep 2020 20:53:06 +0000 (21:53 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 3 Sep 2020 20:53:06 +0000 (21:53 +0100)
src/api.rs
src/updates.rs

index e3088e258e0ef6233fee1568180e01cd6566270d..6158a134229908e74aa8fb801d6ce095fc90ee84 100644 (file)
@@ -78,6 +78,7 @@ fn api_piece_op<O: ApiPieceOp>(form : Json<ApiPiece<O>>)
   let _ = gs.players.byid(player)?;
   let lens = TransparentLens { };
   let piece = lens.decode_visible_pieceid(form.piece, player);
+  use ApiPieceOpError::*;
 
   match (||{
     let pc = gs.pieces.byid_mut(piece)
@@ -97,8 +98,16 @@ fn api_piece_op<O: ApiPieceOp>(form : Json<ApiPiece<O>>)
     let (update, logents) = form.op.op(gs,player,piece,&lens)?;
     Ok::<_,ApiPieceOpError>((update, logents))
   })() {
-    Err(err) => err.report(&mut ig, piece, player, client, &lens)?,
-
+    Err(ReportViaUpdate(poe)) => {
+      PrepareUpdatesBuffer::piece_report_error(
+        &mut ig, poe,
+        piece, player, client, &lens
+      )?;
+    },
+    Err(ReportViaResponse(err)) => {
+      eprintln!("API ERROR => {:?}", &err);
+      Err(err)?;
+    },
     Ok((update, logents)) => {
       let mut buf = PrepareUpdatesBuffer::new(g, Some((client, form.cseq)),
                                               Some(1 + logents.len()));
@@ -112,43 +121,6 @@ fn api_piece_op<O: ApiPieceOp>(form : Json<ApiPiece<O>>)
   ""
 }
 
-impl ApiPieceOpError {
-  pub fn report(self, ig: &mut InstanceGuard,
-                piece: PieceId, player: PlayerId, client: ClientId,
-                lens: &dyn Lens) -> Result<(),OE> {
-    use ApiPieceOpError::*;
-
-    eprintln!("ApiPieceOpError.report {:?}", &self);
-
-    match self {
-      ReportViaUpdate(poe) => {
-        ig.gs.gen.increment();
-        let gen = ig.gs.gen;
-        let pc = ig.gs.pieces.byid_mut(piece).map_err(|()| OE::PieceGone)?;
-        let pri = lens.svg_pri(piece,pc,player);
-        let state = pc.prep_piecestate(&pri)?;
-        let pl_updates = ig.updates.get_mut(player).ok_or(OE::NoPlayer)?;
-        let pue = PreparedUpdateEntry::Error(
-          Some(client),
-          ErrorSignaledViaUpdate::PieceOpError {
-            piece: pri.id,
-            error: poe,
-            state,
-          },
-        );
-        let update = PreparedUpdate { gen, us : vec![ pue ] };
-        pl_updates.push(Arc::new(update));
-      },
-      
-      ReportViaResponse(err) => {
-        eprintln!("API ERROR => {:?}", &err);
-        Err(err)?;
-      },
-    }
-    Ok(())
-  }
-}
-
 #[derive(Debug,Serialize,Deserialize)]
 struct ApiPieceGrab {
 }
index 479cc379fcbbefc64a3654e9efc541c5dff15ab7..71544b6aaca043af64225b660a9bf69f3194b7a3 100644 (file)
@@ -209,6 +209,40 @@ impl<'r> PrepareUpdatesBuffer<'r> {
     }
   }
 
+  fn new_for_error(ig: &'r mut Instance) -> Self {
+    Self::new(ig, None, Some(1))
+  }
+  pub fn piece_report_error(ig: &mut Instance,
+                            error: PieceOpError,
+                            piece: PieceId, player: PlayerId, client: ClientId,
+                            lens: &dyn Lens) -> Result<(),OE> {
+    let mut buf = PrepareUpdatesBuffer::new_for_error(ig);
+    let update = buf.piece_update_fallible(
+      piece, PieceUpdateOp::Modify(()), lens
+    )?;
+    let update = match update {
+      PreparedUpdateEntry::Piece {
+        piece,
+        op : PieceUpdateOp::Modify(state),
+        ..
+      } => {
+        PreparedUpdateEntry::Error(
+          Some(client),
+          ErrorSignaledViaUpdate::PieceOpError {
+            piece, error, state,
+          },
+        )
+      },
+      _ => panic!(),
+    };
+    let update = PreparedUpdate { gen: buf.gen, us : vec![ update ] };
+    assert!(buf.us.is_empty());
+    mem::drop(buf);
+    let pl_updates = ig.updates.get_mut(player).ok_or(OE::NoPlayer)?;
+    pl_updates.push(Arc::new(update));
+    Ok(())
+  }
+
   #[throws(InternalError)]
   fn piece_update_fallible(&mut self, piece: PieceId,
                            update: PieceUpdateOp<()>,