From: Ian Jackson Date: Sat, 30 Jan 2021 12:11:33 +0000 (+0000) Subject: hidden prep: Reorganise PieceUpdateFromOp X-Git-Tag: otter-0.4.0~605 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=6332302f49a8e4acffb55bf65ec6947da373774c;p=otter.git hidden prep: Reorganise PieceUpdateFromOp We are going to want to allow an op to give different answers to different clients. The representation from an op is going to be either basically what we have now, or a version where the PieceUpdateOp is different for each player. Prepare for this with some struct and type shuffling. We laave a convenience Into impl to allow ops to easily handle the simple case. No functional change. Signed-off-by: Ian Jackson --- diff --git a/daemon/api.rs b/daemon/api.rs index 9fa89756..976d5dc7 100644 --- a/daemon/api.rs +++ b/daemon/api.rs @@ -45,7 +45,7 @@ struct ApiPieceOpArgs<'a> { trait ApiPieceOp : Debug { #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp; + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate; #[throws(OnlineError)] fn check_held(&self, pc: &PieceState, player: PlayerId) { @@ -133,13 +133,13 @@ fn api_piece_op(form : Json>) if u_gen > q_gen { throw!(PieceOpError::Conflict) } form.op.check_held(pc,player)?; - let (wrc, update, logents) = + let update = form.op.op(ApiPieceOpArgs { gs, player, piece, p: p.as_ref(), lens: &lens, })?; - Ok::<_,ApiPieceOpError>((wrc, update, logents)) + Ok::<_,ApiPieceOpError>(update) })() { Err(ReportViaUpdate(poe)) => { PrepareUpdatesBuffer::piece_report_error( @@ -159,13 +159,13 @@ fn api_piece_op(form : Json>) warn!("api_piece_op ERROR {:?}: {:?}", &form, &err); Err(err)?; }, - Ok((wrc, update, logents)) => { + Ok(PieceUpdate { wrc, log, ops }) => { let mut buf = PrepareUpdatesBuffer::new(g, Some((wrc, client, form.cseq)), - Some(1 + logents.len())); + Some(1 + log.len())); - buf.piece_update(piece, update, &lens); - buf.log_updates(logents); + buf.piece_update(piece, ops, &lens); + buf.log_updates(log); debug!("api_piece_op OK: {:?}", &form); } @@ -221,7 +221,7 @@ api_route!{ struct ApiPieceGrab { } #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,player,piece,p,lens, .. } = a; let gpl = gs.players.byid(player)?; let pc = gs.pieces.byid_mut(piece)?; @@ -233,7 +233,7 @@ api_route!{ let logents = log_did_to_piece(gpl, lens, piece, pc, p, "grasped"); (WhatResponseToClientOp::Predictable, - update, logents) + update, logents).into() } } @@ -245,7 +245,7 @@ api_route!{ fn check_held(&self, _pc: &PieceState, _player: PlayerId) { } #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,player,piece,p,lens, .. } = a; let gpl = gs.players.byid(player)?; let pc = gs.pieces.byid_mut(piece)?; @@ -266,7 +266,7 @@ api_route!{ })}; (WhatResponseToClientOp::Predictable, - update, vec![logent]) + update, vec![logent]).into() } } @@ -275,7 +275,7 @@ api_route!{ struct ApiPieceUngrab { } #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,player,piece,p,lens, .. } = a; let gpl = gs.players.byid(player).unwrap(); let pc = gs.pieces.byid_mut(piece).unwrap(); @@ -287,7 +287,7 @@ api_route!{ let logents = log_did_to_piece(gpl, lens, piece, pc, p, "released"); (WhatResponseToClientOp::Predictable, - update, logents) + update, logents).into() } } @@ -297,13 +297,13 @@ api_route!{ z : ZCoord, } #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,piece, .. } = a; let pc = gs.pieces.byid_mut(piece).unwrap(); pc.zlevel = ZLevel { z : self.z.clone(), zg : gs.gen }; let update = PieceUpdateOp::SetZLevel(()); (WhatResponseToClientOp::Predictable, - update, vec![]) + update, vec![]).into() } } @@ -312,7 +312,7 @@ api_route!{ struct ApiPieceMove(Pos); #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,piece, .. } = a; let pc = gs.pieces.byid_mut(piece).unwrap(); let (pos, clamped) = self.0.clamped(gs.table_size); @@ -326,7 +326,7 @@ api_route!{ } let update = PieceUpdateOp::Move(self.0); (WhatResponseToClientOp::Predictable, - update, logents) + update, logents).into() } } @@ -335,7 +335,7 @@ api_route!{ struct ApiPieceRotate(CompassAngle); #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,player,piece,p,lens, .. } = a; let pc = gs.pieces.byid_mut(piece).unwrap(); let gpl = gs.players.byid(player).unwrap(); @@ -343,7 +343,7 @@ api_route!{ let logents = log_did_to_piece(gpl, lens, piece, pc, p, "rotated"); let update = PieceUpdateOp::Modify(()); (WhatResponseToClientOp::Predictable, - update, logents) + update, logents).into() } } @@ -352,7 +352,7 @@ api_route!{ struct ApiPiecePin (bool); #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,player,piece,p,lens, .. } = a; let pc = gs.pieces.byid_mut(piece).unwrap(); let gpl = gs.players.byid(player).unwrap(); @@ -363,7 +363,7 @@ api_route!{ if pc.pinned { "pinned" } else { "unpinned" }, ); (WhatResponseToClientOp::Predictable, - update, logents) + update, logents).into() } } @@ -376,7 +376,7 @@ api_route!{ wrc: WhatResponseToClientOp, } #[throws(ApiPieceOpError)] - fn op(&self, a: ApiPieceOpArgs) -> PieceUpdateFromOp { + fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate { let ApiPieceOpArgs { gs,player,piece,p,lens, .. } = a; '_normal_global_ops__not_loop: loop { let pc = gs.pieces.byid_mut(piece)?; @@ -390,7 +390,7 @@ api_route!{ wrc, PieceUpdateOp::Modify(()), log_did_to_piece(gpl, lens, piece, pc, p, "flipped"), - ) + ).into() }, _ => break, diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 82339ad6..2890dd24 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -820,7 +820,7 @@ impl UpdateHandler { let mut buf = PrepareUpdatesBuffer::new(g, None, Some(estimate)); for (upiece, uuop) in updates.pcs { let lens = TransparentLens { }; - buf.piece_update(upiece, uuop, &lens); + buf.piece_update(upiece, PUO::Simple(uuop), &lens); } buf.log_updates(updates.log); buf.raw_updates(raw); @@ -836,7 +836,7 @@ impl UpdateHandler { let mut buf = PrepareUpdatesBuffer::new(g, None, None); for (upiece, uuop) in bulk.pieces { let lens = TransparentLens { }; - buf.piece_update(upiece, uuop, &lens); + buf.piece_update(upiece, PUO::Simple(uuop), &lens); } if bulk.logs { diff --git a/src/global.rs b/src/global.rs index 9f951890..3ee067f3 100644 --- a/src/global.rs +++ b/src/global.rs @@ -699,7 +699,7 @@ impl<'ig> InstanceGuard<'ig> { let estimate = updated_pieces.len() + 1; let mut buf = PrepareUpdatesBuffer::new(self, None , Some(estimate)); for &piece in &updated_pieces { - buf.piece_update(piece, PieceUpdateOp::Modify(()), &lens); + buf.piece_update(piece, PieceUpdateOp::Modify(()).into(), &lens); } buf.finish(); diff --git a/src/imports.rs b/src/imports.rs index 72af0411..b79258fd 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -118,3 +118,6 @@ display_as_debug!(Impossible); pub type AE = anyhow::Error; pub type OE = OnlineError; pub type POEPP = PieceOpErrorPartiallyProcessed; + +// updates.rs +pub type PUO = PieceUpdateOps; diff --git a/src/updates.rs b/src/updates.rs index 5ff17001..fd60c675 100644 --- a/src/updates.rs +++ b/src/updates.rs @@ -100,9 +100,34 @@ pub enum PieceUpdateOp { SetZLevel(ZL), } -pub type PieceUpdateFromOp = (WhatResponseToClientOp, - PieceUpdateOp<(),()>, Vec); -pub type PieceUpdateResult = Result; +pub type PieceUpdateFromOpSimple = ( + WhatResponseToClientOp, + PieceUpdateOp<(),()>, + Vec, +); +pub type PieceUpdateResult = Result; + +#[derive(Debug)] +pub struct PieceUpdate { + pub wrc: WhatResponseToClientOp, + pub log: Vec, + pub ops: PieceUpdateOps, +} + +#[derive(Debug)] +pub enum PieceUpdateOps { + Simple(PieceUpdateOp<(),()>), +} + +impl From> for PieceUpdateOps { + fn from(op: PieceUpdateOp<(),()>) -> Self { PUO::Simple(op) } +} + +impl From for PieceUpdate { + fn from((wrc, op, log): PieceUpdateFromOpSimple) -> Self { + PieceUpdate { wrc, log, ops: op.into() } + } +} // ---------- for traansmission ---------- @@ -462,11 +487,13 @@ impl<'r> PrepareUpdatesBuffer<'r> { } } - pub fn piece_update(&mut self, piece: PieceId, update: PieceUpdateOp<(),()>, + pub fn piece_update(&mut self, piece: PieceId, ops: PieceUpdateOps, lens: &dyn Lens) { // Caller needs us to be infallible since it is too late by // this point to back out a game state change. + let PUO::Simple(update) = ops; + let update = self.piece_update_fallible( piece, update, lens, |pc, gen, by_client|