Skip to content

Commit

Permalink
Use rich entity modification info (#1604)
Browse files Browse the repository at this point in the history
This is a refactoring that is a prerequisite for both #1579 and #1595.
  • Loading branch information
kostmo authored Oct 29, 2023
1 parent d3889ef commit 3a39873
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 12 deletions.
14 changes: 7 additions & 7 deletions src/Swarm/Game/Step/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import Control.Effect.Error
import Control.Effect.Lens
import Control.Effect.Lift
import Control.Lens as Lens hiding (Const, distrib, from, parts, use, uses, view, (%=), (+=), (.=), (<+=), (<>=))
import Control.Monad (forM, guard, join, when)
import Control.Monad (forM, forM_, guard, join, when)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
import Data.Array (bounds, (!))
import Data.IntMap qualified as IM
import Data.List (find)
import Data.Map qualified as M
import Data.Maybe (fromMaybe)
import Data.Set qualified as S
import Data.Text (Text)
import Data.Text qualified as T
Expand All @@ -33,6 +32,7 @@ import Swarm.Game.Robot
import Swarm.Game.State
import Swarm.Game.Universe
import Swarm.Game.World qualified as W
import Swarm.Game.World.Modify qualified as WM
import Swarm.Language.Capability
import Swarm.Language.Requirement qualified as R
import Swarm.Language.Syntax
Expand Down Expand Up @@ -68,11 +68,11 @@ updateEntityAt ::
(Maybe Entity -> Maybe Entity) ->
m ()
updateEntityAt cLoc@(Cosmic subworldName loc) upd = do
didChange <-
fmap (fromMaybe False) $
zoomWorld subworldName $
W.updateM @Int (W.locToCoords loc) upd
when didChange $
someChange <-
zoomWorld subworldName $
W.updateM @Int (W.locToCoords loc) upd

forM_ (WM.getModification =<< someChange) $ \_modType -> do
wakeWatchingRobots cLoc

-- * Capabilities
Expand Down
10 changes: 5 additions & 5 deletions src/Swarm/Game/World.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,18 @@ import Data.Array.Unboxed qualified as U
import Data.Bifunctor (second)
import Data.Bits
import Data.Foldable (foldl')
import Data.Function (on)
import Data.Int (Int32)
import Data.Map (Map)
import Data.Map.Strict qualified as M
import Data.Semigroup (Last (..))
import Data.Yaml (FromJSON, ToJSON)
import GHC.Generics (Generic)
import Swarm.Game.Entity (Entity, entityHash)
import Swarm.Game.Entity (Entity)
import Swarm.Game.Location
import Swarm.Game.Terrain (TerrainType (BlankT))
import Swarm.Game.Universe
import Swarm.Game.World.Coords
import Swarm.Game.World.Modify
import Swarm.Util ((?))
import Swarm.Util.Erasable
import Prelude hiding (lookup)
Expand Down Expand Up @@ -265,9 +265,9 @@ update ::
Coords ->
(Maybe Entity -> Maybe Entity) ->
World t Entity ->
(World t Entity, Bool)
(World t Entity, CellUpdate Entity)
update i g w@(World f t m) =
(wNew, ((/=) `on` fmap (view entityHash)) entityAfter entityBefore)
(wNew, classifyModification entityBefore entityAfter)
where
wNew = World f t $ M.insert i entityAfter m
entityBefore = lookupEntity i w
Expand All @@ -280,7 +280,7 @@ updateM ::
(Has (State (World t Entity)) sig m, IArray U.UArray t) =>
Coords ->
(Maybe Entity -> Maybe Entity) ->
m Bool
m (CellUpdate Entity)
updateM c g = do
state @(World t Entity) $ update c g . loadCell c

Expand Down
40 changes: 40 additions & 0 deletions src/Swarm/Game/World/Modify.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Captures the various possibilities of cell
-- modification as a sum type for use by the structure recognizer
-- (see 'Swarm.Game.Scenario.Topography.Structure.Recognition.Tracking.entityModified').
module Swarm.Game.World.Modify where

import Control.Lens (view)
import Data.Function (on)
import Swarm.Game.Entity (Entity, entityHash)

-- | Compare to 'WorldUpdate' in "Swarm.Game.World"
data CellUpdate e
= NoChange (Maybe e)
| Modified (CellModification e)

getModification :: CellUpdate e -> Maybe (CellModification e)
getModification (NoChange _) = Nothing
getModification (Modified x) = Just x

data CellModification e
= -- | Fields represent what existed in the cell "before" and "after", in that order.
Swap e e
| Remove e
| Add e

classifyModification ::
-- | before
Maybe Entity ->
-- | after
Maybe Entity ->
CellUpdate Entity
classifyModification Nothing Nothing = NoChange Nothing
classifyModification Nothing (Just x) = Modified $ Add x
classifyModification (Just x) Nothing = Modified $ Remove x
classifyModification (Just x) (Just y) =
if ((/=) `on` view entityHash) x y
then Modified $ Swap x y
else NoChange $ Just x
1 change: 1 addition & 0 deletions swarm.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ library
Swarm.Game.World.Gen
Swarm.Game.World.Interpret
Swarm.Game.World.Load
Swarm.Game.World.Modify
Swarm.Game.World.Parse
Swarm.Game.World.Render
Swarm.Game.World.Syntax
Expand Down

0 comments on commit 3a39873

Please sign in to comment.