From ecb90280e81600a5376daeafbeeb9533a88e9237 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 1 May 2022 12:19:35 +0100 Subject: [PATCH] delete_piece: Break out into global.rs fastsplit deletion is going to want this. This may not be in its final form, particularly because of ToRecalculate, which fastsplit doesn't have one of yet. Signed-off-by: Ian Jackson --- daemon/cmdlistener.rs | 54 ++++++++++++------------------------------- src/global.rs | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 39 deletions(-) diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 6745b260..a3c1a550 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -1012,45 +1012,21 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>( }, 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 { - "".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 { + "".to_html() + } + })?; + (U{ pcs: vec![(piece, PieceUpdateOp::Delete())], log: vec![ LogEntry { html: hformat!("A piece {} was removed from the game", @@ -1058,9 +1034,9 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>( }], raw: None }, Fine, - xupdates.into_unprepared(None), + xupdates, vec![], - ig_g) + ig) }, MGI::AddPieces(PiecesSpec{ pos,posd,count,face,pinned,angle,info }) => { diff --git a/src/global.rs b/src/global.rs index 11da90ed..02ec3169 100644 --- a/src/global.rs +++ b/src/global.rs @@ -641,6 +641,55 @@ impl InstanceAccessDetails } impl<'ig> InstanceGuard<'ig> { + /// Idempotent. + #[throws(IE)] + pub fn delete_piece(&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)] -- 2.30.2