From 28301fa599c0aea6aaa9cf2dc888ba47a4f664d9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 14 Mar 2021 19:02:47 +0000 Subject: [PATCH] Structure: Break out pcrender.rs Signed-off-by: Ian Jackson --- src/gamestate.rs | 177 --------------------------------------------- src/lib.rs | 1 + src/pcrender.rs | 184 +++++++++++++++++++++++++++++++++++++++++++++++ src/prelude.rs | 1 + 4 files changed, 186 insertions(+), 177 deletions(-) create mode 100644 src/pcrender.rs diff --git a/src/gamestate.rs b/src/gamestate.rs index aa5c86d1..6b8635da 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -19,13 +19,6 @@ pub struct Generation(pub u64); visible_slotmap_key!{ VisiblePieceId(b'.') } -type VisiblePieceAngle = PieceAngle; - -#[derive(Clone,Debug)] -#[derive(Serialize,Deserialize)] -#[serde(transparent)] -pub struct VisibleAngleTransform(String); - #[derive(Clone,Serialize,Deserialize,Hash,Eq,Ord,PartialEq,PartialOrd)] #[serde(transparent)] pub struct Html(pub String); @@ -284,41 +277,9 @@ impl Debug for Html { } } -impl VisiblePieceAngle { - pub fn to_transform(self) -> VisibleAngleTransform { - VisibleAngleTransform(base_misc::raw_angle_transform( - self.to_compass().into() - )) - } - - pub fn to_compass(self) -> CompassAngle { - match self { - PieceAngle::Compass(compass) => compass, - } - } -} - // ---------- game state - rendering etc. ---------- impl GPiece { - #[throws(IE)] - pub fn prep_piecestate(&self, ioccults: &IOccults, - ipc: &IPiece, pri: &PieceRenderInstructions) - -> PreparedPieceState { - let (pos, zlevel) = pri.pos_zlevel(self); - dbgc!(pos, pri, self, ioccults, ipc); - PreparedPieceState { - pos : pos, - held : self.held, - svg : pri.make_defs(ioccults, self, ipc)?, - z : zlevel.z, - zg : zlevel.zg, - angle : pri.angle(self).to_compass(), - pinned : self.pinned, - uos : pri.ui_operations(self, ipc.p.borrow())?, - } - } - #[throws(IE)] pub fn xdata(&self) -> Option<&T> { self.xdata.get()? @@ -384,144 +345,6 @@ impl PieceXDataState { } } -#[derive(Debug,Clone)] -pub struct PieceRenderInstructions { - pub vpid: VisiblePieceId, - pub occulted: PriOcculted, -} - -#[derive(Debug,Clone)] -pub enum PriOcculted { Visible, Occulted, Displaced(Pos, ZLevel) } - -impl PieceRenderInstructions { - pub fn new_visible(vpid: VisiblePieceId) -> PieceRenderInstructions { - PieceRenderInstructions { vpid, occulted: PriOcculted::Visible } - } - - #[throws(IE)] - fn instead<'p>(&self, ioccults: &'p IOccults, p: &'p IPiece) - -> Option<&'p dyn OccultedPieceTrait> - { - match self.occulted { - PriOcculted::Visible => None, - PriOcculted::Occulted | PriOcculted::Displaced(..) => { - Some({ - let occilk = p.occilk.as_ref() - .ok_or_else(|| internal_logic_error(format!( - "occulted non-occultable {:?}", p)))? - .borrow(); - let occ_data = ioccults.ilks.get(occilk) - .ok_or_else(|| internal_logic_error(format!( - "occulted ilk vanished {:?} {:?}", p, occilk)))?; - occ_data.p_occ.as_ref() - }) - }, - } - } - - pub fn angle(&self, gpc: &GPiece) -> VisiblePieceAngle { - match self.occulted { - PriOcculted::Visible => gpc.angle, - PriOcculted::Occulted | PriOcculted::Displaced(..) => default(), - } - } - - pub fn pos_zlevel(&self, gpc: &GPiece) -> (Pos, ZLevel) { - use PriOcculted as PO; - match &self.occulted { - PO::Visible | PO::Occulted => (gpc.pos, gpc.zlevel.clone()), - PO::Displaced(pos, zlevel) => (*pos, zlevel.clone()), - } - } - - #[throws(IE)] - pub fn make_defs<'p>(&self, ioccults: &IOccults, - gpc: &GPiece, ipc: &IPiece) -> Html - { - let pri = self; - let instead = pri.instead(ioccults, ipc)?; - - let o: &dyn OutlineTrait = match instead { - None => Borrow::::borrow(&ipc.p).dyn_upcast(), - Some(i) => i.dyn_upcast(), - }; - - let angle = pri.angle(gpc); - - let dragraise = match o.thresh_dragraise()? { - Some(n) if n < 0 => throw!(SvgE::NegativeDragraise), - Some(n) => n, - None => -1, - }; - - let transform = angle.to_transform(); - - let mut defs = Html(String::new()); - write!(&mut defs.0, - r##""##, - pri.vpid, &transform.0, dragraise)?; - - match instead { - None => { - ipc.p.svg_piece(&mut defs, gpc, pri.vpid)?; - }, - Some(i) => { - i.svg(&mut defs, pri.vpid)?; - }, - }; - - write!(&mut defs.0, r##""##)?; - write!(&mut defs.0, - r##""##, - pri.vpid, o.surround_path()?.0)?; - defs - } - - pub fn describe(&self, ioccults: &IOccults, - gpc: &GPiece, ipc: &IPiece) -> Html - { - self.describe_fallible(ioccults, gpc, ipc) - .unwrap_or_else(|e| { - error!("error describing piece: {:?}", e); - Html::lit("") - }) - } - - #[throws(IE)] - pub fn describe_fallible(&self, ioccults: &IOccults, - gpc: &GPiece, ipc: &IPiece) -> Html { - match self.instead(ioccults, ipc)? { - None => ipc.p.describe_html(gpc)?, - Some(i) => i.describe_html()?, - } - } - - #[throws(InternalError)] - pub fn ui_operations(&self, gpc: &GPiece, p: &dyn PieceTrait) - -> Vec - { - match self.occulted { - PriOcculted::Visible => (), - PriOcculted::Occulted | PriOcculted::Displaced(..) => return vec![], - }; - - type WRC = WhatResponseToClientOp; - - let mut out = vec![]; - if p.nfaces() > 1 { - out.push(UoDescription { - wrc: WRC::UpdateSvg, - kind: UoKind::Global, - def_key: 'f'.into(), - opname: "flip".to_string(), - desc: Html::lit("flip"), - }) - } - p.add_ui_operations(&mut out, gpc)?; - out - } -} - // ---------- log expiry ========== impl GameState { diff --git a/src/lib.rs b/src/lib.rs index 7796d698..1c4072c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,7 @@ pub mod keydata; pub mod mgmtchannel; pub mod nwtemplates; pub mod occultilks; +pub mod pcrender; pub mod pieces; pub mod shapelib; pub mod spec; diff --git a/src/pcrender.rs b/src/pcrender.rs new file mode 100644 index 00000000..860e8813 --- /dev/null +++ b/src/pcrender.rs @@ -0,0 +1,184 @@ +// Copyright 2020-2021 Ian Jackson and contributors to Otter +// SPDX-License-Identifier: AGPL-3.0-or-later +// There is NO WARRANTY. + +use crate::prelude::*; + +pub type VisiblePieceAngle = PieceAngle; + +#[derive(Clone,Debug)] +#[derive(Serialize,Deserialize)] +#[serde(transparent)] +pub struct VisibleAngleTransform(String); + +#[derive(Debug,Clone)] +pub struct PieceRenderInstructions { + pub vpid: VisiblePieceId, + pub occulted: PriOcculted, +} + +#[derive(Debug,Clone)] +pub enum PriOcculted { Visible, Occulted, Displaced(Pos, ZLevel) } + +impl VisiblePieceAngle { + pub fn to_transform(self) -> VisibleAngleTransform { + VisibleAngleTransform(base_misc::raw_angle_transform( + self.to_compass().into() + )) + } + + pub fn to_compass(self) -> CompassAngle { + match self { + PieceAngle::Compass(compass) => compass, + } + } +} + +impl GPiece { + #[throws(IE)] + pub fn prep_piecestate(&self, ioccults: &IOccults, + ipc: &IPiece, pri: &PieceRenderInstructions) + -> PreparedPieceState { + let (pos, zlevel) = pri.pos_zlevel(self); + dbgc!(pos, pri, self, ioccults, ipc); + PreparedPieceState { + pos : pos, + held : self.held, + svg : pri.make_defs(ioccults, self, ipc)?, + z : zlevel.z, + zg : zlevel.zg, + angle : pri.angle(self).to_compass(), + pinned : self.pinned, + uos : pri.ui_operations(self, ipc.p.borrow())?, + } + } +} + +impl PieceRenderInstructions { + pub fn new_visible(vpid: VisiblePieceId) -> PieceRenderInstructions { + PieceRenderInstructions { vpid, occulted: PriOcculted::Visible } + } + + #[throws(IE)] + fn instead<'p>(&self, ioccults: &'p IOccults, p: &'p IPiece) + -> Option<&'p dyn OccultedPieceTrait> + { + match self.occulted { + PriOcculted::Visible => None, + PriOcculted::Occulted | PriOcculted::Displaced(..) => { + Some({ + let occilk = p.occilk.as_ref() + .ok_or_else(|| internal_logic_error(format!( + "occulted non-occultable {:?}", p)))? + .borrow(); + let occ_data = ioccults.ilks.get(occilk) + .ok_or_else(|| internal_logic_error(format!( + "occulted ilk vanished {:?} {:?}", p, occilk)))?; + occ_data.p_occ.as_ref() + }) + }, + } + } + + pub fn angle(&self, gpc: &GPiece) -> VisiblePieceAngle { + match self.occulted { + PriOcculted::Visible => gpc.angle, + PriOcculted::Occulted | PriOcculted::Displaced(..) => default(), + } + } + + pub fn pos_zlevel(&self, gpc: &GPiece) -> (Pos, ZLevel) { + use PriOcculted as PO; + match &self.occulted { + PO::Visible | PO::Occulted => (gpc.pos, gpc.zlevel.clone()), + PO::Displaced(pos, zlevel) => (*pos, zlevel.clone()), + } + } + + #[throws(IE)] + pub fn make_defs<'p>(&self, ioccults: &IOccults, + gpc: &GPiece, ipc: &IPiece) -> Html + { + let pri = self; + let instead = pri.instead(ioccults, ipc)?; + + let o: &dyn OutlineTrait = match instead { + None => Borrow::::borrow(&ipc.p).dyn_upcast(), + Some(i) => i.dyn_upcast(), + }; + + let angle = pri.angle(gpc); + + let dragraise = match o.thresh_dragraise()? { + Some(n) if n < 0 => throw!(SvgE::NegativeDragraise), + Some(n) => n, + None => -1, + }; + + let transform = angle.to_transform(); + + let mut defs = Html(String::new()); + write!(&mut defs.0, + r##""##, + pri.vpid, &transform.0, dragraise)?; + + match instead { + None => { + ipc.p.svg_piece(&mut defs, gpc, pri.vpid)?; + }, + Some(i) => { + i.svg(&mut defs, pri.vpid)?; + }, + }; + + write!(&mut defs.0, r##""##)?; + write!(&mut defs.0, + r##""##, + pri.vpid, o.surround_path()?.0)?; + defs + } + + pub fn describe(&self, ioccults: &IOccults, + gpc: &GPiece, ipc: &IPiece) -> Html + { + self.describe_fallible(ioccults, gpc, ipc) + .unwrap_or_else(|e| { + error!("error describing piece: {:?}", e); + Html::lit("") + }) + } + + #[throws(IE)] + pub fn describe_fallible(&self, ioccults: &IOccults, + gpc: &GPiece, ipc: &IPiece) -> Html { + match self.instead(ioccults, ipc)? { + None => ipc.p.describe_html(gpc)?, + Some(i) => i.describe_html()?, + } + } + + #[throws(InternalError)] + pub fn ui_operations(&self, gpc: &GPiece, p: &dyn PieceTrait) + -> Vec + { + match self.occulted { + PriOcculted::Visible => (), + PriOcculted::Occulted | PriOcculted::Displaced(..) => return vec![], + }; + + type WRC = WhatResponseToClientOp; + + let mut out = vec![]; + if p.nfaces() > 1 { + out.push(UoDescription { + wrc: WRC::UpdateSvg, + kind: UoKind::Global, + def_key: 'f'.into(), + opname: "flip".to_string(), + desc: Html::lit("flip"), + }) + } + p.add_ui_operations(&mut out, gpc)?; + out + } +} diff --git a/src/prelude.rs b/src/prelude.rs index a2c09917..bc6c8d5a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -124,6 +124,7 @@ pub use crate::keydata::*; pub use crate::mgmtchannel::*; pub use crate::nwtemplates; pub use crate::occultilks::*; +pub use crate::pcrender::*; pub use crate::pieces::*; pub use crate::shapelib; pub use crate::slotmap_slot_idx::*; -- 2.30.2