chiark / gitweb /
simple pieces: support edges
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 12 Feb 2021 23:09:13 +0000 (23:09 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 13 Feb 2021 01:47:37 +0000 (01:47 +0000)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
specs/demo.game.toml
src/pieces.rs
src/spec.rs

index c1d91819df478023540249816776f49cef0a40e3..cb5c3a36f3010fdc642d2e279407d0e483c9c9fe 100644 (file)
@@ -9,6 +9,7 @@ pos = [90,40]
 type = "Disc"
 diam = 10
 faces = ["red","grey"]
+edges = ["black","white"]
 
 [[pieces]]
 pos = [90, 20]
index 2bc59e804d972c5e85e36d236fe5b0bd35adc357..9d7e531dee23119a2d2b7fbe02a3c9c335b7db48 100644 (file)
@@ -16,6 +16,7 @@ struct SimpleShape {
   desc: Html,
   path: Html,
   colours: ColourMap,
+  #[serde(default)] edges: ColourMap,
   itemname: String,
   outline: Box<dyn Outline>,
 }
@@ -121,8 +122,16 @@ impl Outline for SimpleShape {
 impl Piece for SimpleShape {
   #[throws(IE)]
   fn svg_piece(&self, f: &mut Html, pri: &PieceRenderInstructions) {
-    write!(&mut f.0, r##"<path fill="{}" d="{}"/>"##,
-           self.colours[pri.face].0,
+    let ef = |cmap: &ColourMap, attrname: &str| {
+      if let Some(colour) = cmap.get(pri.face) {
+        format!(r##"{}="{}""##, attrname, colour.0)
+      } else {
+        "".to_owned()
+      }
+    };
+    write!(&mut f.0, r##"<path {} {} d="{}"/>"##,
+           ef(&self.colours, "fill"),
+           ef(&self.edges, r##"stroke-width="0.2" stroke"##),
            &self.path.0)?;
   }
   fn describe_html(&self, face: Option<FaceId>) -> Html {
@@ -132,12 +141,14 @@ impl Piece for SimpleShape {
       format!("a {}", self.desc.0)
     })
   }
-  fn nfaces(&self) -> RawFaceId { self.colours.len().try_into().unwrap() }
+  fn nfaces(&self) -> RawFaceId { self.count_faces().try_into().unwrap() }
 
   fn itemname(&self) -> &str { &self.itemname }
 }
 
 impl SimpleShape {
+  fn count_faces(&self) -> usize { max(self.colours.len(), self.edges.len()) }
+
   #[throws(SpecError)]
   fn new(desc: Html, path: Html,
          outline: Box<dyn Outline>,
@@ -147,13 +158,32 @@ impl SimpleShape {
   {
     let itemname = common.itemname.clone()
       .unwrap_or_else(|| def_itemname.to_string());
-    let colours = common.faces
-      .iter()
-      .map(|s| s.try_into())
-      .collect::<Result<_,SpecError>>()?;
-    SimpleShape {
-      desc, path, colours, itemname, outline,
-    }
+
+    let cmap = |spec: &FaceColourSpecs| Ok::<_,SpecError>(
+      spec
+        .iter()
+        .map(|s| s.try_into())
+        .collect::<Result<_,_>>()?
+    );
+
+    let shape = SimpleShape {
+      desc, path, itemname, outline,
+      colours: cmap(&common.faces)?,
+      edges: cmap(&common.edges)?,
+    };
+
+    let count = shape.count_faces();
+    if count == 0 { throw!(SpecError::ZeroFaces) }
+
+    let check = |colours: &ColourMap| {
+      let x = colours.len();
+      if x == 0 || x == count { Ok(()) }
+      else { Err(SpecError::InconsistentFacesEdgecoloursCount) }
+    };
+    check(&shape.colours)?;
+    check(&shape.edges)?;
+
+    shape
   }
 }
 
index 03bcccb20cecfa9e6adb4b39ecfe8370267e3b67..1b20ff35d623b30260ad0305941100a296dd7650 100644 (file)
@@ -77,6 +77,8 @@ pub enum SpecError {
   BadUrlSyntax,
   UrlTooLong,
   CompassAngleInvalid,
+  ZeroFaces,
+  InconsistentFacesEdgecoloursCount,
 }
 display_as_debug!{SpecError}
 
@@ -198,6 +200,7 @@ pub mod piece_specs {
   pub struct SimpleCommon {
     pub itemname: Option<String>,
     pub faces: IndexVec<FaceId, ColourSpec>,
+    #[serde(default)] pub edges: IndexVec<FaceId, ColourSpec>,
   }
 
   #[derive(Debug,Serialize,Deserialize)]