Skip to content

Commit aacdbf3

Browse files
authored
Remove Benchmark dependence on AppState and TUI (#1746)
`stack bench` is now independent of the TUI and `AppState`.
1 parent 6691633 commit aacdbf3

File tree

14 files changed

+181
-138
lines changed

14 files changed

+181
-138
lines changed

app/Swarm/App.hs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import Data.Text.IO qualified as T
2525
import Graphics.Vty qualified as V
2626
import Graphics.Vty.CrossPlatform qualified as V
2727
import Swarm.Game.Failure (SystemFailure)
28+
import Swarm.Game.State.Runtime
2829
import Swarm.Language.Pretty (prettyText)
2930
import Swarm.Log (LogSource (SystemLog), Severity (..))
3031
import Swarm.TUI.Controller

scripts/benchmark-against-parent.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fi
1616
BASELINE_OUTPUT=baseline.csv
1717

1818
git checkout HEAD~
19-
stack bench --benchmark-arguments "--csv $BASELINE_OUTPUT --color always"
19+
STACK_WORK=.stack-work-bench stack bench swarm:benchmark --benchmark-arguments "--csv $BASELINE_OUTPUT --color always"
2020

2121
git switch -
22-
stack bench --benchmark-arguments "--baseline $BASELINE_OUTPUT --fail-if-slower 3 --color always"
22+
STACK_WORK=.stack-work-bench stack bench swarm:benchmark --benchmark-arguments "--baseline $BASELINE_OUTPUT --fail-if-slower 3 --color always"

src/Swarm/TUI/Controller.hs

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ import Swarm.Game.Scenario.Topography.Structure.Recognition.Type (originalStruct
8585
import Swarm.Game.ScenarioInfo
8686
import Swarm.Game.State
8787
import Swarm.Game.State.Robot
88+
import Swarm.Game.State.Runtime
8889
import Swarm.Game.State.Substate
8990
import Swarm.Game.Step (finishGameTick, gameTick)
9091
import Swarm.Language.Capability (Capability (CDebug, CGod, CMake), constCaps)

src/Swarm/TUI/Model.hs

+3-117
Original file line numberDiff line numberDiff line change
@@ -80,21 +80,8 @@ module Swarm.TUI.Model (
8080
modalScroll,
8181
replScroll,
8282

83-
-- * Runtime state
84-
RuntimeState,
85-
webPort,
86-
upstreamRelease,
87-
eventLog,
88-
worlds,
89-
scenarios,
90-
stdEntityMap,
91-
stdRecipes,
92-
appData,
93-
nameParts,
94-
9583
-- ** Utility
9684
logEvent,
97-
mkGameStateConfig,
9885

9986
-- * App state
10087
AppState (AppState),
@@ -115,49 +102,39 @@ module Swarm.TUI.Model (
115102
focusedItem,
116103
focusedEntity,
117104
nextScenario,
118-
initRuntimeState,
119105
) where
120106

121107
import Brick
122108
import Brick.Widgets.List qualified as BL
123-
import Control.Effect.Accum
124-
import Control.Effect.Lift
125-
import Control.Effect.Throw
126109
import Control.Lens hiding (from, (<.>))
127110
import Control.Monad ((>=>))
128111
import Control.Monad.State (MonadState)
129112
import Data.List (findIndex)
130113
import Data.List.NonEmpty (NonEmpty (..))
131-
import Data.Map (Map)
132114
import Data.Maybe (fromMaybe)
133-
import Data.Sequence (Seq)
134115
import Data.Text (Text)
135116
import Data.Vector qualified as V
136117
import GitHash (GitInfo)
137118
import Graphics.Vty (ColorMode (..))
138119
import Network.Wai.Handler.Warp (Port)
139120
import Swarm.Game.Entity as E
140-
import Swarm.Game.Failure
141-
import Swarm.Game.Recipe (Recipe, loadRecipes)
142-
import Swarm.Game.ResourceLoading (NameGenerator, initNameGenerator, readAppData)
143121
import Swarm.Game.Robot
144122
import Swarm.Game.Robot.Concrete
145123
import Swarm.Game.Robot.Context
146124
import Swarm.Game.Scenario.Status
147-
import Swarm.Game.ScenarioInfo (ScenarioCollection, loadScenarios, _SISingle)
125+
import Swarm.Game.ScenarioInfo (_SISingle)
148126
import Swarm.Game.State
127+
import Swarm.Game.State.Runtime
149128
import Swarm.Game.State.Substate
150129
import Swarm.Game.Tick (TickNumber (..))
151-
import Swarm.Game.World.Load (loadWorlds)
152-
import Swarm.Game.World.Typecheck (WorldMap)
153130
import Swarm.Log
154131
import Swarm.TUI.Inventory.Sorting
155132
import Swarm.TUI.Model.Menu
156133
import Swarm.TUI.Model.Name
157134
import Swarm.TUI.Model.Repl
158135
import Swarm.TUI.Model.UI
159136
import Swarm.Util.Lens (makeLensesNoSigs)
160-
import Swarm.Version (NewReleaseFailure (NoMainUpstreamRelease))
137+
import Swarm.Version (NewReleaseFailure)
161138
import Text.Fuzzy qualified as Fuzzy
162139

163140
------------------------------------------------------------
@@ -188,87 +165,6 @@ modalScroll = viewportScroll ModalViewport
188165
replScroll :: ViewportScroll Name
189166
replScroll = viewportScroll REPLViewport
190167

191-
-- ----------------------------------------------------------------------------
192-
-- Runtime state --
193-
-- ----------------------------------------------------------------------------
194-
195-
data RuntimeState = RuntimeState
196-
{ _webPort :: Maybe Port
197-
, _upstreamRelease :: Either NewReleaseFailure String
198-
, _eventLog :: Notifications LogEntry
199-
, _worlds :: WorldMap
200-
, _scenarios :: ScenarioCollection
201-
, _stdEntityMap :: EntityMap
202-
, _stdRecipes :: [Recipe Entity]
203-
, _appData :: Map Text Text
204-
, _nameParts :: NameGenerator
205-
}
206-
207-
initRuntimeState ::
208-
( Has (Throw SystemFailure) sig m
209-
, Has (Accum (Seq SystemFailure)) sig m
210-
, Has (Lift IO) sig m
211-
) =>
212-
m RuntimeState
213-
initRuntimeState = do
214-
entities <- loadEntities
215-
recipes <- loadRecipes entities
216-
worlds <- loadWorlds entities
217-
scenarios <- loadScenarios entities worlds
218-
appDataMap <- readAppData
219-
nameGen <- initNameGenerator appDataMap
220-
return $
221-
RuntimeState
222-
{ _webPort = Nothing
223-
, _upstreamRelease = Left (NoMainUpstreamRelease [])
224-
, _eventLog = mempty
225-
, _worlds = worlds
226-
, _scenarios = scenarios
227-
, _stdEntityMap = entities
228-
, _stdRecipes = recipes
229-
, _appData = appDataMap
230-
, _nameParts = nameGen
231-
}
232-
233-
makeLensesNoSigs ''RuntimeState
234-
235-
-- | The port on which the HTTP debug service is running.
236-
webPort :: Lens' RuntimeState (Maybe Port)
237-
238-
-- | The upstream release version.
239-
upstreamRelease :: Lens' RuntimeState (Either NewReleaseFailure String)
240-
241-
-- | A log of runtime events.
242-
--
243-
-- This logging is separate from the logging done during game-play.
244-
-- If some error happens before a game is even selected, this is the
245-
-- place to log it.
246-
eventLog :: Lens' RuntimeState (Notifications LogEntry)
247-
248-
-- | A collection of typechecked world DSL terms that are available to
249-
-- be used in scenario definitions.
250-
worlds :: Lens' RuntimeState WorldMap
251-
252-
-- | The collection of scenarios that comes with the game.
253-
scenarios :: Lens' RuntimeState ScenarioCollection
254-
255-
-- | The standard entity map loaded from disk. Individual scenarios
256-
-- may define additional entities which will get added to this map
257-
-- when loading the scenario.
258-
stdEntityMap :: Lens' RuntimeState EntityMap
259-
260-
-- | The standard list of recipes loaded from disk. Individual scenarios
261-
-- may define additional recipes which will get added to this list
262-
-- when loading the scenario.
263-
stdRecipes :: Lens' RuntimeState [Recipe Entity]
264-
265-
-- | Free-form data loaded from the @data@ directory, for things like
266-
-- the logo, about page, tutorial story, etc.
267-
appData :: Lens' RuntimeState (Map Text Text)
268-
269-
-- | Lists of words/adjectives for use in building random robot names.
270-
nameParts :: Lens' RuntimeState NameGenerator
271-
272168
--------------------------------------------------
273169
-- Utility
274170

@@ -281,16 +177,6 @@ logEvent src sev who msg el =
281177
where
282178
l = LogEntry (TickNumber 0) src sev who msg
283179

284-
-- | Create a 'GameStateConfig' record from the 'RuntimeState'.
285-
mkGameStateConfig :: RuntimeState -> GameStateConfig
286-
mkGameStateConfig rs =
287-
GameStateConfig
288-
{ initNameParts = rs ^. nameParts
289-
, initEntities = rs ^. stdEntityMap
290-
, initRecipes = rs ^. stdRecipes
291-
, initWorldMap = rs ^. worlds
292-
}
293-
294180
-- ----------------------------------------------------------------------------
295181
-- APPSTATE --
296182
-- ----------------------------------------------------------------------------

src/Swarm/TUI/Model/StateUpdate.hs

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import Swarm.Game.ScenarioInfo (
6060
_SISingle,
6161
)
6262
import Swarm.Game.State
63+
import Swarm.Game.State.Runtime
6364
import Swarm.Game.State.Substate
6465
import Swarm.Language.Pretty (prettyText)
6566
import Swarm.Log (LogSource (SystemLog), Severity (..))

src/Swarm/TUI/View.hs

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import Swarm.Game.ScenarioInfo (
103103
)
104104
import Swarm.Game.State
105105
import Swarm.Game.State.Robot
106+
import Swarm.Game.State.Runtime
106107
import Swarm.Game.State.Substate
107108
import Swarm.Game.Tick (TickNumber (..), addTicks)
108109
import Swarm.Game.Universe

src/swarm-engine/Swarm/Game/State.hs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ module Swarm.Game.State (
3535
-- ** GameState initialization
3636
initGameState,
3737
scenarioToGameState,
38+
pureScenarioToGameState,
3839
CodeToRun (..),
3940
Sha1 (..),
4041
SolutionSource (..),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
{-# LANGUAGE TemplateHaskell #-}
2+
3+
-- |
4+
-- SPDX-License-Identifier: BSD-3-Clause
5+
--
6+
-- Runtime state and utility functions
7+
module Swarm.Game.State.Runtime (
8+
RuntimeState,
9+
10+
-- ** Lenses
11+
webPort,
12+
upstreamRelease,
13+
eventLog,
14+
worlds,
15+
scenarios,
16+
stdEntityMap,
17+
stdRecipes,
18+
appData,
19+
nameParts,
20+
21+
-- ** Utility
22+
initRuntimeState,
23+
mkGameStateConfig,
24+
)
25+
where
26+
27+
import Control.Effect.Accum
28+
import Control.Effect.Lift
29+
import Control.Effect.Throw
30+
import Control.Lens
31+
import Data.Map (Map)
32+
import Data.Sequence (Seq)
33+
import Data.Text (Text)
34+
import Network.Wai.Handler.Warp (Port)
35+
import Swarm.Game.Entity (Entity, EntityMap, loadEntities)
36+
import Swarm.Game.Failure (SystemFailure)
37+
import Swarm.Game.Recipe (Recipe, loadRecipes)
38+
import Swarm.Game.ResourceLoading (NameGenerator, initNameGenerator, readAppData)
39+
import Swarm.Game.ScenarioInfo (ScenarioCollection, loadScenarios)
40+
import Swarm.Game.State.Substate
41+
import Swarm.Game.World.Load (loadWorlds)
42+
import Swarm.Game.World.Typecheck (WorldMap)
43+
import Swarm.Log
44+
import Swarm.Util.Lens (makeLensesNoSigs)
45+
import Swarm.Version (NewReleaseFailure (..))
46+
47+
data RuntimeState = RuntimeState
48+
{ _webPort :: Maybe Port
49+
, _upstreamRelease :: Either NewReleaseFailure String
50+
, _eventLog :: Notifications LogEntry
51+
, _worlds :: WorldMap
52+
, _scenarios :: ScenarioCollection
53+
, _stdEntityMap :: EntityMap
54+
, _stdRecipes :: [Recipe Entity]
55+
, _appData :: Map Text Text
56+
, _nameParts :: NameGenerator
57+
}
58+
59+
initRuntimeState ::
60+
( Has (Throw SystemFailure) sig m
61+
, Has (Accum (Seq SystemFailure)) sig m
62+
, Has (Lift IO) sig m
63+
) =>
64+
m RuntimeState
65+
initRuntimeState = do
66+
entities <- loadEntities
67+
recipes <- loadRecipes entities
68+
worlds <- loadWorlds entities
69+
scenarios <- loadScenarios entities worlds
70+
appDataMap <- readAppData
71+
nameGen <- initNameGenerator appDataMap
72+
return $
73+
RuntimeState
74+
{ _webPort = Nothing
75+
, _upstreamRelease = Left (NoMainUpstreamRelease [])
76+
, _eventLog = mempty
77+
, _worlds = worlds
78+
, _scenarios = scenarios
79+
, _stdEntityMap = entities
80+
, _stdRecipes = recipes
81+
, _appData = appDataMap
82+
, _nameParts = nameGen
83+
}
84+
85+
makeLensesNoSigs ''RuntimeState
86+
87+
-- | The port on which the HTTP debug service is running.
88+
webPort :: Lens' RuntimeState (Maybe Port)
89+
90+
-- | The upstream release version.
91+
upstreamRelease :: Lens' RuntimeState (Either NewReleaseFailure String)
92+
93+
-- | A log of runtime events.
94+
--
95+
-- This logging is separate from the logging done during game-play.
96+
-- If some error happens before a game is even selected, this is the
97+
-- place to log it.
98+
eventLog :: Lens' RuntimeState (Notifications LogEntry)
99+
100+
-- | A collection of typechecked world DSL terms that are available to
101+
-- be used in scenario definitions.
102+
worlds :: Lens' RuntimeState WorldMap
103+
104+
-- | The collection of scenarios that comes with the game.
105+
scenarios :: Lens' RuntimeState ScenarioCollection
106+
107+
-- | The standard entity map loaded from disk. Individual scenarios
108+
-- may define additional entities which will get added to this map
109+
-- when loading the scenario.
110+
stdEntityMap :: Lens' RuntimeState EntityMap
111+
112+
-- | The standard list of recipes loaded from disk. Individual scenarios
113+
-- may define additional recipes which will get added to this list
114+
-- when loading the scenario.
115+
stdRecipes :: Lens' RuntimeState [Recipe Entity]
116+
117+
-- | Free-form data loaded from the @data@ directory, for things like
118+
-- the logo, about page, tutorial story, etc.
119+
appData :: Lens' RuntimeState (Map Text Text)
120+
121+
-- | Lists of words/adjectives for use in building random robot names.
122+
nameParts :: Lens' RuntimeState NameGenerator
123+
124+
-- | Create a 'GameStateConfig' record from the 'RuntimeState'.
125+
mkGameStateConfig :: RuntimeState -> GameStateConfig
126+
mkGameStateConfig rs =
127+
GameStateConfig
128+
{ initNameParts = rs ^. nameParts
129+
, initEntities = rs ^. stdEntityMap
130+
, initRecipes = rs ^. stdRecipes
131+
, initWorldMap = rs ^. worlds
132+
}
File renamed without changes.

0 commit comments

Comments
 (0)