From: Ian Jackson Date: Sat, 20 Feb 2021 00:23:46 +0000 (+0000) Subject: Outline: use enum_dispatch X-Git-Tag: otter-0.4.0~415 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=5dd8ab97f1b4363a74a7eba5d18fd75add6530a0;p=otter.git Outline: use enum_dispatch Signed-off-by: Ian Jackson --- diff --git a/src/gamestate.rs b/src/gamestate.rs index b728bc3c..e69b9356 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -110,7 +110,7 @@ pub trait PieceXData: Downcast + Debug + Send + 'static { } impl_downcast!(PieceXData); -#[typetag::serde] +#[enum_dispatch] pub trait Outline: Send + Debug { fn surround_path(&self, pri: &PieceRenderInstructions) -> Result; fn thresh_dragraise(&self, pri: &PieceRenderInstructions) diff --git a/src/hand.rs b/src/hand.rs index 89508864..1d657ab4 100644 --- a/src/hand.rs +++ b/src/hand.rs @@ -27,7 +27,6 @@ struct HandState { #[typetag::serde(name="Hand")] impl PieceXData for HandState { } -#[typetag::serde] impl Outline for Hand { delegate!{ to self.shape { diff --git a/src/pieces.rs b/src/pieces.rs index e0d9bc6a..4e23dd20 100644 --- a/src/pieces.rs +++ b/src/pieces.rs @@ -19,7 +19,7 @@ pub struct SimpleShape { #[serde(default)] pub edges: ColourMap, #[serde(default="default_edge_width")] pub edge_width: f64, pub itemname: String, - pub outline: Box, + pub outline: OutlineRepr, } pub const SELECT_SCALE: f64 = 1.1; @@ -111,7 +111,6 @@ pub fn svg_rectangle_path(PosC([x,y]): PosC) -> Html { -x*0.5, -y*0.5, x, y, -x)) } -#[typetag::serde] impl Outline for SimpleShape { delegate! { to self.outline { @@ -151,7 +150,7 @@ impl SimpleShape { #[throws(SpecError)] fn new(desc: Html, path: Html, - outline: Box, + outline: OutlineRepr, def_itemname: &'_ str, common: &SimpleCommon) -> SimpleShape @@ -238,7 +237,7 @@ impl SimplePieceSpec for piece_specs::Disc { (SimpleShape::new( Html::lit("disc"), svg_circle_path(self.diam as f64)?, - Box::new(outline), + outline.into(), "simple-disc", &self.common, )?, &self.common) @@ -266,11 +265,11 @@ impl piece_specs::Square { impl SimplePieceSpec for piece_specs::Square { #[throws(SpecError)] fn load_raw(&self) -> (SimpleShape, &SimpleCommon) { - let outline = shapelib::Square { xy: self.xy()?.map(|v| v as f64) }; + let outline = shapelib::Rectangle { xy: self.xy()?.map(|v| v as f64) }; (SimpleShape::new( Html::lit("square"), svg_rectangle_path(self.xy()?.promote())?, - Box::new(outline), + outline.into(), "simple-square", &self.common, )?, &self.common) diff --git a/src/prelude.rs b/src/prelude.rs index 0fd99fbc..259be25b 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -54,6 +54,7 @@ pub use delegate::delegate; pub use derive_more::*; pub use downcast_rs::{impl_downcast, Downcast}; pub use either::{Either, Left, Right}; +pub use enum_dispatch::enum_dispatch; pub use enum_map::{Enum, EnumMap}; pub use fehler::{throw, throws}; pub use flexi_logger::LogSpecification; diff --git a/src/shapelib.rs b/src/shapelib.rs index 0a0fbea4..790941f7 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -26,7 +26,7 @@ pub struct GroupData { #[typetag::deserialize(tag="outline")] pub trait OutlineDefn: Debug + Sync + Send { fn check(&self, lgi: &GroupData) -> Result<(),LLE>; - fn load(&self, lgi: &GroupData) -> Result,IE>; + fn load(&self, lgi: &GroupData) -> Result; } #[derive(Debug)] @@ -126,7 +126,7 @@ struct Item { desc_hidden: DescId, svgs: IndexVec, descs: IndexVec, - outline: Box, + outline: OutlineRepr, } #[derive(Debug,Clone,Serialize,Deserialize,Eq,PartialEq,Ord,PartialOrd)] @@ -142,7 +142,6 @@ impl ItemEnquiryData { } } -#[typetag::serde(name="Lib")] impl Outline for Item { delegate! { to self.outline { fn surround_path(&self, pri: &PieceRenderInstructions) -> Result; fn thresh_dragraise(&self, pri: &PieceRenderInstructions) @@ -493,10 +492,9 @@ pub fn load(libs: &Vec) { } } -#[derive(Serialize,Deserialize,Debug)] +#[derive(Clone,Copy,Debug,Serialize,Deserialize)] pub struct Circle { pub diam: f64 } -#[typetag::serde(name="Circle")] impl Outline for Circle { #[throws(IE)] fn surround_path(&self, _pri: &PieceRenderInstructions) -> Html { @@ -518,10 +516,10 @@ struct CircleDefn { } impl OutlineDefn for CircleDefn { #[throws(LibraryLoadError)] fn check(&self, lgd: &GroupData) { Self::get_size(lgd)?; } - fn load(&self, lgd: &GroupData) -> Result,IE> { - Ok(Box::new(Circle { + fn load(&self, lgd: &GroupData) -> Result { + Ok(Circle { diam: Self::get_size(lgd).map_err(|e| e.ought())?, - })) + }.into()) } } impl CircleDefn { @@ -535,11 +533,10 @@ impl CircleDefn { } } -#[derive(Serialize,Deserialize,Debug)] -pub struct Square { pub xy: PosC } +#[derive(Clone,Copy,Debug,Serialize,Deserialize)] +pub struct Rectangle { pub xy: PosC } -#[typetag::serde(name="Square")] -impl Outline for Square { +impl Outline for Rectangle { #[throws(IE)] fn surround_path(&self, _pri: &PieceRenderInstructions) -> Html { let size = self.xy * SELECT_SCALE; @@ -567,16 +564,16 @@ struct SquareDefn { } impl OutlineDefn for SquareDefn { #[throws(LibraryLoadError)] fn check(&self, lgd: &GroupData) { Self::get(lgd)?; } - fn load(&self, lgd: &GroupData) -> Result,IE> { - Ok(Box::new( - Self::get(lgd).map_err(|e| e.ought())? - )) + fn load(&self, lgd: &GroupData) -> Result { + Ok( + Self::get(lgd).map_err(|e| e.ought())?.into() + ) } } impl SquareDefn { #[throws(LibraryLoadError)] - fn get(group: &GroupData) -> Square { - Square { xy: PosC( + fn get(group: &GroupData) -> Rectangle { + Rectangle { xy: PosC( match group.d.size.as_slice() { &[s] => [s,s], s if s.len() == 2 => s.try_into().unwrap(), diff --git a/src/spec.rs b/src/spec.rs index 9164b18e..68cc506f 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -196,6 +196,20 @@ pub struct CompassAngle(u8); //---------- Piece specs ---------- // the implementations are in pieces.rs +mod outline { + use super::*; + use crate::prelude::*; + use crate::shapelib::{Circle, Rectangle}; + #[enum_dispatch(Outline)] + #[derive(Clone,Debug,Serialize,Deserialize)] + #[serde(tag="type")] + pub enum OutlineRepr { + Circle, + #[serde(alias="Square")] Rectangle, + } +} +pub use outline::*; + pub mod piece_specs { use super::*;