From 283a46cdfb3edf6b1d4525e848452d4bfcd608d9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 2 Apr 2021 20:03:05 +0100 Subject: [PATCH] movehist: Move into its own module Signed-off-by: Ian Jackson --- src/gamestate.rs | 23 ++----------- src/movehist.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ src/prelude.rs | 1 + src/updates.rs | 48 ++------------------------ 4 files changed, 93 insertions(+), 66 deletions(-) create mode 100644 src/movehist.rs diff --git a/src/gamestate.rs b/src/gamestate.rs index eef43382..5a0aabec 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -55,8 +55,8 @@ pub struct GPlayer { // usual variable: gpl pub nick: String, pub layout: PresentationLayout, pub idmap: PerPlayerIdMap, - #[serde(default)] pub moveheld: SparseSecondaryMap, - #[serde(default)] pub movehist: VecDeque, + #[serde(default)] pub moveheld: GMoveHeld, + #[serde(default)] pub movehist: GMoveHist, } #[derive(Debug,Serialize,Deserialize)] @@ -75,25 +75,6 @@ pub struct GPiece { // usual variable: gpc pub moveable: PieceMoveable, } -#[derive(Debug,Copy,Clone,Serialize,Deserialize)] -pub struct MoveHistPosx { // usual variable: posx - pub pos: Pos, - pub angle: CompassAngle, - pub facehint: Option, -} - -#[derive(Debug,Copy,Clone,Serialize,Deserialize)] -pub struct GMoveHistLast { - pub held: PlayerId, - pub posx: MoveHistPosx, -} - -#[derive(Debug,Clone,Serialize,Deserialize)] -pub struct MoveHistEnt { - pub held: PlayerId, - pub posx: OldNew, -} - pub type PieceXDataState = Option>; #[derive(Debug,Serialize,Deserialize)] diff --git a/src/movehist.rs b/src/movehist.rs new file mode 100644 index 00000000..85baca41 --- /dev/null +++ b/src/movehist.rs @@ -0,0 +1,87 @@ +// Copyright 2020-2021 Ian Jackson and contributors to Otter +// SPDX-License-Identifier: AGPL-3.0-or-later +// There is NO WARRANTY. + +use super::*; // we are otter::updates::movehist + +#[derive(Debug,Copy,Clone,Serialize,Deserialize)] +pub struct MoveHistPosx { // usual variable: posx + pub pos: Pos, + pub angle: CompassAngle, + pub facehint: Option, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct MoveHistEnt { + pub held: PlayerId, + pub posx: OldNew, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct GMoveHist { + pub hist: VecDeque, +} + +// ---------- non-public structs ---------- + +#[derive(Debug,Clone,Serialize,Deserialize,Default)] +pub struct GMoveHeld { + held: SparseSecondaryMap, +} + +#[derive(Debug,Copy,Clone,Serialize,Deserialize)] +struct GMoveHistLast { + held: PlayerId, + posx: MoveHistPosx, +} + +impl Default for GMoveHist { + fn default() -> GMoveHist { GMoveHist { + hist: VecDeque::with_capacity(MOVEHIST_LEN_MAX), + } } +} + +// We're track this on behalf of the client, based on the updates +// we are sending. That means we don't ahve to worry about +// occultation, etc. etc. +pub fn peek_prep_update(gs: &mut GameState, peek: &PreparedUpdateEntry) + -> Option { + if_let!{ PUE::Piece(PUE_P { ops,.. }) = peek; else return None; } + + let mut pu = SecondarySlotMap::new(); + for (player, &PreparedPieceUpdate { ref op, piece,.. }) in ops { if_chain! { + if let Some(ns) = op.new_state(); + if let Some(gpl) = wants!( gs.players.get_mut(player), ?player); + if let Some(mut ent) = wants!( gpl.moveheld.held.entry(piece), ?piece); + let &PreparedPieceState { pos, angle, facehint, .. } = ns; + let new_posx = MoveHistPosx { pos, angle, facehint }; + + then { + if let slotmap::sparse_secondary::Entry::Occupied(ref mut oe) = ent { + let last = oe.get(); + if ns.held == Some(last.held) { continue } + + // Generate an update + let histent = MoveHistEnt { + held: last.held, + posx: OldNew::from([last.posx, new_posx]), + }; + if gpl.movehist.hist.len() == MOVEHIST_LEN_MAX { + gpl.movehist.hist.pop_front(); + } + gpl.movehist.hist.push_back(histent.clone()); + pu.insert(player, histent); + } + + if let Some(held) = ns.held { + ent.insert(GMoveHistLast { held: held, posx: new_posx }); + } else { + ent.remove(); + } + } + } } + + if pu.is_empty() { return None } + + Some(PUE::MoveHistEnt(pu)) +} diff --git a/src/prelude.rs b/src/prelude.rs index caeeaf04..aa10014f 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -145,6 +145,7 @@ pub use crate::sse; pub use crate::toml_de; pub use crate::tz::*; pub use crate::updates::*; +pub use crate::updates::movehist::{self, GMoveHeld, GMoveHist, MoveHistEnt}; pub use crate::utils::*; pub use crate::ui::*; diff --git a/src/updates.rs b/src/updates.rs index 289ff5a2..e939268b 100644 --- a/src/updates.rs +++ b/src/updates.rs @@ -6,6 +6,8 @@ use crate::prelude::*; +#[path="movehist.rs"] pub mod movehist; + #[allow(non_camel_case_types)] type TUE_P<'u> = TransmitUpdateEntry_Piece<'u>; #[allow(non_camel_case_types)] type PUE_I = PreparedUpdateEntry_Image; #[allow(non_camel_case_types)] type TUE_I<'u> = TransmitUpdateEntry_Image<'u>; @@ -757,52 +759,8 @@ impl<'r> PrepareUpdatesBuffer<'r> { PreparedUpdateEntry::Error(ErrorSignaledViaUpdate::InternalError) }); - // We're track this on behalf of the client, based on the updates - // we are sending. That means we don't ahve to worry about - // occultation, etc. etc. - let movehist_update = if let PUE::Piece(PUE_P { ops,.. }) = &update { - let mut pu = SecondarySlotMap::new(); - for (player, PreparedPieceUpdate { op,.. }) in ops { if_chain! { - if let Some(ns) = op.new_state(); - if let Some(gpl) = wants!( self.g.gs.players.get_mut(player), ?player); - if let Some(mut ent) = wants!( gpl.moveheld.entry(piece), ?piece); - let &PreparedPieceState { pos, angle, facehint, .. } = ns; - let new_posx = MoveHistPosx { pos, angle, facehint }; - - then { - if let slotmap::sparse_secondary::Entry::Occupied(ref mut oe) = ent { - let last = oe.get(); - if ns.held == Some(last.held) { continue } - - // Generate an update - let histent = MoveHistEnt { - held: last.held, - posx: OldNew::from([last.posx, new_posx]), - }; - gpl.movehist.reserve(MOVEHIST_LEN_MAX); - if gpl.movehist.len() == MOVEHIST_LEN_MAX { - gpl.movehist.pop_front(); - } - gpl.movehist.push_back(histent.clone()); - pu.insert(player, histent); - } - - if let Some(held) = ns.held { - ent.insert(GMoveHistLast { held: held, posx: new_posx }); - } else { - ent.remove(); - } - } - } } + let movehist_update = movehist::peek_prep_update(&mut self.g.gs, &update); - if pu.is_empty() { - None - } else { - Some(PUE::MoveHistEnt(pu)) - } - } else { - None - }; self.us.push(update); self.us.extend(movehist_update); } -- 2.30.2