From f499e29f043a9f39069717e1b599f44f10362000 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 8 Jul 2020 14:38:47 +0100 Subject: [PATCH] server side new raise --- src/bin/server.rs | 8 +++++--- src/error.rs | 2 ++ src/gamestate.rs | 27 +++++++++++++++++++++++++-- src/global.rs | 7 ++++--- src/http.rs | 1 + src/imports.rs | 5 +++-- src/sse.rs | 5 +++-- 7 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index f17c8778..97ac32b0 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -87,7 +87,7 @@ fn session(form : Json) -> Result { let mut pieces : Vec<_> = ig.gs.pieces.iter().collect(); - pieces.sort_by_key(|(_,pr)| pr.raised); + pieces.sort_by_key(|(_,pr)| pr.zlevel); for (gpid, pr) in pieces { let pri = PieceRenderInstructions { @@ -231,6 +231,7 @@ fn api_piece_op(form : Json>) client, sameclient_cseq : form.cseq, piece : pri_for_all.id, + zg : pc.zlevel.1, op : update, }); @@ -320,6 +321,7 @@ impl ApiPieceOp for ApiPieceUngrab { #[derive(Debug,Serialize,Deserialize)] struct ApiPieceRaise { + z : ZCoord, } #[post("/_/api/raise", format="json", data="
")] #[throws(OE)] @@ -333,8 +335,8 @@ impl ApiPieceOp for ApiPieceRaise { _: &dyn Lens) -> (PieceUpdateOp<()>, Vec) { let pc = gs.pieces.byid_mut(piece).unwrap(); - pc.raised = gs.gen; - let update = PieceUpdateOp::Raise(); + pc.zlevel = (self.z, gs.gen); + let update = PieceUpdateOp::SetZLevel(pc.zlevel); (update, vec![]) } } diff --git a/src/error.rs b/src/error.rs index 7aabe52c..2ff9da47 100644 --- a/src/error.rs +++ b/src/error.rs @@ -19,6 +19,8 @@ pub enum OnlineError { NoClient, #[error("player not part of game (removed?)")] NoPlayer, + #[error("invalid Z coordinate")] + InvalidZCoord, } pub use OnlineError::{NoClient,NoPlayer}; diff --git a/src/gamestate.rs b/src/gamestate.rs index 5a672dab..f6169ee5 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -47,13 +47,36 @@ pub trait Piece : Send + Debug { fn describe_html(&self, face : Option) -> String; } +#[derive(Debug,Copy,Clone,PartialEq,PartialOrd)] +#[derive(Serialize,Deserialize)] +#[serde(into="f64")] +#[serde(try_from="f64")] +pub struct ZCoord(f64); +impl TryFrom for ZCoord { + type Error = OnlineError; + #[throws(OnlineError)] + fn try_from(v: f64) -> ZCoord { + if !v.is_finite() { Err(OnlineError::InvalidZCoord)? } + ZCoord(v) + } +} +impl From for f64 { + fn from(v: ZCoord) -> f64 { v.0 } +} +impl Ord for ZCoord { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.0.partial_cmp(&other.0).unwrap() + } +} +impl Eq for ZCoord { } + #[derive(Debug)] pub struct PieceRecord { pub pos : Pos, pub p : Box, pub face : FaceId, pub held : Option, - pub raised : Generation, + pub zlevel : (ZCoord,Generation), pub gen : Generation, pub lastclient : ClientId, pub gen_before_lastclient : Generation, @@ -127,7 +150,7 @@ pub fn xxx_gamestate_init() -> GameState { face : 0.into(), held : None, lastclient : Default::default(), - raised: Generation(0), + zlevel : (0f64 .try_into().unwrap(), Generation(0)), gen, gen_before_lastclient : Generation(0), }; diff --git a/src/global.rs b/src/global.rs index 69f6aac7..f1910733 100644 --- a/src/global.rs +++ b/src/global.rs @@ -30,6 +30,7 @@ pub enum PreparedUpdateEntry { sameclient_cseq : ClientSequence, piece : VisiblePieceId, op : PieceUpdateOp, + zg : Generation, }, Log (Arc), } @@ -59,7 +60,7 @@ pub enum PieceUpdateOp { Insert(NS), Modify(NS), Move(Pos), - Raise(), + SetZLevel((ZCoord, Generation)), } impl PieceUpdateOp { pub fn new_state(&self) -> Option<&NS> { @@ -69,7 +70,7 @@ impl PieceUpdateOp { Insert(ns) => Some(ns), Modify(ns) => Some(ns), Move(_) => None, - Raise() => None, + SetZLevel(_) => None, } } pub fn map_new_state NS2>(self, f:F) @@ -80,7 +81,7 @@ impl PieceUpdateOp { Insert(ns) => Insert(f(ns)), Modify(ns) => Modify(f(ns)), Move(pos) => Move(pos), - Raise() => Raise(), + SetZLevel(zl) => SetZLevel(zl), } } } diff --git a/src/http.rs b/src/http.rs index 292466e1..b9711025 100644 --- a/src/http.rs +++ b/src/http.rs @@ -13,6 +13,7 @@ impl<'r> Responder<'r> for OnlineError { let status = match self { GameCorrupted => Status::InternalServerError, NoClient | NoPlayer => Status::NotFound, + InvalidZCoord => Status::BadRequest, }; let mut resp = Responder::respond_to(msg,req).unwrap(); resp.set_status(status); diff --git a/src/imports.rs b/src/imports.rs index 0cade33f..80894365 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -8,14 +8,15 @@ pub use std::time::Duration; pub use std::sync::{Arc,Mutex,RwLock,Condvar}; pub use std::collections::HashMap; pub use std::borrow::Borrow; -pub use std::convert::TryFrom; +pub use std::convert::{TryFrom,TryInto}; pub use std::str; pub use std::str::FromStr; pub use std::iter; pub use std::iter::repeat_with; pub use std::collections::VecDeque; pub use std::num::Wrapping; - +pub use std::cmp; + pub use thiserror::Error; pub use anyhow::{Context,anyhow}; pub use fehler::{throws,throw}; diff --git a/src/sse.rs b/src/sse.rs index bf5e45cf..296b57f4 100644 --- a/src/sse.rs +++ b/src/sse.rs @@ -51,6 +51,7 @@ enum TransmitUpdate<'u> { Recorded { piece : VisiblePieceId, cseq : ClientSequence, + zg : Generation, }, Piece { piece : VisiblePieceId, @@ -94,9 +95,9 @@ impl Read for UpdateReader { for u in &next.us { let tu = match u { &PreparedUpdateEntry::Piece - { piece, client, sameclient_cseq : cseq, .. } + { piece, client, sameclient_cseq : cseq, zg, .. } if client== self.client => { - TransmitUpdate::Recorded { piece, cseq } + TransmitUpdate::Recorded { piece, cseq, zg } }, &PreparedUpdateEntry::Piece { piece, ref op, .. } => { TransmitUpdate::Piece { piece, op } -- 2.30.2