From: Ian Jackson Date: Wed, 17 Mar 2021 18:11:22 +0000 (+0000) Subject: Plumb &GameState through into svg_piece X-Git-Tag: otter-0.5.0~687 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=41324c04233f3652e02476801bce898c5cfebcda;p=otter.git Plumb &GameState through into svg_piece This is quite a lot of plumbing. Signed-off-by: Ian Jackson --- diff --git a/daemon/session.rs b/daemon/session.rs index 8a8214e7..04b64b53 100644 --- a/daemon/session.rs +++ b/daemon/session.rs @@ -109,6 +109,7 @@ fn session_inner(form: Json, } let layout = gpl.layout; let mut pieces: Vec<_> = ig.gs.pieces.iter().collect(); + let nick = gpl.nick.clone(); pieces.sort_by_key(|(_,pr)| &pr.zlevel); @@ -116,11 +117,14 @@ fn session_inner(form: Json, let ipc = if let Some(pto) = ig.ipieces.get(piece) { pto } else { continue /* was deleted */ }; - let pri = piece_pri(ioccults, &ig.gs.occults, player, gpl, + let pri = piece_pri(ioccults, &ig.gs.occults, player, + // we need to re-obtain gpl, because + // make_defs needs to borrow the whole of &gs + ig.gs.players.byid_mut(player)?, piece, gpc, ipc); let pri = if let Some(pri) = pri { pri } else { continue /*invisible*/}; - let defs = pri.make_defs(ioccults, gpc, ipc)?; + let defs = pri.make_defs(ioccults, &ig.gs, gpc, ipc)?; alldefs.push((pri.vpid, defs)); let desc = pri.describe(ioccults, &gpc, ipc); @@ -203,7 +207,7 @@ fn session_inner(form: Json, defs: alldefs, uses, scale: SVG_SCALE, - nick: gpl.nick.clone(), + nick, sse_url_prefix, player_info_pane, ptoken: form.ptoken.clone(), diff --git a/src/bin/otterlib.rs b/src/bin/otterlib.rs index b3400384..19a62360 100644 --- a/src/bin/otterlib.rs +++ b/src/bin/otterlib.rs @@ -173,7 +173,7 @@ fn preview(items: Vec) { } let mut html = Html("".into()); let gpc = GPiece { face: face.into(), ..GPiece::dummy() }; - p.svg_piece(&mut html, &gpc, default())?; + p.svg_piece(&mut html, &gpc, &GameState::dummy(), default())?; println!("{}", html.0); } println!(""); diff --git a/src/clock.rs b/src/clock.rs index 0a1bb707..8d859e67 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -47,7 +47,7 @@ impl PieceTrait for Clock { fn nfaces(&self) -> RawFaceId { 1 } #[throws(IE)] - fn svg_piece(&self, f: &mut Html, _gpc: &GPiece, id: VisiblePieceId) { + fn svg_piece(&self, f: &mut Html, _gpc: &GPiece, _gs: &GameState, id: VisiblePieceId) { dbgc!("rendering", id); write!( &mut f.0, r##" diff --git a/src/gamestate.rs b/src/gamestate.rs index 073e68e1..7768107b 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -137,7 +137,7 @@ pub trait PieceTrait: OutlineTrait + Send + Debug + 'static { } // #[throws] doesn't work here - fehler #todo - fn svg_piece(&self, f: &mut Html, gpc: &GPiece, + fn svg_piece(&self, f: &mut Html, gpc: &GPiece, gs: &GameState, id: VisiblePieceId) -> Result<(),IE>; fn describe_html(&self, gpc: &GPiece) -> Result; diff --git a/src/hand.rs b/src/hand.rs index 484c9766..755a95d8 100644 --- a/src/hand.rs +++ b/src/hand.rs @@ -89,7 +89,7 @@ impl Hand { impl PieceTrait for Hand { fn nfaces(&self) -> RawFaceId { 1 } #[throws(IE)] - fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _vpid: VisiblePieceId) { + fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _gs: &GameState, _vpid: VisiblePieceId) { self.shape.svg_piece_raw(f, gpc.face, &mut |f: &mut String| { if_chain!{ if let Some(xdata) = gpc.xdata.get::()?; diff --git a/src/pcrender.rs b/src/pcrender.rs index 933f744a..86978638 100644 --- a/src/pcrender.rs +++ b/src/pcrender.rs @@ -79,7 +79,7 @@ impl PriOccultedGeneral { impl PieceRenderInstructions { #[throws(IE)] - pub fn map_piece_update_op(&self, ioccults: &IOccults, + pub fn map_piece_update_op(&self, ioccults: &IOccults, gs: &GameState, gpc: &GPiece, ipc: &IPiece, op: PieceUpdateOp<(),()> ) -> Option> @@ -99,7 +99,7 @@ impl PieceRenderInstructions { let op = op.try_map( |()|{ - let ns = self.prep_piecestate(ioccults, gpc, ipc)?; + let ns = self.prep_piecestate(ioccults, gs, gpc, ipc)?; >::Ok(ns) }, |()|{ @@ -110,7 +110,7 @@ impl PieceRenderInstructions { } #[throws(IE)] - pub fn prep_piecestate(&self, ioccults: &IOccults, + pub fn prep_piecestate(&self, ioccults: &IOccults, gs: &GameState, gpc: &GPiece, ipc: &IPiece) -> PreparedPieceState { let pri = self; @@ -118,7 +118,7 @@ impl PieceRenderInstructions { let r = PreparedPieceState { pos : pos, held : gpc.held, - svg : pri.make_defs(ioccults, gpc, ipc)?, + svg : pri.make_defs(ioccults, gs, gpc, ipc)?, z : zlevel.z.clone(), zg : zlevel.zg, angle : pri.angle(gpc).to_compass(), @@ -145,7 +145,7 @@ impl PieceRenderInstructions { } #[throws(IE)] - pub fn make_defs<'p>(&self, ioccults: &IOccults, + pub fn make_defs<'p>(&self, ioccults: &IOccults, gs: &GameState, gpc: &GPiece, ipc: &IPiece) -> Html { let pri = self; @@ -173,7 +173,7 @@ impl PieceRenderInstructions { match instead { Left(y) => { - ipc.show(y).svg_piece(&mut defs, gpc, pri.vpid)?; + ipc.show(y).svg_piece(&mut defs, gpc, gs, pri.vpid)?; }, Right(i) => { i.svg(&mut defs, pri.vpid)?; diff --git a/src/pieces.rs b/src/pieces.rs index 038fa56f..6ed3846c 100644 --- a/src/pieces.rs +++ b/src/pieces.rs @@ -129,7 +129,7 @@ impl OutlineTrait for GenericSimpleShape #[typetag::serde] impl PieceTrait for SimpleShape { #[throws(IE)] - fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _vpid: VisiblePieceId) { + fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _gs: &GameState, _vpid: VisiblePieceId) { self.svg_piece_raw(f, gpc.face, &mut |_|Ok(()))?; } #[throws(IE)] diff --git a/src/shapelib.rs b/src/shapelib.rs index c180b9b4..9e5d5dd5 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -216,7 +216,7 @@ impl PieceTrait for Item { } #[throws(IE)] - fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _vpid: VisiblePieceId) { + fn svg_piece(&self, f: &mut Html, gpc: &GPiece, _gs: &GameState, _vpid: VisiblePieceId) { let face = &self.faces[gpc.face]; let svgd = &self.svgs[face.svg]; face.xform.write_svgd(f, svgd)?; diff --git a/src/updates.rs b/src/updates.rs index d93ee0ca..25be6382 100644 --- a/src/updates.rs +++ b/src/updates.rs @@ -499,7 +499,8 @@ impl<'r> PrepareUpdatesBuffer<'r> { #[throws(InternalError)] fn piece_update_player(ioccults: &IOccults, - gpc: &mut GPiece, + gs: &GameState, + gpc: &GPiece, ipc: &IPiece, op: PieceUpdateOp<(),()>, pri: &Option) @@ -508,7 +509,7 @@ impl<'r> PrepareUpdatesBuffer<'r> { let pri = match pri { Some(pri) => pri, None => return None }; - let op = pri.map_piece_update_op(ioccults, gpc, ipc, op)?; + let op = pri.map_piece_update_op(ioccults, gs, gpc, ipc, op)?; op.map(|op| PreparedPieceUpdate { piece: pri.vpid, op, @@ -533,8 +534,17 @@ impl<'r> PrepareUpdatesBuffer<'r> { if let Some(ref mut gpc) = gpc { gen_update(gpc, gen, &self.by_client); } + let gpc = gs.pieces.byid(piece).ok(); + let mut out: SecondarySlotMap = default(); - for (player, gpl) in &mut gs.players { + for player in self.g.iplayers.keys() { + // Iterate via iplayers because we want to borrow each gpl + // mutably and also gs immutably, at different times. The naive + // approach fails because the iterator must borrow the whole + // thing, and mutably to produce mut references, so ties everything + // in a knot. + let gpl = match gs.players.get_mut(player) { Some(v)=>v, _=>continue }; + let ops = match ops { PUOs::Simple(update) => update, PUOs::PerPlayer(ref ops) => match ops.get(player) { @@ -542,13 +552,14 @@ impl<'r> PrepareUpdatesBuffer<'r> { None => continue, } }; - let op = match (&mut gpc, ipc) { + let op = match (gpc, ipc) { (Some(gpc), Some(ipc)) => { let pri = piece_pri(ioccults, &gs.occults, player, - gpl, piece, *gpc, ipc); + gpl, piece, gpc, ipc); gs.max_z.update_max(&gpc.zlevel.z); + drop(gpl); Self::piece_update_player( - ioccults, gpc, ipc, ops, &pri + ioccults, gs, gpc, ipc, ops, &pri )? } _ => gpl.idmap.fwd(piece).map(