This is quite a lot of plumbing.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
}
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);
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);
defs: alldefs,
uses,
scale: SVG_SCALE,
- nick: gpl.nick.clone(),
+ nick,
sse_url_prefix,
player_info_pane,
ptoken: form.ptoken.clone(),
}
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!("{}</svg>", html.0);
}
println!("</td>");
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##"
<rect fill="black" width="10" height="10"/>
}
// #[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<Html,IE>;
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::<HandState>()?;
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<PieceUpdateOp<PreparedPieceState, ZLevel>>
let op = op.try_map(
|()|{
- let ns = self.prep_piecestate(ioccults, gpc, ipc)?;
+ let ns = self.prep_piecestate(ioccults, gs, gpc, ipc)?;
<Result<_,InternalError>>::Ok(ns)
},
|()|{
}
#[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;
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(),
}
#[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;
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)?;
#[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)]
}
#[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)?;
#[throws(InternalError)]
fn piece_update_player(ioccults: &IOccults,
- gpc: &mut GPiece,
+ gs: &GameState,
+ gpc: &GPiece,
ipc: &IPiece,
op: PieceUpdateOp<(),()>,
pri: &Option<PieceRenderInstructions>)
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,
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<PlayerId, PreparedPieceUpdate> = 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) {
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(