From: Ian Jackson Date: Thu, 1 Apr 2021 11:38:26 +0000 (+0100) Subject: movehost: Send updates. X-Git-Tag: otter-0.5.0~309 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=5492474e6b51ed653cc9af9d9eb97bce8a582c66;p=otter.git movehost: Send updates. Just a stub to receive them, right now. Signed-off-by: Ian Jackson --- diff --git a/base/misc.rs b/base/misc.rs index 7ee1c6f5..f7982cdb 100644 --- a/base/misc.rs +++ b/base/misc.rs @@ -9,6 +9,15 @@ use crate::prelude::*; pub const SVG_SCALE: f64 = 6.; +pub const MOVEHIST_LENS: &[usize] = &[ 1, 3, 10, 0]; +pub const MOVEHIST_LEN_MAX: usize = 10; + +#[test] +fn movehist_len_max() { assert_eq!( + MOVEHIST_LENS.iter().max(), + Some(&MOVEHIST_LEN_MAX), +) } + pub fn timestring_abbreviate<'x>(base: &str, this: &'x str) -> (&'x str, bool) { diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 52ed8f9d..4cab0716 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -383,6 +383,8 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>( nick: nick.to_string(), layout: arecord.layout, idmap: default(), + moveheld: default(), + movehist: default(), }; let ipl = IPlayer { acctid, diff --git a/src/gamestate.rs b/src/gamestate.rs index d5b03cbe..eef43382 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -55,6 +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, } #[derive(Debug,Serialize,Deserialize)] @@ -73,6 +75,25 @@ 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/prelude.rs b/src/prelude.rs index 5d0d64ab..d9a13edd 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -89,7 +89,7 @@ pub use serde::{de::DeserializeOwned, Deserialize, Serialize}; pub use serde::{Deserializer, Serializer}; pub use serde_with::DeserializeFromStr; pub use serde_with::SerializeDisplay; -pub use slotmap::{dense::DenseSlotMap, Key as _}; +pub use slotmap::{dense::DenseSlotMap, SparseSecondaryMap, Key as _}; pub use strum::{EnumString, EnumIter, EnumProperty}; pub use strum::{IntoEnumIterator, IntoStaticStr}; pub use thiserror::Error; diff --git a/src/updates.rs b/src/updates.rs index 9a35845e..0e8a97cf 100644 --- a/src/updates.rs +++ b/src/updates.rs @@ -55,6 +55,7 @@ pub struct PreparedUpdate { pub enum PreparedUpdateEntry { Piece(PreparedUpdateEntry_Piece), Image(PreparedUpdateEntry_Image), + MoveHistEnt(SecondarySlotMap), SetTableSize(Pos), SetTableColour(Colour), SetLinks(Arc), @@ -221,6 +222,7 @@ enum TransmitUpdateEntry<'u> { }, Piece(TransmitUpdateEntry_Piece<'u>), Image(TransmitUpdateEntry_Image<'u>), + MoveHistEnt(&'u MoveHistEnt), RecordedUnpredictable { piece: VisiblePieceId, cseq: ClientSequence, @@ -406,6 +408,9 @@ impl PreparedUpdateEntry { Image(ims) => { ims.json_len(player) } + MoveHistEnt(ents) => { + match ents.get(player) { None => 0, Some(_) => 100 } + } Log(logent) => { logent.logent.html.json_len() * 28 } @@ -752,7 +757,55 @@ impl<'r> PrepareUpdatesBuffer<'r> { piece, &e); 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(); + } + } + } } + + if pu.is_empty() { + None + } else { + Some(PUE::MoveHistEnt(pu)) + } + } else { + None + }; self.us.push(update); + self.us.extend(movehist_update); } #[throws(InternalError)] @@ -896,6 +949,12 @@ impl PreparedUpdate { _ => continue, } } + PUE::MoveHistEnt(ents) => { + match ents.get(player) { + Some(mhe) => TUE::MoveHistEnt(mhe), + _ => continue, + } + } PUE::Log(logent) => { TUE::Log((&tz, &logent)) } diff --git a/templates/script.ts b/templates/script.ts index 8d9972a6..8e23588a 100644 --- a/templates/script.ts +++ b/templates/script.ts @@ -970,6 +970,10 @@ messages.SetLinks = function links_elem.innerHTML = msg } +messages.MoveHistEnt = function +(todo: object) { +} + // ----- logs ----- messages.Log = function