Big internal API changes.
No functional change.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
cl.lastseen = Instant::now();
let player = cl.player;
let gs = &mut g.gs;
+ let ioccults = &g.ioccults;
let ipieces = &g.ipieces;
let iplayers = &g.iplayers;
let _ = iplayers.byid(player)?;
use ApiPieceOpError::*;
match (||{
- let p = ipieces.get(piece).ok_or(OnlineError::PieceGone)?;
+ let ipc = ipieces.get(piece).ok_or(OnlineError::PieceGone)?;
let gpc = gs.pieces.byid_mut(piece)?;
let q_gen = form.gen;
form.op.check_held(gpc,player)?;
let update =
form.op.op_complex(ApiPieceOpArgs {
- gs, player, piece, ipieces,
- p: p.as_ref(),
+ ioccults, gs, player, piece, ipieces, ipc,
})?;
Ok::<_,ApiPieceOpError>(update)
})() {
as:
#[throws(ApiPieceOpError)]
fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
- let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+ let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
let gpl = gs.players.byid_mut(player)?;
let gpc = gs.pieces.byid_mut(piece)?;
let logents = log_did_to_piece(
- &gs.occults, player, gpl, piece, gpc, p,
+ ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
"grasped"
)?;
impl op::Simple as {
#[throws(ApiPieceOpError)]
fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
- let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+ let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
let gpc = gs.pieces.byid_mut(piece)?;
let players = &mut gs.players;
let was = gpc.held;
let was = was.map(|was| htmlescape::encode_minimal(&was.nick));
let gpl = players.byid_mut(player)?;
- let pri = piece_pri(&gs.occults, player, gpl, piece, gpc, &p)
+ let pri = piece_pri(ioccults, &gs.occults, player, gpl, piece, gpc, ipc)
.ok_or(OE::PieceGone)?;
- let pcs = pri.describe(gpc, &p).0;
+ let pcs = pri.describe(ioccults, gpc, ipc).0;
gpc.held = Some(player);
as:
#[throws(ApiPieceOpError)]
fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
- let ApiPieceOpArgs { gs,player,piece,p,ipieces, .. } = a;
+ let ApiPieceOpArgs { gs,ioccults,player,piece,ipc,ipieces, .. } = a;
let gpl = gs.players.byid_mut(player).unwrap();
let gpc = gs.pieces.byid_mut(piece).unwrap();
let (logents, who_by) = log_did_to_piece_whoby(
- &gs.occults, player, gpl, piece, gpc, p,
+ ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
"released"
)?;
let who_by = who_by.ok_or(OE::PieceGone)?;
as:
#[throws(ApiPieceOpError)]
fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
- let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+ let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
let gpc = gs.pieces.byid_mut(piece).unwrap();
let gpl = gs.players.byid_mut(player).unwrap();
let logents = log_did_to_piece(
- &gs.occults, player, gpl, piece, gpc, p,
+ ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
"rotated"
)?;
gpc.angle = PieceAngle::Compass(self.0);
as:
#[throws(ApiPieceOpError)]
fn op(&self, a: ApiPieceOpArgs) -> PieceUpdate {
- let ApiPieceOpArgs { gs,player,piece,p, .. } = a;
+ let ApiPieceOpArgs { gs,ioccults,player,piece,ipc, .. } = a;
let gpc = gs.pieces.byid_mut(piece).unwrap();
let gpl = gs.players.byid_mut(player).unwrap();
let logents = log_did_to_piece(
- &gs.occults, player, gpl, piece, gpc, p,
+ ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
if gpc.pinned { "pinned" } else { "unpinned" },
)?;
forbid_piece_involved_in_occultation(&gpc)?;
impl op::Complex as {
#[throws(ApiPieceOpError)]
fn op_complex(&self, mut a: ApiPieceOpArgs) -> UpdateFromOpComplex {
- let ApiPieceOpArgs { player,piece,p, .. } = a;
+ let ApiPieceOpArgs { ioccults,player,piece,ipc, .. } = a;
let gs = &mut a.gs;
'_normal_global_ops__not_loop: loop {
let gpc = gs.pieces.byid_mut(piece)?;
let _: Void = match (self.opname.as_str(), self.wrc) {
("flip", wrc@ WRC::UpdateSvg) => {
- let nfaces = p.nfaces();
+ let nfaces = ipc.p.nfaces();
let logents = log_did_to_piece(
- &gs.occults, player, gpl, piece, gpc, p,
+ ioccults, &gs.occults, player, gpl, piece, gpc, ipc,
"flipped"
)?;
gpc.face = ((RawFaceId::from(gpc.face) + 1) % nfaces).into();
};
}
- p.ui_operation(a, &self.opname, self.wrc)?
+ ipc.p.ui_operation(a, &self.opname, self.wrc)?
}
}
}
},
MGI::ListPieces => readonly(cs,ag,ig, &[TP::ViewNotSecret], |ig|{
+ let ioccults = &ig.ioccults;
let pieces = ig.gs.pieces.iter().filter_map(
|(piece,gpc)| (|| Ok::<_,MgmtError>(if_chain!{
let &GPiece { pos, face, .. } = gpc;
- if let Some(p) = ig.ipieces.get(piece);
+ if let Some(ipc) = ig.ipieces.get(piece);
let visible = if ! piece_at_all_occulted(gpc) {
// todo: something more sophisticated would be nice
let pri = PieceRenderInstructions::new_visible(
// visible id is internal one here
VisiblePieceId(piece.data())
);
- let bbox = p.bbox_approx()?;
- let desc_html = pri.describe(gpc, p);
+ let bbox = ipc.p.bbox_approx()?;
+ let desc_html = pri.describe(ioccults, gpc, ipc);
Some(MgmtGamePieceVisibleInfo {
pos, face, desc_html, bbox
})
} else {
None
};
- let itemname = p.itemname().to_string();
+ let itemname = ipc.p.itemname().to_string();
then {
Some(MgmtGamePieceInfo {
piece, itemname,
},
MGI::DeletePiece(piece) => {
- let (ig, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
- let IPiece { p, occilk } = ig.ipieces.as_mut(modperm)
+ let (ig_g, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
+ let ig = &mut **ig_g;
+ let ipc = ig.ipieces.as_mut(modperm)
.remove(piece).ok_or(ME::PieceNotFound)?;
+ let ioccults = &ig.ioccults;
let gs = &mut ig.gs;
let gpc = gs.pieces.as_mut(modperm).remove(piece);
let desc_html = if let Some(gpc) = &gpc {
let pri = PieceRenderInstructions::new_visible(default());
- pri.describe(gpc, &p)
+ pri.describe(ioccults, gpc, &ipc)
} else {
Html::lit("<piece partially missing from game state!>")
};
- if let Some(gpc) = gpc { p.delete_hook(&gpc, gs); }
- if let Some(occilk) = occilk { ig.ioccults.ilks.dispose(occilk); }
+ if let Some(gpc) = gpc { ipc.p.delete_hook(&gpc, gs); }
+ if let Some(occilk) = ipc.occilk { ig.ioccults.ilks.dispose(occilk); }
(U{ pcs: vec![(piece, PieceUpdateOp::Delete())],
log: vec![ LogEntry {
html: Html(format!("A piece {} was removed from the game",
desc_html.0)),
}],
raw: None },
- Fine, ig)
+ Fine, ig_g)
},
MGI::AddPieces(PiecesSpec{ pos,posd,count,face,pinned,angle,info }) => {
let ctoken = record_token(&mut ig, ciad)?;
ig.save_game_later(); // in case we changed anything eg gpl.layout
let ig = &mut *ig;
+ let ioccults = &ig.ioccults;
let mut uses = vec![];
let mut alldefs = vec![];
pieces.sort_by_key(|(_,pr)| &pr.zlevel);
for (piece, gpc) in pieces {
- let p = if let Some(pto) = ig.ipieces.get(piece) { pto }
+ let ipc = if let Some(pto) = ig.ipieces.get(piece) { pto }
else { continue /* was deleted */ };
- let pri = piece_pri(&ig.gs.occults, player, gpl, piece, gpc, p);
+ let pri = piece_pri(ioccults, &ig.gs.occults, player, gpl,
+ piece, gpc, ipc);
let pri = if let Some(pri) = pri { pri } else { continue /*invisible*/};
- let defs = pri.make_defs(gpc, p)?;
+ let defs = pri.make_defs(ioccults, gpc, ipc)?;
alldefs.push((pri.vpid, defs));
- let desc = pri.describe(&gpc, p);
+ let desc = pri.describe(ioccults, &gpc, ipc);
let vangle = pri.angle(gpc).to_compass();
pinned: gpc.pinned,
angle: vangle,
desc,
- uos: &pri.ui_operations(gpc, p.as_ref())?,
+ uos: &pri.ui_operations(gpc, ipc.p.as_ref())?,
};
let for_piece = SessionPieceContext {
pub struct ApiPieceOpArgs<'a> {
pub gs: &'a mut GameState,
pub ipieces: &'a IPieces,
+ pub ioccults: &'a IOccults,
pub player: PlayerId,
pub piece: PieceId,
- pub p: &'a dyn PieceTrait,
+ pub ipc: &'a IPiece,
}
#[derive(Debug)]
impl GPiece {
#[throws(IE)]
- pub fn prep_piecestate(&self, p: &dyn PieceTrait, pri: &PieceRenderInstructions)
+ pub fn prep_piecestate(&self, ioccults: &IOccults,
+ ipc: &IPiece, pri: &PieceRenderInstructions)
-> PreparedPieceState {
PreparedPieceState {
pos : self.pos,
held : self.held,
- svg : pri.make_defs(self, &p)?,
+ svg : pri.make_defs(ioccults, self, ipc)?,
z : self.zlevel.z.clone(),
zg : self.zlevel.zg,
angle : pri.angle(self).to_compass(),
pinned : self.pinned,
- uos : pri.ui_operations(self, p)?,
+ uos : pri.ui_operations(self, ipc.p.borrow())?,
}
}
}
#[throws(IE)]
- fn instead<'p>(&self, p: &'p dyn PieceTrait)
+ fn instead<'p>(&self, _ioccults: &'p IOccults, p: &'p IPiece)
-> Option<&'p dyn OccultedPieceTrait>
{
match self.occulted {
PriOcculted::Visible => None,
PriOcculted::Occulted | PriOcculted::Displaced(_) => {
Some(
- p.occultable()
+ p.p.occultable()
.ok_or_else(|| internal_logic_error(format!(
"occulted non-occultable {:?}", p)))?
)
#[throws(IE)]
- pub fn make_defs<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
- where P:Borrow<dyn PieceTrait>
+ pub fn make_defs<'p>(&self, ioccults: &IOccults,
+ gpc: &GPiece, ipc: &IPiece) -> Html
{
#[throws(IE)]
- fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
+ fn inner(pri: &PieceRenderInstructions, ioccults: &IOccults,
+ gpc: &GPiece, ipc: &IPiece)
-> Html
{
- let instead = pri.instead(p)?;
+ let instead = pri.instead(ioccults, ipc)?;
let o: &dyn OutlineTrait = match instead {
- None => p.dyn_upcast(),
+ None => Borrow::<dyn PieceTrait>::borrow(&ipc.p).dyn_upcast(),
Some(i) => i.dyn_upcast(),
};
match instead {
None => {
- p.svg_piece(&mut defs, gpc, pri.vpid)?;
+ ipc.p.svg_piece(&mut defs, gpc, pri.vpid)?;
},
Some(i) => {
i.svg(&mut defs, pri.vpid)?;
pri.vpid, o.surround_path()?.0)?;
defs
}
- inner(self, gpc, p.borrow())?
+ inner(self, ioccults, gpc, ipc)?
}
- pub fn describe<'p,P>(&self, gpc: &GPiece, p: &P) -> Html
- where P:Borrow<dyn PieceTrait>
+ pub fn describe(&self, ioccults: &IOccults,
+ gpc: &GPiece, ipc: &IPiece) -> Html
{
- fn inner(pri: &PieceRenderInstructions, gpc: &GPiece, p: &dyn PieceTrait)
- -> Html
+ fn inner(pri: &PieceRenderInstructions, ioccults: &IOccults,
+ gpc: &GPiece, ipc: &IPiece) -> Html
{
- pri.describe_fallible(gpc, p)
+ pri.describe_fallible(ioccults, gpc, ipc)
.unwrap_or_else(|e| {
error!("error describing piece: {:?}", e);
Html::lit("<internal error describing piece>")
})
}
- inner(self, gpc, p.borrow())
+ inner(self, ioccults, gpc, ipc)
}
#[throws(IE)]
- pub fn describe_fallible(&self, gpc: &GPiece, p: &dyn PieceTrait) -> Html {
- match self.instead(p)? {
- None => p.describe_html(gpc)?,
+ pub fn describe_fallible(&self, ioccults: &IOccults,
+ gpc: &GPiece, ipc: &IPiece) -> Html {
+ match self.instead(ioccults, ipc)? {
+ None => ipc.p.describe_html(gpc)?,
Some(i) => i.describe_html()?,
}
}
// ========== instance pieces data access ==========
impl IPieces {
- pub fn get(&self, piece: PieceId) -> Option<&Box<dyn PieceTrait>> {
- Some(&self.0.get(piece)?.p)
- }
-
- pub fn get_ipc(&self, piece: PieceId) -> Option<&IPiece> {
+ pub fn get(&self, piece: PieceId) -> Option<&IPiece> {
self.0.get(piece)
}
// ========== public entrypoints ==========
/// None => do not render at all
-pub fn piece_pri<P:Borrow<dyn PieceTrait>>(
+pub fn piece_pri(
+ ioccults: &IOccults,
occults: &GameOccults,
player: PlayerId, gpl: &mut GPlayer,
- piece: PieceId, gpc: &GPiece, p: &P,
+ piece: PieceId, gpc: &GPiece, ipc: &IPiece,
) -> Option<PieceRenderInstructions>
{
fn inner(
+ _ioccults: &IOccults,
occults: &GameOccults,
player: PlayerId, gpl: &mut GPlayer,
- piece: PieceId, gpc: &GPiece, _p: &dyn PieceTrait,
+ piece: PieceId, gpc: &GPiece, _ipc: &IPiece,
) -> Option<PieceRenderInstructions>
{
let occk = if_chain! {
trace_dbg!("piece_pri", gpc, occk, vpid, occulted);
Some(PieceRenderInstructions { vpid, occulted })
}
- inner(occults, player, gpl, piece, gpc, p.borrow())
+ inner(ioccults, occults, player, gpl, piece, gpc, ipc)
}
pub fn piece_at_all_occulted(gpc: &GPiece) -> bool {
// prevent occulting pieces being occulted
// (also prevents reflexive occultation)
return None
- } else if ipc.occultable().is_none() {
+ } else if ipc.p.occultable().is_none() {
// if we cannot make it look identical to the others, we
// cannot occult it beause we can't hide its identity
return None
let bad = || internal_error_bydebug(&("missing", opiece, h.occid));
let oipc = ipieces.get(opiece).ok_or_else(bad)?;
let ogpc = gpieces.get(opiece).ok_or_else(bad)?;
- Ok::<_,IE>(oipc.describe_html(ogpc)?)
+ Ok::<_,IE>(oipc.p.describe_html(ogpc)?)
};
let most_obscure = most_obscure.unwrap_or(&OccK::Visible); // no players!
log_visible
}
OccK::Scrambled | OccK::Displaced{..} => {
- let _face = ipc.nfaces() - 1; // xxx use other thing entirely
- let show = ipc.describe_html(gpc)?;
+ let _face = ipc.p.nfaces() - 1; // xxx use other thing entirely
+ let show = ipc.p.describe_html(gpc)?;
call_log_callback(Some(&show))?
},
OccK::Invisible => {
#[throws(OE)]
pub fn log_did_to_piece_whoby(
+ ioccults: &IOccults,
occults: &GameOccults,
player: PlayerId,
gpl: &mut GPlayer,
- piece: PieceId, gpc: &GPiece, p: &dyn PieceTrait,
+ piece: PieceId, gpc: &GPiece, ipc: &IPiece,
did: &str,
) -> (Vec<LogEntry>, Option<Html>) {
let who_by = Html(htmlescape::encode_minimal(&gpl.nick));
- let pri = piece_pri(occults, player, gpl, piece, gpc, &p)
+ let pri = piece_pri(ioccults, occults, player, gpl, piece, gpc, ipc)
.ok_or(OE::PieceGone)?;
let log = vec![ LogEntry { html: Html(format!(
"{} {} {}",
&who_by.0,
did,
- pri.describe(gpc, &p).0,
+ pri.describe(ioccults, gpc, ipc).0,
))}];
(log, Some(who_by))
}
#[throws(OE)]
pub fn log_did_to_piece(
+ ioccults: &IOccults,
occults: &GameOccults,
player: PlayerId,
gpl: &mut GPlayer,
- piece: PieceId, gpc: &GPiece, p: &dyn PieceTrait,
+ piece: PieceId, gpc: &GPiece, ipc: &IPiece,
did: &str,
) -> Vec<LogEntry> {
- log_did_to_piece_whoby(occults,player,gpl,piece,gpc,p,did)?.0
+ log_did_to_piece_whoby(ioccults,occults,player,gpl,piece,gpc,ipc,did)?.0
}
// ---------- prepared updates, queued in memory ----------
}
#[throws(InternalError)]
- fn piece_update_player(max_z: &mut ZCoord,
+ fn piece_update_player(ioccults: &IOccults,
+ max_z: &mut ZCoord,
pc: &mut GPiece,
- p: &Box<dyn PieceTrait>,
+ ipc: &IPiece,
op: PieceUpdateOp<(),()>,
pri: &Option<PieceRenderInstructions>)
-> Option<PreparedPieceUpdate>
let op = op.try_map(
|()|{
- let mut ns = pc.prep_piecestate(p.as_ref(), pri)?;
+ let mut ns = pc.prep_piecestate(ioccults, ipc, pri)?;
massage_prep_piecestate(pri, &mut ns);
<Result<_,InternalError>>::Ok(ns)
},
{
let gen = self.gen();
let gs = &mut self.g.gs;
+ let ioccults = &self.g.ioccults;
let mut gpc = gs.pieces.byid_mut(piece).ok();
- let p = self.g.ipieces.get(piece);
+ let ipc = self.g.ipieces.get(piece);
if let Some(ref mut gpc) = gpc {
gen_update(gpc, gen, &self.by_client);
None => continue,
}
};
- let op = match (&mut gpc, p) {
- (Some(gpc), Some(p)) => {
- let pri = piece_pri(&gs.occults, player, gpl, piece, *gpc, p);
+ let op = match (&mut gpc, ipc) {
+ (Some(gpc), Some(ipc)) => {
+ let pri = piece_pri(ioccults, &gs.occults, player,
+ gpl, piece, *gpc, ipc);
Self::piece_update_player(
- &mut gs.max_z, gpc, p, ops, &pri
+ ioccults, &mut gs.max_z, gpc, ipc, ops, &pri
)?
}
_ => gpl.idmap.fwd(piece).map(