},
MGI::DeletePiece(piece) => {
- let (ig_g, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
- let ig = &mut **ig_g;
+ let (ig, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
let _ipc = ig.ipieces.as_mut(modperm)
.get(piece).ok_or(ME::PieceNotFound)?;
- let gs = &mut ig.gs;
- let gpc = gs.pieces.as_mut(modperm).get_mut(piece);
- let mut xupdates = vec![];
- if let Some(gpc) = gpc {
- gpc.occult.passive_delete_hook(&mut gs.occults, piece);
- if gpc.occult.is_active() {
- xupdates.append(
- &mut
- remove_occultation(
- &mut gs.gen.unique_gen(),
- &mut gs.players,
- &mut gs.pieces,
- &mut gs.occults,
- &ig.ipieces,
- &ig.ioccults,
- to_permute,
- piece)?
- );
- }
- }
- let ioccults = &ig.ioccults;
- let gpc = gs.pieces.as_mut(modperm).remove(piece);
- let ipc = ig.ipieces.as_mut(modperm).remove(piece).unwrap();
- let desc_html = if let Some(gpc) = &gpc {
- let pri = PieceRenderInstructions::new_visible(default());
- pri.describe(ioccults,&gs.occults, gpc, &ipc)
- } else {
- "<piece partially missing from game state>".to_html()
- };
- if let Some(gpc) = gpc {
- ipc.p.into_inner().delete_hook(&gpc, gs);
- }
- if let Some(occilk) = ipc.occilk {
- ig.ioccults.ilks.dispose_iilk(occilk);
- }
+
+ let (desc_html, xupdates) =
+ ig.delete_piece(modperm, to_permute, piece,
+ |ioccults, goccults, ipc, gpc| {
+ if let (Some(ipc), Some(gpc)) = (ipc, gpc) {
+ let pri = PieceRenderInstructions::new_visible(default());
+ pri.describe(ioccults,goccults, gpc, &ipc)
+ } else {
+ "<piece partially missing from game state>".to_html()
+ }
+ })?;
+
(U{ pcs: vec![(piece, PieceUpdateOp::Delete())],
log: vec![ LogEntry {
html: hformat!("A piece {} was removed from the game",
}],
raw: None },
Fine,
- xupdates.into_unprepared(None),
+ xupdates,
vec![],
- ig_g)
+ ig)
},
MGI::AddPieces(PiecesSpec{ pos,posd,count,face,pinned,angle,info }) => {
}
impl<'ig> InstanceGuard<'ig> {
+ /// Idempotent.
+ #[throws(IE)]
+ pub fn delete_piece<H,T>(&mut self, modperm: ModifyingPieces,
+ to_permute: &mut ToRecalculate,
+ piece: PieceId, hook: H)
+ -> (T, UnpreparedUpdates)
+ where H: FnOnce(&IOccults, &GOccults,
+ Option<&IPiece>, Option<&GPiece>) -> T
+ {
+ let ig = &mut **self;
+ let gs = &mut ig.gs;
+ let gpc = gs.pieces.as_mut(modperm).get_mut(piece);
+ let mut xupdates = vec![];
+ if let Some(gpc) = gpc {
+ gpc.occult.passive_delete_hook(&mut gs.occults, piece);
+ if gpc.occult.is_active() {
+ xupdates.append(
+ &mut
+ remove_occultation(
+ &mut gs.gen.unique_gen(),
+ &mut gs.players,
+ &mut gs.pieces,
+ &mut gs.occults,
+ &ig.ipieces,
+ &ig.ioccults,
+ to_permute,
+ piece)?
+ );
+ }
+ }
+ let ioccults = &ig.ioccults;
+ let gpc = gs.pieces.as_mut(modperm).remove(piece);
+ let ipc = ig.ipieces.as_mut(modperm).remove(piece);
+
+ let hook_r = hook(ioccults, &gs.occults,
+ ipc.as_ref(), gpc.as_ref());
+
+ if let Some(ipc) = ipc {
+ if let Some(gpc) = gpc {
+ ipc.p.into_inner().delete_hook(&gpc, gs);
+ }
+ if let Some(occilk) = ipc.occilk {
+ ig.ioccults.ilks.dispose_iilk(occilk);
+ }
+ }
+
+ (hook_r, xupdates.into_unprepared(None))
+ }
+
/// caller is responsible for logging; threading it through
/// proves the caller has a log entry.
#[throws(MgmtError)]