chiark / gitweb /
Piece traits: Pass ig and depth rather than PieceAliases
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 May 2021 01:33:52 +0000 (02:33 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 15 May 2021 10:55:11 +0000 (11:55 +0100)
Bundle loading needs ig too.  gref is not

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/cmdlistener.rs
src/bin/otterlib.rs
src/clock.rs
src/deck.rs
src/gamestate.rs
src/global.rs
src/hand.rs
src/pcaliases.rs
src/pieces.rs
src/shapelib.rs
src/spec.rs

index 9f77f6491deac02d1dcfe784429eeae3c42d72a1..4b5bb8a43ec3be902bb3bad690d5a1fe5791d80b 100644 (file)
@@ -878,7 +878,6 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
 
     MGI::AddPieces(PiecesSpec{ pos,posd,count,face,pinned,angle,info }) => {
       let (ig_g, modperm, _) = cs.check_acl_modify_pieces(ag, ig)?;
-      let gref = ig_g.gref.clone();
       let ig = &mut **ig_g;
       let gs = &mut ig.gs;
       let implicit: u32 = info.count(&ig.pcaliases)?
@@ -908,7 +907,7 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
       let mut pos = pos.unwrap_or(DEFAULT_POS_START);
       let mut z = gs.max_z.z.clone_mut();
       for piece_i in count {
-        let ilks = &mut ig.ioccults.ilks;
+        let gs = &mut ig.gs;
         let face = face.unwrap_or_default();
         let mut gpc = GPiece {
           held: None,
@@ -925,10 +924,12 @@ fn execute_game_insn<'cs, 'igr, 'ig: 'igr>(
           rotateable: true,
         };
         let PieceSpecLoaded { p, loaded_via_alias, occultable } =
-          info.load(piece_i as usize, &mut gpc, &ig.pcaliases, &gref)?;
+          info.load(piece_i as usize, &mut gpc, &ig, SpecDepth::zero())?;
         if p.nfaces() <= face.into() {
           throw!(SpecError::FaceNotFound);
         }
+        let gs = &mut ig.gs;
+        let ilks = &mut ig.ioccults.ilks;
         let occilk = occultable.map(|(ilkname, p_occ)| {
           ilks.insert(ilkname, OccultIlkData { p_occ })
         });
index 7778501f265a48fa182db19c30feca20b42349ab..3b22dbe906487fe1c087584fdb645c8b90f67785 100644 (file)
@@ -80,7 +80,7 @@ fn preview(items: Vec<ItemForOutput>) {
   }
 
   const SEVERAL: usize = 3;
-  let pcaliases = default();
+  let ig_dummy = Instance::dummy();
 
   impl Prep {
     fn want_several(&self) -> bool {
@@ -96,7 +96,8 @@ fn preview(items: Vec<ItemForOutput>) {
     let spec = ItemSpec { lib: it.0, item: it.1.itemname.into() };
     let sortkey = it.1.sortkey;
     (||{
-      let (p, _occultable) = spec.clone().find_load(&pcaliases)
+      let (p, _occultable) = spec.clone()
+        .find_load(&ig_dummy, SpecDepth::zero())
         .context("load")?;
       // todo show occulted version too
       let mut uos = vec![];
index 706182dcd87628b14d9bff91653dbb04429f40e1..b3276f06529e3141a8ecd544dd140e6668d18352 100644 (file)
@@ -404,8 +404,7 @@ fn unprepared_update(piece: PieceId) -> UnpreparedUpdates {
 #[typetag::serde(name="ChessClock")]
 impl PieceSpec for Spec {
   #[throws(SpecError)]
-  fn load(&self, _: usize, gpc: &mut GPiece,
-          _pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, gpc: &mut GPiece, _ig: &Instance, _:SpecDepth)
           -> PieceSpecLoaded {
     if self.time <= 0 { throw!(SpecError::NegativeTimeout) }
 
index 04b4d305c1cdcdb6e31fc83c1d33f3bcd2bbdd27..5e3101c628c2430ea131fd738ff88c315902a064 100644 (file)
@@ -37,8 +37,7 @@ impl OutlineTrait for Deck {
 #[typetag::serde(name="PickupDeck")]
 impl PieceSpec for piece_specs::Deck {
   #[throws(SpecError)]
-  fn load(&self, _: usize, gpc: &mut GPiece,
-          _pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, gpc: &mut GPiece, _ig: &Instance, _:SpecDepth)
           -> PieceSpecLoaded {
     let common = SimpleCommon {
       itemname: None,
index 85eb1fa73fdc25a7b4c5742b604597fd6160287e..65adb3a95e2db2f5d5ee4816c8f41208607b2851 100644 (file)
@@ -26,6 +26,9 @@ pub struct Timestamp(pub u64); /* time_t */
 pub const DEFAULT_TABLE_SIZE: Pos = PosC::new( 400, 200 );
 pub const DEFAULT_TABLE_COLOUR: &str = "green";
 
+#[derive(Copy,Clone,Debug,Eq,Ord,PartialEq,PartialOrd)]
+pub struct SpecDepth(u16);
+
 // ---------- general data types ----------
 
 #[derive(Debug,Clone,Eq,PartialEq,Ord,PartialOrd)]
@@ -264,10 +267,9 @@ pub type PieceSpecLoadedOccultable =
 pub trait PieceSpec: Debug + Sync + Send + 'static {
   #[throws(SpecError)]
   fn count(&self, _pcaliases: &PieceAliases) -> usize { 1 }
-  fn load(&self, i: usize, gpc: &mut GPiece,
-          pcaliases: &PieceAliases, ir: &InstanceRef)
+  fn load(&self, i: usize, gpc: &mut GPiece, ig: &Instance, depth: SpecDepth)
           -> Result<PieceSpecLoaded, SpecError>;
-  fn load_occult(&self, _pcaliases: &PieceAliases)
+  fn load_occult(&self, _ig: &Instance, _:SpecDepth)
                  -> Result<Box<dyn OccultedPieceTrait>, SpecError> {
     throw!(SpE::ComplexPieceWhereSimpleRequired)
   }
@@ -303,6 +305,15 @@ impl UniqueGenGen<'_> {
   }
 }
 
+impl SpecDepth {
+  pub fn zero() -> Self { Self(0) }
+  pub fn increment(self) -> Option<Self> {
+    const MAX: SpecDepth = SpecDepth(5);
+    if self > MAX { return None }
+    Some(Self(self.0 + 1))
+  }
+}
+
 impl Timestamp {
   /// Always >= previously
   pub fn now() -> Timestamp {
index c24ac09e85e4a24396bf10b6e6a820ab04f13ceb..4ab5b9cb972dd73ac3f2b3f62c6646941030e118 100644 (file)
@@ -490,6 +490,25 @@ impl Instance {
     );
     html
   }
+
+  pub fn dummy() -> Instance {
+    Instance {
+      name: Arc::new("server::".parse().unwrap()),
+      gs: GameState::dummy(),
+      ipieces: IPieces(default()),
+      pcaliases: default(),
+      ioccults: default(),
+      clients: default(),
+      tokens_players: default(),
+      tokens_clients: default(),
+      acl: default(),
+      links: default(),
+      bundle_list: default(),
+      asset_url_key: AssetUrlKey::Dummy,
+      iplayers: default(),
+    }
+  }
+
 }
 
 pub fn games_lock() -> RwLockWriteGuard<'static, GamesTable> {
index 14597a1aaa2538afeaf1cca9cd44e9e5761f319b..9a57415899e951ee8147e9e88808d12e8d5ea1fb 100644 (file)
@@ -119,8 +119,7 @@ impl piece_specs::OwnedCommon {
 #[typetag::serde]
 impl PieceSpec for piece_specs::Hand {
   #[throws(SpecError)]
-  fn load(&self, _: usize, gpc: &mut GPiece,
-          _pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, gpc: &mut GPiece, _ig: &Instance, _:SpecDepth)
           -> PieceSpecLoaded {
     gpc.moveable = PieceMoveable::IfWresting;
     gpc.rotateable = false;
@@ -131,8 +130,7 @@ impl PieceSpec for piece_specs::Hand {
 #[typetag::serde]
 impl PieceSpec for piece_specs::PlayerLabel {
   #[throws(SpecError)]
-  fn load(&self, _: usize, _: &mut GPiece,
-          _pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, _: &mut GPiece, _ig: &Instance, _:SpecDepth)
           -> PieceSpecLoaded {
     self.c.load(Behaviour::PlayerLabel)?
   }
index 7287d6bfc9f47b040bdb9427651cb369e5d7ba1f..26cb29d48f7f8413280db6a66568d33c679ffd34 100644 (file)
@@ -41,6 +41,13 @@ impl Alias {
         .ok_or(SpecError::AliasNotFound)?
     )
   }
+
+  #[throws(SpecError)]
+  fn new_depth(&self, depth: SpecDepth) -> SpecDepth {
+    depth.increment().ok_or_else(||{
+      SpE::AliasLoop(self.target.clone())
+    })?
+  }
 }
 
 #[typetag::serde]
@@ -52,17 +59,17 @@ impl PieceSpec for Alias {
     self.resolve(pcaliases)?.count(&default())?
   }
   #[throws(SpecError)]
-  fn load(&self, i: usize, gpc: &mut GPiece,
-          pcaliases: &PieceAliases, ir: &InstanceRef)
+  fn load(&self, i: usize, gpc: &mut GPiece, ig: &Instance, depth: SpecDepth)
           -> PieceSpecLoaded {
-    let mut r = self.resolve(pcaliases)?.load(i, gpc, &default(), ir)?;
+    let mut r = self.resolve(&ig.pcaliases)?
+      .load(i, gpc, ig, self.new_depth(depth)?)?;
     r.loaded_via_alias = Some(self.target.clone());
     r
   }
   #[throws(SpecError)]
-  fn load_occult(&self, pcaliases: &PieceAliases)
+  fn load_occult(&self, ig: &Instance, depth: SpecDepth)
                  -> Box<dyn OccultedPieceTrait> {
-    self.resolve(pcaliases)?.load_occult(&default())?
+    self.resolve(&ig.pcaliases)?.load_occult(ig, self.new_depth(depth)?)?
   }
 }
 
index aa70ac68a33fd56e5edcc22b9031fae209caaa71..1c7ed1be1e1d6a54453bab4c0977bf640bb86cf8 100644 (file)
@@ -325,8 +325,7 @@ impl SimplePieceSpec for piece_specs::Disc {
 #[typetag::serde]
 impl PieceSpec for piece_specs::Disc {
   #[throws(SpecError)]
-  fn load(&self, _: usize, _: &mut GPiece,
-          _pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, _: &mut GPiece, _ig: &Instance, _:SpecDepth)
           -> PieceSpecLoaded {
     SimplePieceSpec::load(self)?
   }
@@ -364,8 +363,7 @@ impl SimplePieceSpec for piece_specs::Rect {
 #[typetag::serde]
 impl PieceSpec for piece_specs::Rect {
   #[throws(SpecError)]
-  fn load(&self, _: usize, _: &mut GPiece,
-          _pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, _: &mut GPiece, _ig: &Instance, _:SpecDepth)
           -> PieceSpecLoaded {
     SimplePieceSpec::load(self)?
   }
index ba680caeef6f2a237542f3c3b46024005108b71d..f115bdbc5866d0e5ecd98b960ff23fa00241218e 100644 (file)
@@ -381,11 +381,11 @@ impl From<ItemSpecLoaded> for PieceSpecLoaded {
 
 impl ItemSpec {
   #[throws(SpecError)]
-  pub fn find_load(&self, pcaliases: &PieceAliases) -> ItemSpecLoaded {
+  pub fn find_load(&self, ig: &Instance, depth: SpecDepth) -> ItemSpecLoaded {
     let lib = libs_lookup(&self.lib)?;
     let (item, idata) = lib.items.get_key_value(self.item.as_str())
       .ok_or(SpE::LibraryItemNotFound(self.clone()))?;
-    lib.load1(idata, &self.lib, item.unnest::<str>(), pcaliases)?
+    lib.load1(idata, &self.lib, item.unnest::<str>(), ig, depth)?
   }
 
   fn from_strs<L,I>(lib: &L, item: &I) -> Self
@@ -422,7 +422,7 @@ impl Contents {
   #[throws(SpecError)]
   fn load1(&self, idata: &ItemData, lib_name: &str,
            name: &SvgBaseName<str>,
-           pcaliases: &PieceAliases)
+           ig: &Instance, depth:SpecDepth)
            -> ItemSpecLoaded {
     let svg_data = self.load_svg(name, lib_name, &**name)?;
 
@@ -446,7 +446,7 @@ impl Contents {
       face.xform.scale[0] *= -1.;
       faces.push(face);
     } else if let Some(back_spec) = &idata.group.d.back {
-      match back_spec.load_occult(pcaliases) {
+      match back_spec.load_occult(ig, depth) {
         Err(SpecError::AliasNotFound) => { },
         Err(e) => throw!(e),
         Ok(p) => {
@@ -510,7 +510,8 @@ impl Contents {
     for (k,v) in &self.items {
       if !pat.matches(k.as_str()) { continue }
       let (loaded, _) = match
-        self.load1(v, &self.libname, k.unnest(), &default())
+        self.load1(v, &self.libname, k.unnest(),
+                   &Instance::dummy(), SpecDepth::zero())
       {
         Err(SpecError::LibraryItemNotFound(_)) => continue,
         Err(SpecError::LibraryItemNotPrepared(_)) => continue,
@@ -533,15 +534,14 @@ impl Contents {
 #[typetag::serde(name="Lib")]
 impl PieceSpec for ItemSpec {
   #[throws(SpecError)]
-  fn load(&self, _: usize, _: &mut GPiece,
-          pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, _: usize, _: &mut GPiece, ig: &Instance, depth: SpecDepth)
           -> PieceSpecLoaded {
-    self.find_load(pcaliases)?.into()
+    self.find_load(ig,depth)?.into()
   }
   #[throws(SpecError)]
-  fn load_occult(&self, pcaliases: &PieceAliases)
+  fn load_occult(&self, ig: &Instance, depth: SpecDepth)
                  -> Box<dyn OccultedPieceTrait> {
-    self.find_load(pcaliases)?.0 as Box<dyn OccultedPieceTrait>
+    self.find_load(ig,depth)?.0 as Box<dyn OccultedPieceTrait>
   }
 }
 
@@ -551,8 +551,7 @@ impl PieceSpec for MultiSpec {
   fn count(&self, _pcaliases: &PieceAliases) -> usize { self.items.len() }
 
   #[throws(SpecError)]
-  fn load(&self, i: usize, _: &mut GPiece,
-          pcaliases: &PieceAliases, _ir: &InstanceRef)
+  fn load(&self, i: usize, _: &mut GPiece, ig: &Instance, depth:SpecDepth)
           -> PieceSpecLoaded
   {
     let item = self.items.get(i).ok_or_else(
@@ -560,7 +559,7 @@ impl PieceSpec for MultiSpec {
     )?;
     let item = format!("{}{}{}", &self.prefix, item, &self.suffix);
     let lib = self.lib.clone();
-    ItemSpec { lib, item }.find_load(pcaliases)?.into()
+    ItemSpec { lib, item }.find_load(ig,depth)?.into()
   }
 }
 
index b5e61fa096ab44354ecc565b83d794c52066cf6a..017b9b22b5a05be8c0311599d9c3a65d5e8ca5e7 100644 (file)
@@ -83,6 +83,7 @@ pub enum SpecError {
   ComplexPieceWhereSimpleRequired,
   AliasNotFound,
   AliasTargetMultiSpec,
+  AliasLoop(String),
 }
 display_as_debug!{SpecError}