swarm-0.2.0.0: 2D resource gathering game with programmable robots
CopyrightBrent Yorgey
LicenseBSD-3-Clause
Maintainerbyorgey@gmail.com
Safe HaskellSafe-Inferred
LanguageHaskell2010

Swarm.TUI.Model

Description

Application state for the brick-based Swarm TUI.

Synopsis

Custom UI label types

These types are used as parameters to various brick types.

data AppEvent Source #

AppEvent represents a type for custom event types our app can receive. At the moment, we only have one custom event, but it's very important: a separate thread sends Frame events as fast as it can, telling the TUI to render a new frame.

Instances

Instances details
Show AppEvent Source # 
Instance details

Defined in Swarm.TUI.Model

data Name Source #

Name represents names to uniquely identify various components of the UI, such as forms, panels, caches, extents, and lists.

Constructors

REPLPanel

The panel containing the REPL.

WorldPanel

The panel containing the world view.

RobotPanel

The panel showing robot info and inventory on the top left.

InfoPanel

The info panel on the bottom left.

REPLInput

The REPL input form.

WorldCache

The render cache for the world view.

WorldExtent

The cached extent for the world view.

InventoryList

The list of inventory items for the currently focused robot.

InventoryListItem Int

The inventory item position in the InventoryList.

MenuList

The list of main menu choices.

ScenarioList

The list of scenario choices.

InfoViewport

The scrollable viewport for the info panel.

ModalViewport

The scrollable viewport for any modal dialog.

Instances

Instances details
Read Name Source # 
Instance details

Defined in Swarm.TUI.Model

Show Name Source # 
Instance details

Defined in Swarm.TUI.Model

Methods

showsPrec :: Int -> Name -> ShowS #

show :: Name -> String #

showList :: [Name] -> ShowS #

Eq Name Source # 
Instance details

Defined in Swarm.TUI.Model

Methods

(==) :: Name -> Name -> Bool #

(/=) :: Name -> Name -> Bool #

Ord Name Source # 
Instance details

Defined in Swarm.TUI.Model

Methods

compare :: Name -> Name -> Ordering #

(<) :: Name -> Name -> Bool #

(<=) :: Name -> Name -> Bool #

(>) :: Name -> Name -> Bool #

(>=) :: Name -> Name -> Bool #

max :: Name -> Name -> Name #

min :: Name -> Name -> Name #

Menus and dialogs

data MainMenuEntry Source #

Constructors

NewGame 
Tutorial 
Messages 
About 
Quit 

Instances

Instances details
Bounded MainMenuEntry Source # 
Instance details

Defined in Swarm.TUI.Model

Enum MainMenuEntry Source # 
Instance details

Defined in Swarm.TUI.Model

Read MainMenuEntry Source # 
Instance details

Defined in Swarm.TUI.Model

Show MainMenuEntry Source # 
Instance details

Defined in Swarm.TUI.Model

Eq MainMenuEntry Source # 
Instance details

Defined in Swarm.TUI.Model

Ord MainMenuEntry Source # 
Instance details

Defined in Swarm.TUI.Model

mkScenarioList :: Bool -> ScenarioCollection -> List Name ScenarioItem Source #

Create a brick List of scenario items from a ScenarioCollection.

mkNewGameMenu :: Bool -> ScenarioCollection -> FilePath -> Maybe Menu Source #

Given a ScenarioCollection and a FilePath which is the canonical path to some folder or scenario, construct a NewGameMenu stack focused on the given item, if possible.

UI state

REPL

data REPLHistItem Source #

An item in the REPL history.

Constructors

REPLEntry Text

Something entered by the user.

REPLOutput Text

A response printed by the system.

replItemText :: REPLHistItem -> Text Source #

Get the text of REPL input/output.

isREPLEntry :: REPLHistItem -> Bool Source #

Useful helper function to filter out REPL output.

getREPLEntry :: REPLHistItem -> Maybe Text Source #

Useful helper function to only get user input text.

data REPLHistory Source #

History of the REPL with indices (0 is first entry) to the current line and to the first entry since loading saved history. We also (ab)use the length of the REPL as the index of current input line, since that number is one past the index of last entry.

replIndex :: Lens' REPLHistory Int Source #

The current index in the REPL history (if the user is going back through the history using up/down keys).

replLength :: REPLHistory -> Int Source #

Current number lines of the REPL history - (ab)used as index of input buffer.

replSeq :: Lens' REPLHistory (Seq REPLHistItem) Source #

Sequence of REPL inputs and outputs, oldest entry is leftmost.

newREPLHistory :: [REPLHistItem] -> REPLHistory Source #

Create new REPL history (i.e. from loaded history file lines).

addREPLItem :: REPLHistItem -> REPLHistory -> REPLHistory Source #

Add new REPL input - the index must have been pointing one past the last element already, so we increment it to keep it that way.

restartREPLHistory :: REPLHistory -> REPLHistory Source #

Point the start of REPL history after current last line. See replStart.

getLatestREPLHistoryItems :: Int -> REPLHistory -> [REPLHistItem] Source #

Get the latest N items in history, starting with the oldest one.

This is used to show previous REPL lines in UI, so we need the items sorted in the order they were entered and will be drawn top to bottom.

data TimeDir Source #

Constructors

Newer 
Older 

Instances

Instances details
Show TimeDir Source # 
Instance details

Defined in Swarm.TUI.Model

Eq TimeDir Source # 
Instance details

Defined in Swarm.TUI.Model

Methods

(==) :: TimeDir -> TimeDir -> Bool #

(/=) :: TimeDir -> TimeDir -> Bool #

Ord TimeDir Source # 
Instance details

Defined in Swarm.TUI.Model

Prompt utils

data REPLPrompt Source #

This data type tells us how to interpret the text typed by the player at the prompt (which is stored in Editor).

Constructors

CmdPrompt [Text]

Interpret the prompt text as a regular command. The list is for potential completions, which we can cycle through by hitting Tab repeatedly

SearchPrompt REPLHistory

Interpret the prompt text as "search this text in history"

removeEntry :: Text -> REPLHistory -> REPLHistory Source #

Given some text, removes the REPLEntry within REPLHistory which is equal to that. This is used when the user enters in search mode and want to traverse the history. If a command has been used many times, the history will be populated with it causing the effect that search command always finds the same command.

Inventory

data InventoryListEntry Source #

An entry in the inventory list displayed in the info panel. We can either have an entity with a count in the robot's inventory, an entity installed on the robot, or a labelled separator. The purpose of the separators is to show a clear distinction between the robot's inventory and its installed devices.

Instances

Instances details
Eq InventoryListEntry Source # 
Instance details

Defined in Swarm.TUI.Model

UI Model

data UIState Source #

The main record holding the UI state. For access to the fields, see the lenses below.

uiMenu :: Lens' UIState Menu Source #

The current menu state.

uiPlaying :: Lens' UIState Bool Source #

Are we currently playing the game? True = we are playing, and should thus display a world, REPL, etc.; False = we should display the current menu.

uiCheatMode :: Lens' UIState Bool Source #

Cheat mode, i.e. are we allowed to turn creative mode on and off?

uiFocusRing :: Lens' UIState (FocusRing Name) Source #

The focus ring is the set of UI panels we can cycle among using the Tab key.

uiWorldCursor :: Lens' UIState (Maybe Coords) Source #

The last clicked position on the world view.

uiREPL :: Lens' UIState REPLState Source #

The state of REPL panel.

uiInventory :: Lens' UIState (Maybe (Int, List Name InventoryListEntry)) Source #

The hash value of the focused robot entity (so we can tell if its inventory changed) along with a list of the items in the focused robot's inventory.

uiInventorySort :: Lens' UIState InventorySortOptions Source #

The order and direction of sorting inventory list.

uiMoreInfoTop :: Lens' UIState Bool Source #

Does the info panel contain more content past the top of the panel?

uiMoreInfoBot :: Lens' UIState Bool Source #

Does the info panel contain more content past the bottom of the panel?

uiScrollToEnd :: Lens' UIState Bool Source #

A flag telling the UI to scroll the info panel to the very end (used when a new log message is appended).

uiError :: Lens' UIState (Maybe Text) Source #

When this is Just, it represents a popup box containing an error message that is shown on top of the rest of the UI.

uiModal :: Lens' UIState (Maybe Modal) Source #

When this is Just, it represents a modal to be displayed on top of the UI, e.g. for the Help screen.

uiGoal :: Lens' UIState (Maybe [Text]) Source #

Status of the scenario goal: whether there is one, and whether it has been displayed to the user initially.

lgTicksPerSecond :: Lens' UIState Int Source #

The base-2 logarithm of the current game speed in ticks/second. Note that we cap this value to the range of +/- log2 INTMAX.

lastFrameTime :: Lens' UIState TimeSpec Source #

The time of the last Frame event.

accumulatedTime :: Lens' UIState TimeSpec Source #

The amount of accumulated real time. Every time we get a Frame event, we accumulate the amount of real time that happened since the last frame, then attempt to take an appropriate number of ticks to "catch up", based on the target tick rate.

See https://gafferongames.com/post/fix_your_timestep/ .

tickCount :: Lens' UIState Int Source #

A counter used to track how many ticks have happened since the last time we updated the ticks/frame statistics.

frameCount :: Lens' UIState Int Source #

A counter used to track how many frames have been rendered since the last time we updated the ticks/frame statistics.

frameTickCount :: Lens' UIState Int Source #

A counter used to track how many ticks have happened in the current frame, so we can stop when we get to the tick cap.

lastInfoTime :: Lens' UIState TimeSpec Source #

The time of the last info widget update

uiShowFPS :: Lens' UIState Bool Source #

A toggle to show the FPS by pressing f

uiShowZero :: Lens' UIState Bool Source #

A toggle to show or hide inventory items with count 0 by pressing `0`

uiShowRobots :: Getter UIState Bool Source #

Whether to show or hide robots on the world map.

uiHideRobotsUntil :: Lens' UIState TimeSpec Source #

Hide robots on the world map.

uiInventoryShouldUpdate :: Lens' UIState Bool Source #

Whether the Inventory ui panel should update

uiTPF :: Lens' UIState Double Source #

Computed ticks per milli seconds

uiFPS :: Lens' UIState Double Source #

Computed frames per milli seconds

scenarioRef :: Lens' UIState (Maybe ScenarioInfoPair) Source #

The currently active Scenario description, useful for starting over.

appData :: Lens' UIState (Map Text Text) Source #

Free-form data loaded from the data directory, for things like the logo, about page, tutorial story, etc.

REPL Panel Model

replPromptType :: Lens' REPLState REPLPrompt Source #

The way we interpret text typed by the player in the REPL prompt.

replPromptEditor :: Lens' REPLState (Editor Text Name) Source #

The prompt where the user can type input at the REPL.

replPromptText :: Lens' REPLState Text Source #

Convinience lens to get text from editor and replace it with new one that has the provided text.

replValid :: Lens' REPLState Bool Source #

Whether the prompt text is a valid Term.

replLast :: Lens' REPLState Text Source #

The last thing the user has typed which isn't part of the history. This is used to restore the repl form after the user visited the history.

replType :: Lens' REPLState (Maybe Polytype) Source #

The type of the current REPL input which should be displayed to the user (if any).

replHistory :: Lens' REPLState REPLHistory Source #

History of things the user has typed at the REPL, interleaved with outputs the system has generated.

Initialization

initFocusRing :: FocusRing Name Source #

The initial state of the focus ring.

initLgTicksPerSecond :: Int Source #

The initial tick speed.

initUIState :: Bool -> Bool -> ExceptT Text IO UIState Source #

Initialize the UI state. This needs to be in the IO monad since it involves reading a REPL history file, getting the current time, and loading text files from the data directory. The Bool parameter indicates whether we should start off by showing the main menu.

lastEntry :: Text -> REPLHistory -> Maybe Text Source #

Get the last REPLEntry in REPLHistory matching the given text

Updating

populateInventoryList :: MonadState UIState m => Maybe Robot -> m () Source #

Given the focused robot, populate the UI inventory list in the info panel with information about its inventory.

Runtime state

webPort :: Lens' RuntimeState (Maybe Port) Source #

The port on which the HTTP debug service is running.

eventLog :: Lens' RuntimeState (Notifications LogEntry) Source #

A log of runtime events.

This logging is separate from the logging done during game-play. If some error happens before a game is even selected, this is the place to log it.

logEvent :: LogSource -> (Text, RID) -> Text -> Notifications LogEntry -> Notifications LogEntry Source #

Simply log to the runtime event log.

App state

data AppState Source #

The AppState just stores together the other states.

This is so you can use a smaller state when e.g. writing some game logic or updating the UI. Also consider that GameState can change when loading a new scenario - if the state should persist games, use RuntimeState.

Initialization

data AppOpts Source #

Command-line options for configuring the app.

Constructors

AppOpts 

Fields

startGame :: (MonadIO m, MonadState AppState m) => ScenarioInfoPair -> Maybe CodeToRun -> m () Source #

Load a Scenario and start playing the game.

restartGame :: (MonadIO m, MonadState AppState m) => Seed -> ScenarioInfoPair -> m () Source #

Re-initialize the game from the stored reference to the current scenario.

Note that "restarting" is intended only for "scenarios"; with some scenarios, it may be possible to get stuck so that it is either impossible or very annoying to win, so being offered an option to restart is more user-friendly.

Since scenarios are stored as a Maybe in the UI state, we handle the Nothing case upstream so that the Scenario passed to this function definitely exists.

scenarioToAppState :: (MonadIO m, MonadState AppState m) => ScenarioInfoPair -> Maybe Seed -> Maybe CodeToRun -> m () Source #

Modify the AppState appropriately when starting a new scenario.

type Seed = Int Source #

Utility

topContext :: AppState -> RobotContext Source #

Context for the REPL commands to execute in. Contains the base robot context plus the it variable that refer to the previously computed values. (Note that `it{n}` variables are set in the base robot context; we only set it here because it's so transient)

focusedItem :: AppState -> Maybe InventoryListEntry Source #

Get the currently focused InventoryListEntry from the robot info panel (if any).

focusedEntity :: AppState -> Maybe Entity Source #

Get the currently focused entity from the robot info panel (if any). This is just like focusedItem but forgets the distinction between plain inventory items and installed devices.

nextScenario :: Menu -> Maybe ScenarioInfoPair Source #

Extract the scenario which would come next in the menu from the currently selected scenario (if any). Can return Nothing if either we are not in the NewGameMenu, or the current scenario is the last among its siblings.