From: Ian Jackson Date: Sun, 1 May 2022 11:19:35 +0000 (+0100) Subject: delete_piece: Break out into global.rs X-Git-Tag: otter-1.1.0~371 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=ecb90280e81600a5376daeafbeeb9533a88e9237;p=otter.git 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 --- 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)]