From: Ian Jackson Date: Sat, 15 May 2021 01:33:52 +0000 (+0100) Subject: Piece traits: Pass ig and depth rather than PieceAliases X-Git-Tag: otter-0.6.0~295 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=bb51279ec9d0a11100f24b2e2805d9c531989cb2;p=otter.git Piece traits: Pass ig and depth rather than PieceAliases Bundle loading needs ig too. gref is not Signed-off-by: Ian Jackson --- diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 9f77f649..4b5bb8a4 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -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 }) }); diff --git a/src/bin/otterlib.rs b/src/bin/otterlib.rs index 7778501f..3b22dbe9 100644 --- a/src/bin/otterlib.rs +++ b/src/bin/otterlib.rs @@ -80,7 +80,7 @@ fn preview(items: Vec) { } 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) { 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![]; diff --git a/src/clock.rs b/src/clock.rs index 706182dc..b3276f06 100644 --- a/src/clock.rs +++ b/src/clock.rs @@ -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) } diff --git a/src/deck.rs b/src/deck.rs index 04b4d305..5e3101c6 100644 --- a/src/deck.rs +++ b/src/deck.rs @@ -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, diff --git a/src/gamestate.rs b/src/gamestate.rs index 85eb1fa7..65adb3a9 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -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; - fn load_occult(&self, _pcaliases: &PieceAliases) + fn load_occult(&self, _ig: &Instance, _:SpecDepth) -> Result, SpecError> { throw!(SpE::ComplexPieceWhereSimpleRequired) } @@ -303,6 +305,15 @@ impl UniqueGenGen<'_> { } } +impl SpecDepth { + pub fn zero() -> Self { Self(0) } + pub fn increment(self) -> Option { + const MAX: SpecDepth = SpecDepth(5); + if self > MAX { return None } + Some(Self(self.0 + 1)) + } +} + impl Timestamp { /// Always >= previously pub fn now() -> Timestamp { diff --git a/src/global.rs b/src/global.rs index c24ac09e..4ab5b9cb 100644 --- a/src/global.rs +++ b/src/global.rs @@ -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> { diff --git a/src/hand.rs b/src/hand.rs index 14597a1a..9a574158 100644 --- a/src/hand.rs +++ b/src/hand.rs @@ -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)? } diff --git a/src/pcaliases.rs b/src/pcaliases.rs index 7287d6bf..26cb29d4 100644 --- a/src/pcaliases.rs +++ b/src/pcaliases.rs @@ -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 { - self.resolve(pcaliases)?.load_occult(&default())? + self.resolve(&ig.pcaliases)?.load_occult(ig, self.new_depth(depth)?)? } } diff --git a/src/pieces.rs b/src/pieces.rs index aa70ac68..1c7ed1be 100644 --- a/src/pieces.rs +++ b/src/pieces.rs @@ -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)? } diff --git a/src/shapelib.rs b/src/shapelib.rs index ba680cae..f115bdbc 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -381,11 +381,11 @@ impl From 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::(), pcaliases)? + lib.load1(idata, &self.lib, item.unnest::(), ig, depth)? } fn from_strs(lib: &L, item: &I) -> Self @@ -422,7 +422,7 @@ impl Contents { #[throws(SpecError)] fn load1(&self, idata: &ItemData, lib_name: &str, name: &SvgBaseName, - 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 { - self.find_load(pcaliases)?.0 as Box + self.find_load(ig,depth)?.0 as Box } } @@ -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() } } diff --git a/src/spec.rs b/src/spec.rs index b5e61fa0..017b9b22 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -83,6 +83,7 @@ pub enum SpecError { ComplexPieceWhereSimpleRequired, AliasNotFound, AliasTargetMultiSpec, + AliasLoop(String), } display_as_debug!{SpecError}