chiark / gitweb /
Outline: use enum_dispatch
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 20 Feb 2021 00:23:46 +0000 (00:23 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 20 Feb 2021 10:45:02 +0000 (10:45 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/gamestate.rs
src/hand.rs
src/pieces.rs
src/prelude.rs
src/shapelib.rs
src/spec.rs

index b728bc3c7e8d9b69b94179e5db79491a96f06a9b..e69b935645f27a9d4d80858e203ef8ec8968516d 100644 (file)
@@ -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<Html, IE>;
   fn thresh_dragraise(&self, pri: &PieceRenderInstructions)
index 89508864dc428cfbe7815249e238b3fb303b4f5d..1d657ab4406fe1e19770dcd0c71c1d9122d50df8 100644 (file)
@@ -27,7 +27,6 @@ struct HandState {
 #[typetag::serde(name="Hand")]
 impl PieceXData for HandState { }
 
-#[typetag::serde]
 impl Outline for Hand {
   delegate!{
     to self.shape {
index e0d9bc6a97917e121f376a9f54f5b867ce10edf8..4e23dd20b4a129a1c331dcf184f21f634cd1cd54 100644 (file)
@@ -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<dyn Outline>,
+  pub outline: OutlineRepr,
 }
 
 pub const SELECT_SCALE: f64 = 1.1;
@@ -111,7 +111,6 @@ pub fn svg_rectangle_path(PosC([x,y]): PosC<f64>) -> 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<dyn Outline>,
+         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)
index 0fd99fbcb1ae65e132fbe26b67efaa4f848bf775..259be25b62150182e6221e84521db3ae5f47fb92 100644 (file)
@@ -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;
index 0a0fbea4bd26a95d0909971d6284e87b3f8e55c1..790941f768339197e1eb1a4d5407765780a40d97 100644 (file)
@@ -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<Box<dyn Outline>,IE>;
+  fn load(&self, lgi: &GroupData) -> Result<OutlineRepr,IE>;
 }
 
 #[derive(Debug)]
@@ -126,7 +126,7 @@ struct Item {
   desc_hidden: DescId,
   svgs: IndexVec<SvgId, Html>,
   descs: IndexVec<DescId, Html>,
-  outline: Box<dyn Outline>,
+  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<Html, IE>;
   fn thresh_dragraise(&self, pri: &PieceRenderInstructions)
@@ -493,10 +492,9 @@ pub fn load(libs: &Vec<Config1>) {
   }
 }
 
-#[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<Box<dyn Outline>,IE> {
-    Ok(Box::new(Circle {
+  fn load(&self, lgd: &GroupData) -> Result<OutlineRepr,IE> {
+    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<f64> }
+#[derive(Clone,Copy,Debug,Serialize,Deserialize)]
+pub struct Rectangle { pub xy: PosC<f64> }
 
-#[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<Box<dyn Outline>,IE> {
-    Ok(Box::new(
-      Self::get(lgd).map_err(|e| e.ought())?
-    ))
+  fn load(&self, lgd: &GroupData) -> Result<OutlineRepr,IE> {
+    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(),
index 9164b18e660bb55b4990f4aa4b72e6e994af7151..68cc506f20f824dd9c1ab8279c1693769a27565c 100644 (file)
@@ -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::*;