chiark / gitweb /
shapelib refactoring: Change return type of load1
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 22 Mar 2021 00:42:28 +0000 (00:42 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 22 Mar 2021 00:57:19 +0000 (00:57 +0000)
We don't want this to be type-erased; we need to reuse it as a
different trait object.

This means making the `Item` struct public, but nothing else about it.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bin/otterlib.rs
src/gamestate.rs
src/shapelib.rs
src/spec.rs

index 38287f450cad9ecba79ba3d2760fe57bd5a565d2..92b123b89e90f4a2f8f647f9bf9a4904eb305c7b 100644 (file)
@@ -91,8 +91,8 @@ fn preview(items: Vec<ItemForOutput>) {
   let mut pieces: Vec<Prep> = items.into_iter().map(|it| {
     let spec = ItemSpec { lib: it.0, item: it.1.itemname };
     (||{
-      let loaded = spec.clone().load().context("load")?;
-      let p = loaded.p; // todo show occulted version too
+      let (p, _occultable) = spec.clone().load().context("load")?;
+      // todo show occulted version too
       let mut uos = vec![];
       p.add_ui_operations(&mut uos, &GameState::dummy(), &GPiece::dummy())
         .context("add uos")?;
index 643047cc0d380d79ff8c0e10302aa0f065f56d6a..782f440cc8a3773abc418ed9977f4fd036d6acb8 100644 (file)
@@ -189,8 +189,10 @@ pub struct ApiPieceOpArgs<'a> {
 #[derive(Debug)]
 pub struct PieceSpecLoaded {
   pub p: Box<dyn PieceTrait>,
-  pub occultable: Option<(OccultIlkName, Box<dyn OccultedPieceTrait>)>,
+  pub occultable:  PieceSpecLoadedOccultable,
 }
+pub type PieceSpecLoadedOccultable =
+  Option<(OccultIlkName, Box<dyn OccultedPieceTrait>)>;
 
 #[typetag::serde(tag="type")]
 pub trait PieceSpec: Debug + Sync + Send + 'static {
index 9d51b58523a214af69d616b1f27fb17d7a3f8e15..c801462189d16aaf52d085cdb65837a3a5adcd00 100644 (file)
@@ -141,7 +141,7 @@ struct FaceTransform {
 }
 
 #[derive(Debug,Serialize,Deserialize)]
-struct Item {
+pub struct Item {
   itemname: String,
   faces: IndexVec<FaceId, ItemFace>,
   svgs: IndexVec<SvgId, Html>,
@@ -281,9 +281,17 @@ pub fn libs_lookup(libname: &str)
     ?
 }
 
+pub type ItemSpecLoaded = (Box<Item>, PieceSpecLoadedOccultable);
+
+impl From<ItemSpecLoaded> for PieceSpecLoaded {
+  fn from((p, occultable):  ItemSpecLoaded) -> PieceSpecLoaded {
+    PieceSpecLoaded { p, occultable }
+  }
+}
+
 impl ItemSpec {
   #[throws(SpecError)]
-  pub fn load(&self) -> PieceSpecLoaded {
+  pub fn load(&self) -> ItemSpecLoaded {
     let lib = libs_lookup(&self.lib)?;
     let idata = lib.items.get(&self.item)
       .ok_or(SpE::LibraryItemNotFound(self.item.clone()))?;
@@ -310,7 +318,7 @@ impl Contents {
   }
 
   #[throws(SpecError)]
-  fn load1(&self, idata: &ItemData, name: &str) -> PieceSpecLoaded {
+  fn load1(&self, idata: &ItemData, name: &str) -> ItemSpecLoaded {
     let svg_data = self.load_svg(name, name)?;
 
     let occultable = match &idata.occ {
@@ -364,8 +372,7 @@ impl Contents {
 
     let it = Item { faces, descs, svgs, outline,
                     itemname: name.to_string() };
-    let p = Box::new(it);
-    PieceSpecLoaded { p, occultable }
+    (Box::new(it), occultable)
   }
 
   #[throws(MgmtError)]
@@ -375,16 +382,16 @@ impl Contents {
     let mut out = vec![];
     for (k,v) in &self.items {
       if !pat.matches(&k) { continue }
-      let loaded = match self.load1(v, &k) {
+      let (loaded, _) = match self.load1(v, &k) {
         Err(SpecError::LibraryItemNotFound(_)) => continue,
         e@ Err(_) => e?,
         Ok(r) => r,
       };
-      let f0bbox = loaded.p.bbox_approx()?;
+      let f0bbox = loaded.bbox_approx()?;
       let ier = ItemEnquiryData {
         itemname: k.clone(),
         f0bbox,
-        f0desc: loaded.p.describe_html(&GPiece::dummy())?,
+        f0desc: loaded.describe_html(&GPiece::dummy())?,
       };
       out.push(ier);
     }
@@ -394,24 +401,27 @@ impl Contents {
 
 #[typetag::serde(name="Lib")]
 impl PieceSpec for ItemSpec {
+  #[throws(SpecError)]
   fn load(&self, _: usize, _: &mut GPiece, _ir: &InstanceRef)
-          -> Result<PieceSpecLoaded, SpecError> {
-    self.load()
+          -> PieceSpecLoaded {
+    self.load()?.into()
   }
 }
 
 #[typetag::serde(name="LibList")]
 impl PieceSpec for MultiSpec {
   fn count(&self) -> usize { self.items.len() }
+
+  #[throws(SpecError)]
   fn load(&self, i: usize, _: &mut GPiece, _ir: &InstanceRef)
-          -> Result<PieceSpecLoaded, SpecError>
+          -> PieceSpecLoaded
   {
     let item = self.items.get(i).ok_or_else(
       || SpE::InternalError(format!("item {:?} from {:?}", i, &self))
     )?;
     let item = format!("{}{}{}", &self.prefix, item, &self.suffix);
     let lib = self.lib.clone();
-    ItemSpec { lib, item }.load()
+    ItemSpec { lib, item }.load()?.into()
   }
 }
 
index bb963c56c388b1e66f4cebc0cf4837591cee0688..3369eb60084ed5a248f1c8177d2e47be12596efa 100644 (file)
@@ -84,6 +84,7 @@ pub enum SpecError {
   SpecifiedWidthOfNoEdges,
   UnsupportedShape,
   NegativeTimeout,
+  ComplexPieceWhereSimpleRequired,
 }
 display_as_debug!{SpecError}