|(piece,p)| (|| Ok::<_,MgmtError>(if_chain!{
let &GPiece { pos, face, .. } = p;
if let Some(pinfo) = ig.ipieces.get(piece);
- let desc_html = pinfo.describe_html_infallible(None, p);
- let itemname = pinfo.itemname().to_string();
- let bbox = pinfo.bbox_approx()?;
let visible = if ! piece_at_all_occluded(&ig.gs.occults, piece) {
+ // todo: something more sophisticated would be nice
+ let pri = PieceRenderInstructions {
+ id: VisiblePieceId(piece.data()),
+ angle: VisiblePieceAngle(p.angle), // xxx
+ face: default(),
+ occluded: PriOccluded::Visible,
+ };
+ let bbox = pinfo.bbox_approx()?;
+ let desc_html = pri.describe(p, pinfo);
Some(MgmtGamePieceVisibleInfo {
pos, face, desc_html, bbox
})
} else {
None
};
+ let itemname = pinfo.itemname().to_string();
then {
Some(MgmtGamePieceInfo {
piece, itemname,
let gs = &mut ig.gs;
let pc = gs.pieces.as_mut(modperm).remove(piece);
let desc_html = if let Some(pc) = &pc {
- p.describe_html_infallible(Some(default()), pc)
+ let pri = PieceRenderInstructions {
+ id: default(),
+ face: default(),
+ angle: VisiblePieceAngle(pc.angle), // xxx
+ occluded: PriOccluded::Visible,
+ };
+ pri.describe(pc, &p)
} else {
Html::lit("<piece partially missing from game state!>")
};
let pri = piece_pri(&ig.gs.occults, player, gpl, gpid, pr);
let p = if let Some(p) = ig.ipieces.get(gpid) { p }
else { continue /* was deleted */ };
- let defs = p.make_defs(pr, &pri)?;
+ let defs = pri.make_defs(pr, p)?;
alldefs.push((pri.id, defs));
- let desc = p.describe_pri(&pr, &pri);
+ let desc = pri.describe(&pr, p);
let vangle = match pri.angle {
VisiblePieceAngle(PieceAngle::Compass(vangle)) => vangle,
pinned: pr.pinned,
angle: vangle,
desc,
- uos: &p.ui_operations(pr)?,
+ uos: &pri.ui_operations(pr, p.as_ref())?,
};
let for_piece = SessionPieceContext {
pub p: &'a dyn PieceTrait,
}
-#[derive(Debug,Clone)]
-pub struct PieceRenderInstructions {
- pub id: VisiblePieceId,
- pub angle: VisiblePieceAngle,
- pub face: FaceId,
-}
-
#[typetag::serde(tag="type")]
pub trait PieceSpec: Debug {
fn count(&self) -> usize { 1 }
PreparedPieceState {
pos : self.pos,
held : self.held,
- svg : p.make_defs(self, pri)?,
+ svg : pri.make_defs(self, &p)?,
z : self.zlevel.z.clone(),
zg : self.zlevel.zg,
pinned : self.pinned,
- uos : p.ui_operations(self)?,
+ uos : pri.ui_operations(self, p)?,
}
}
}
}
-pub trait PieceExt {
- fn make_defs(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
- -> Result<Html, IE>;
- fn describe_html_infallible(&self, face: Option<FaceId>, gpc: &GPiece)
- -> Html;
- fn describe_pri(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
- -> Html;
- fn ui_operations(&self, gpc: &GPiece) -> Result<Vec<UoDescription>, IE>;
+#[derive(Debug,Clone)]
+pub struct PieceRenderInstructions {
+ pub id: VisiblePieceId,
+ pub angle: VisiblePieceAngle,
+ pub face: FaceId,
+ pub occluded: PriOccluded,
}
-impl<T> PieceExt for T where T: PieceTrait + ?Sized {
+#[derive(Debug,Clone,Copy)]
+pub enum PriOccluded { Visible /*, Occluded*/ }
+
+impl PieceRenderInstructions {
#[throws(IE)]
- fn make_defs(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
- -> Html {
+ pub fn make_defs<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
+ where P:Borrow<dyn PieceTrait + 'p>
+ {
+ #[throws(IE)]
+ fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
+ -> Html
+ {
+ let PriOccluded::Visible = pri.occluded;
+
let mut defs = Html(String::new());
- let dragraise = match self.thresh_dragraise(pri)? {
+ let dragraise = match p.thresh_dragraise(pri)? {
Some(n) if n < 0 => throw!(SvgE::NegativeDragraise),
Some(n) => n,
None => -1,
write!(&mut defs.0,
r##"<g id="piece{}" transform="{}" data-dragraise="{}">"##,
pri.id, &transform.0, dragraise)?;
- self.svg_piece(&mut defs, gpc, &pri)?;
+ p.svg_piece(&mut defs, gpc, pri)?;
write!(&mut defs.0, r##"</g>"##)?;
write!(&mut defs.0,
r##"<path id="surround{}" d="{}"/>"##,
- pri.id, self.surround_path(&pri)?.0)?;
+ pri.id, p.surround_path(pri)?.0)?;
defs
}
+ inner(self, gpc, p.borrow())?
+ }
+
+ pub fn describe<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
+ where P:Borrow<dyn PieceTrait + 'p>
+ {
+ fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
+ -> Html
+ {
+ let PriOccluded::Visible = pri.occluded;
- fn describe_html_infallible(&self, face: Option<FaceId>, gpc: &GPiece)
- -> Html {
- self.describe_html(face, gpc)
+ pri.describe_fallible(gpc, p)
.unwrap_or_else(|e| {
error!("error describing piece: {:?}", e);
Html::lit("<internal error describing piece>")
})
}
+ inner(self, gpc, p.borrow())
+ }
- fn describe_pri(&self, gpc: &GPiece, pri: &PieceRenderInstructions)
- -> Html {
- self.describe_html_infallible(Some(pri.face), gpc)
+ #[throws(IE)]
+ pub fn describe_fallible(&self, gpc: &GPiece, p: &dyn PieceTrait) -> Html {
+ p.describe_html(Some(gpc.face), gpc)?
}
#[throws(InternalError)]
- fn ui_operations(&self, gpc: &GPiece) -> Vec<UoDescription> {
+ pub fn ui_operations(&self, gpc: &GPiece, p: &dyn PieceTrait)
+ -> Vec<UoDescription>
+ {
+ let PriOccluded::Visible = self.occluded;
type WRC = WhatResponseToClientOp;
let mut out = vec![];
- if self.nfaces() > 1 {
+ if p.nfaces() > 1 {
out.push(UoDescription {
wrc: WRC::UpdateSvg,
kind: UoKind::Global,
desc: Html::lit("flip"),
})
}
- self.add_ui_operations(&mut out, gpc)?;
+ p.add_ui_operations(&mut out, gpc)?;
out
}
}