From 5adc8c7429bd7a9269d03dc8ca197741038cf679 Mon Sep 17 00:00:00 2001 From: Brent Yorgey Date: Sat, 13 Jan 2024 18:14:29 -0600 Subject: [PATCH] Child robots only inherit their parent's `displayAttr` (#1722) Fixes #1693. It's not necessarily appropriate to copy the entire `Display` record. So instead, we explicitly list the fields that should be inherited. For now, it is only `displayAttr`, but we could add `invisible` in the future (see #1670, #1663). Tested to make sure behavior is preserved with: ``` scripts/play.sh -i scenarios/Challenges/Ranching/beekeeping.yaml --autoplay ``` --- src/swarm-engine/Swarm/Game/Step/Const.hs | 5 ++++- src/swarm-util/Swarm/Util/Lens.hs | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/swarm-engine/Swarm/Game/Step/Const.hs b/src/swarm-engine/Swarm/Game/Step/Const.hs index 65799b99b..ef929f6ed 100644 --- a/src/swarm-engine/Swarm/Game/Step/Const.hs +++ b/src/swarm-engine/Swarm/Game/Step/Const.hs @@ -91,6 +91,7 @@ import Swarm.Language.Value import Swarm.Log import Swarm.Util hiding (both) import Swarm.Util.Effect (throwToMaybe) +import Swarm.Util.Lens (inherit) import Witch (From (from), into) import Prelude hiding (Applicative (..), lookup) @@ -1052,7 +1053,9 @@ execConst runChildProg c vs s k = do ( ((r ^. robotOrientation) >>= \dir -> guard (dir /= zero) >> return dir) ? north ) - ((r ^. robotDisplay) & invisible .~ False) + ( defaultRobotDisplay + & inherit displayAttr (r ^. robotDisplay) + ) (In cmd e s [FExec]) [] [] diff --git a/src/swarm-util/Swarm/Util/Lens.hs b/src/swarm-util/Swarm/Util/Lens.hs index 19f5659aa..e9230252f 100644 --- a/src/swarm-util/Swarm/Util/Lens.hs +++ b/src/swarm-util/Swarm/Util/Lens.hs @@ -5,9 +5,11 @@ module Swarm.Util.Lens ( makeLensesNoSigs, makeLensesExcluding, + inherit, ) where import Control.Lens ( + Lens', generateSignatures, lensField, lensRules, @@ -16,6 +18,7 @@ import Control.Lens ( (%~), (&), (.~), + (^.), ) import Language.Haskell.TH (DecsQ) import Language.Haskell.TH.Syntax (Name) @@ -40,3 +43,7 @@ makeLensesExcluding exclude = & lensField . mapped . mapped %~ \fn n -> if n `elem` exclude then [] else fn n ) + +-- | Copy a given field from one record to another. +inherit :: Lens' s a -> s -> (s -> s) +inherit field parent child = child & field .~ (parent ^. field)