Skip to content

Commit

Permalink
disambiguate doc links, elaborate waypoint ordering (#1531)
Browse files Browse the repository at this point in the history
Towards #1366

Cleans up many Haddock warnings.
  • Loading branch information
kostmo authored Sep 17, 2023
1 parent b329a43 commit ab7e5b6
Show file tree
Hide file tree
Showing 27 changed files with 139 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/Swarm/Doc/Gen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ data GenerateDocs where
RecipeGraph :: GenerateDocs
-- | Keyword lists for editors.
EditorKeywords :: Maybe EditorType -> GenerateDocs
-- | List of special key names recognized by 'key' command
-- | List of special key names recognized by 'Swarm.Language.Syntax.Key' command
SpecialKeyNames :: GenerateDocs
-- | Cheat sheets for inclusion on the Swarm wiki.
CheatSheet :: PageAddress -> Maybe SheetType -> GenerateDocs
Expand Down
8 changes: 4 additions & 4 deletions src/Swarm/Game/Exception.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import Witch (from)
-- | Suggested way to fix things when a robot does not meet the
-- requirements to run a command.
data IncapableFix
= -- | Equip the missing device on yourself/target
= -- | 'Swarm.Language.Syntax.Equip' the missing device on yourself/target
FixByEquip
| -- | Add the missing device to your inventory
FixByObtain
Expand All @@ -72,11 +72,11 @@ data Exn
-- term that caused the problem, and a suggestion for how to fix
-- things.
Incapable IncapableFix Requirements Term
| -- | A command failed in some "normal" way (/e.g./ a 'Move'
-- command could not move, or a 'Grab' command found nothing to
| -- | A command failed in some "normal" way (/e.g./ a 'Swarm.Language.Syntax.Move'
-- command could not move, or a 'Swarm.Language.Syntax.Grab' command found nothing to
-- grab, /etc./). Can be caught by a @try@ block.
CmdFailed Const Text (Maybe GameplayAchievement)
| -- | The user program explicitly called 'Undefined' or 'Fail'. Can
| -- | The user program explicitly called 'Swarm.Language.Syntax.Undefined' or 'Swarm.Language.Syntax.Fail'. Can
-- be caught by a @try@ block.
User Text
deriving (Eq, Show, Generic, FromJSON, ToJSON)
Expand Down
12 changes: 6 additions & 6 deletions src/Swarm/Game/Location.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,17 @@ import Swarm.Util qualified as Util
-- >>> import Linear
-- >>> import Swarm.Language.Direction

-- | A Location is a pair of (x,y) coordinates, both up to 32 bits.
-- | A t'Location' is a pair of @(x,y)@ coordinates, both up to 32 bits.
-- The positive x-axis points east and the positive y-axis points
-- north. These are the coordinates that are shown to players.
--
-- See also the 'Swarm.Game.World.Coords' type defined in "Swarm.Game.World", which
-- use a (row, column) format instead, which is more convenient for
-- internal use. The "Swarm.Game.World" module also defines
-- conversions between 'Location' and 'Swarm.Game.World.Coords'.
-- conversions between t'Location' and 'Swarm.Game.World.Coords'.
type Location = Point V2 Int32

-- | A convenient way to pattern-match on 'Location' values.
-- | A convenient way to pattern-match on t'Location' values.
pattern Location :: Int32 -> Int32 -> Location
pattern Location x y = P (V2 x y)

Expand All @@ -76,13 +76,13 @@ instance ToJSON Location where

-- | A @Heading@ is a 2D vector, with 32-bit coordinates.
--
-- 'Location' and 'Heading' are both represented using types from
-- t'Location' and 'Heading' are both represented using types from
-- the @linear@ package, so they can be manipulated using a large
-- number of operators from that package. For example:
--
-- * Two headings can be added with '^+^'.
-- * The difference between two 'Location's is a 'Heading' (via '.-.').
-- * A 'Location' plus a 'Heading' is another 'Location' (via 'Linear.Affine..^+').
-- * The difference between two t'Location's is a 'Heading' (via '.-.').
-- * A t'Location' plus a 'Heading' is another t'Location' (via 'Linear.Affine..^+').
type Heading = V2 Int32

deriving instance ToJSON (V2 Int32)
Expand Down
17 changes: 9 additions & 8 deletions src/Swarm/Game/Robot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ data ActivityCounts = ActivityCounts
makeLensesNoSigs ''ActivityCounts

-- | A counter that is decremented upon each step of the robot within the
-- CESK machine. Initially set to 'robotStepsPerTick' at each new tick.
-- CESK machine. Initially set to 'Swarm.Game.State.robotStepsPerTick'
-- at each new tick.
--
-- The need for 'tickStepBudget' is a bit technical, and I hope I can
-- eventually find a different, better way to accomplish it.
Expand Down Expand Up @@ -341,20 +342,20 @@ robotDisplay = lens getDisplay setDisplay

-- | The robot's current location, represented as @(x,y)@. This is only
-- a getter, since when changing a robot's location we must remember
-- to update the 'robotsByLocation' map as well. You can use the
-- 'updateRobotLocation' function for this purpose.
-- to update the 'Swarm.Game.State.robotsByLocation' map as well. You can use the
-- 'Swarm.Game.Step.updateRobotLocation' function for this purpose.
robotLocation :: Getter Robot (Cosmic Location)

-- | Set a robot's location. This is unsafe and should never be
-- called directly except by the 'updateRobotLocation' function.
-- The reason is that we need to make sure the 'robotsByLocation'
-- called directly except by the 'Swarm.Game.Step.updateRobotLocation' function.
-- The reason is that we need to make sure the 'Swarm.Game.State.robotsByLocation'
-- map stays in sync.
unsafeSetRobotLocation :: Cosmic Location -> Robot -> Robot
unsafeSetRobotLocation loc r = r {_robotLocation = loc}

-- | A template robot's location. Unlike 'robotLocation', this is a
-- lens, since when dealing with robot templates there is as yet no
-- 'robotsByLocation' map to keep up-to-date.
-- 'Swarm.Game.State.robotsByLocation' map to keep up-to-date.
trobotLocation :: Lens' TRobot (Maybe (Cosmic Location))
trobotLocation = lens _robotLocation (\r l -> r {_robotLocation = l})

Expand Down Expand Up @@ -414,8 +415,8 @@ equippedDevices = lens _equippedDevices setEquipped
}

-- | The robot's own private message log, most recent message last.
-- Messages can be added both by explicit use of the 'Log' command,
-- and by uncaught exceptions. Stored as a "Data.Sequence" so that
-- Messages can be added both by explicit use of the 'Swarm.Language.Syntax.Log' command,
-- and by uncaught exceptions. Stored as a 'Seq' so that
-- we can efficiently add to the end and also process from beginning
-- to end. Note that updating via this lens will also set the
-- 'robotLogUpdated'.
Expand Down
2 changes: 2 additions & 0 deletions src/Swarm/Game/Scenario/Style.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ instance FromJSON StyleFlag where
instance ToJSON StyleFlag where
toJSON = genericToJSON styleFlagJsonOptions

-- | Hexadecimal color notation.
-- May include a leading hash symbol (see 'Data.Colour.SRGB.sRGB24read').
newtype HexColor = HexColor Text
deriving (Eq, Show, Generic, FromJSON, ToJSON)

Expand Down
5 changes: 4 additions & 1 deletion src/Swarm/Game/Scenario/Topography/Area.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Data.Maybe (listToMaybe)
import Linear (V2 (..))
import Swarm.Game.Location

-- | Height and width of a 2D map region
data AreaDimensions = AreaDimensions
{ rectWidth :: Int32
, rectHeight :: Int32
Expand All @@ -22,7 +23,7 @@ renderRectDimensions (AreaDimensions w h) =
invertY :: V2 Int32 -> V2 Int32
invertY (V2 x y) = V2 x (-y)

-- | Incorporates an offset by -1, since the area is
-- | Incorporates an offset by @-1@, since the area is
-- "inclusive" of the lower-right coordinate.
-- Inverse of 'cornersToArea'.
upperLeftToBottomRight :: AreaDimensions -> Location -> Location
Expand All @@ -41,9 +42,11 @@ cornersToArea upperLeft lowerRight =
where
V2 x y = (+ 1) <$> invertY (lowerRight .-. upperLeft)

-- | Has zero width or height.
isEmpty :: AreaDimensions -> Bool
isEmpty (AreaDimensions w h) = w == 0 || h == 0

-- | Extracts the dimensions of a map grid.
getAreaDimensions :: [[a]] -> AreaDimensions
getAreaDimensions cellGrid =
AreaDimensions w h
Expand Down
6 changes: 3 additions & 3 deletions src/Swarm/Game/Scenario/Topography/Navigation/Portal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ data AnnotatedDestination a = AnnotatedDestination
-- on the portal location specification method ('portalExitLoc').
--
-- == @additionalDimension@
-- As a member of the 'WorldDescription', waypoints are only known within a
-- As a member of the 'Swarm.Game.Scenario.Topography.WorldDescription.WorldDescription', waypoints are only known within a
-- a single subworld, so 'additionalDimension' is 'Identity' for the map
-- of waypoint names to planar locations.
-- At the Scenario level, in contrast, we have access to all subworlds, so
Expand Down Expand Up @@ -129,7 +129,7 @@ failWaypointLookup (WaypointName rawName) =
-- == Data flow
--
-- Waypoints are defined within a subworld and are namespaced by it.
-- Optional intra-subworld uniqueness of Waypoints is enforced at WorldDescription
-- Optional intra-subworld uniqueness of Waypoints is enforced at 'Swarm.Game.Scenario.Topography.WorldDescription.WorldDescription'
-- parse time.
-- Portals are declared within a subworld. The portal entrance must be a waypoint
-- within this subworld.
Expand All @@ -140,7 +140,7 @@ failWaypointLookup (WaypointName rawName) =
-- no entrances overlap can also be performed at that level.
-- * However, enforcement of single-multiplicity on portal /exits/ must be performed
-- at scenario-parse level, because for a portal exit that references a waypoint in
-- another subworld, we can't know at the single-WorldDescription level whether
-- another subworld, we can't know at the single-'Swarm.Game.Scenario.Topography.WorldDescription.WorldDescription' level whether
-- that waypoint has plural multiplicity.
validatePartialNavigation ::
(MonadFail m, Traversable t) =>
Expand Down
16 changes: 16 additions & 0 deletions src/Swarm/Game/Scenario/Topography/Navigation/Waypoint.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Landmarks that are used to specify portal locations
-- and can serve as navigation aids via the `waypoint` command.
--
-- = Waypoint ordering
--
-- The sequence of waypoints of a given name is dictated by criteria in the following order:
--
-- 1. Ordering of structure placements
-- (see implementation of 'Swarm.Game.Scenario.Topography.Structure.mergeStructures');
-- later placements are ordered first.
-- 2. Placement of cells within a map. Map locations go by row-major order
-- (compare to docs for 'Swarm.Game.State.genRobotTemplates').
--
-- TODO (#1366): May be useful to have a mechanism for more
-- precise control of ordering.
module Swarm.Game.Scenario.Topography.Navigation.Waypoint where

import Data.Int (Int32)
Expand Down
2 changes: 1 addition & 1 deletion src/Swarm/Game/Scenario/Topography/Structure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ instance FromJSONE (EntityMap, RobotMap) (PStructure (Maybe (PCell Entity))) whe
return $ Structure maskedArea localStructureDefs placementDefs $ waypointDefs <> mapWaypoints

-- | \"Paint\" a world map using a 'WorldPalette', turning it from a raw
-- string into a nested list of 'Cell' values by looking up each
-- string into a nested list of 'PCell' values by looking up each
-- character in the palette, failing if any character in the raw map
-- is not contained in the palette.
paintMap ::
Expand Down
10 changes: 6 additions & 4 deletions src/Swarm/Game/ScenarioInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import Witch (into)
-- ----------------------------------------------------------------------------

-- | A scenario item is either a specific scenario, or a collection of
-- scenarios (*e.g.* the scenarios contained in a subdirectory).
-- scenarios (/e.g./ the scenarios contained in a subdirectory).
data ScenarioItem = SISingle ScenarioInfoPair | SICollection Text ScenarioCollection
deriving (Show)

Expand All @@ -85,15 +85,17 @@ scenarioItemName (SISingle (s, _ss)) = s ^. scenarioName
scenarioItemName (SICollection name _) = name

-- | A scenario collection is a tree of scenarios, keyed by name,
-- together with an optional order. Invariant: every item in the
-- scOrder exists as a key in the scMap.
-- together with an optional order.
--
-- /Invariant:/ every item in the
-- 'scOrder' exists as a key in the 'scMap'.
data ScenarioCollection = SC
{ scOrder :: Maybe [FilePath]
, scMap :: Map FilePath ScenarioItem
}
deriving (Show)

-- | Access and modify ScenarioItems in collection based on their path.
-- | Access and modify 'ScenarioItem's in collection based on their path.
scenarioItemByPath :: FilePath -> Traversal' ScenarioCollection ScenarioItem
scenarioItemByPath path = ixp ps
where
Expand Down
8 changes: 4 additions & 4 deletions src/Swarm/Game/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ data REPLStatus
= -- | The REPL is not doing anything actively at the moment.
-- We persist the last value and its type though.
--
-- INVARIANT: the 'Value' stored here is not a 'VResult'.
-- INVARIANT: the 'Value' stored here is not a 'Swarm.Language.Value.VResult'.
REPLDone (Maybe (Typed Value))
| -- | A command entered at the REPL is currently being run. The
-- 'Polytype' represents the type of the expression that was
Expand Down Expand Up @@ -694,7 +694,7 @@ recipesInfo :: Lens' GameState Recipes

-- | The filepath of the currently running scenario.
--
-- This is useful as an index to 'scenarios' collection,
-- This is useful as an index to the scenarios collection,
-- see 'Swarm.Game.ScenarioInfo.scenarioItemByPath'.
currentScenarioPath :: Lens' GameState (Maybe FilePath)

Expand Down Expand Up @@ -732,15 +732,15 @@ focusedRobotID = to _focusedRobotID
------------------------------------------------------------

-- | The current rule for determining the center of the world view.
-- It updates also, viewCenter and 'focusedRobotName' to keep
-- It updates also, 'viewCenter' and 'focusedRobot' to keep
-- everything synchronized.
viewCenterRule :: Lens' GameState ViewCenterRule
viewCenterRule = lens getter setter
where
getter :: GameState -> ViewCenterRule
getter = _viewCenterRule

-- The setter takes care of updating viewCenter and focusedRobotName
-- The setter takes care of updating 'viewCenter' and 'focusedRobot'
-- So non of this fields get out of sync.
setter :: GameState -> ViewCenterRule -> GameState
setter g rule =
Expand Down
11 changes: 6 additions & 5 deletions src/Swarm/Game/Step.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
-- ** Note on the IO:
--
-- The only reason we need @IO@ is so that robots can run programs
-- loaded from files, via the 'Run' command.
-- This could be avoided by using 'Import' command instead and parsing
-- loaded from files, via the 'Swarm.Language.Syntax.Run' command.
-- This could be avoided by using a hypothetical @import@ command instead and parsing
-- the required files at the time of declaration.
-- See <https://github.com/swarm-game/swarm/issues/495>.
module Swarm.Game.Step where
Expand Down Expand Up @@ -457,7 +457,7 @@ traceLogShow = void . traceLog Logged Info . from . show

-- | Capabilities needed for a specific robot to evaluate or execute a
-- constant. Right now, the only difference is whether the robot is
-- heavy or not when executing the 'Move' command, but there might
-- heavy or not when executing the 'Swarm.Language.Syntax.Move' command, but there might
-- be other exceptions added in the future.
constCapsFor :: Const -> Robot -> Maybe Capability
constCapsFor Move r
Expand Down Expand Up @@ -796,7 +796,7 @@ stepCESK cesk = case cesk of
runningAtomic .= False
return $ Out v s k

-- Machinery for implementing the 'meetAll' command.
-- Machinery for implementing the 'Swarm.Language.Syntax.MeetAll' command.
-- First case: done meeting everyone.
Out b s (FMeetAll _ [] : k) -> return $ Out b s k
-- More still to meet: apply the function to the current value b and
Expand Down Expand Up @@ -2615,7 +2615,8 @@ formatDevices = T.intercalate " or " . map (^. entityName) . S.toList

-- | Give some entities from a parent robot (the robot represented by
-- the ambient @State Robot@ effect) to a child robot (represented
-- by the given 'RID') as part of a 'Build' or 'Reprogram' command.
-- by the given 'RID') as part of a 'Swarm.Language.Syntax.Build'
-- or 'Swarm.Language.Syntax.Reprogram' command.
-- The first 'Inventory' is devices to be equipped, and the second
-- is entities to be transferred.
--
Expand Down
12 changes: 6 additions & 6 deletions src/Swarm/Game/Step/Combustion.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Some entities are "combustible". A command, `ignite`, will
-- Some entities are "combustible". A command, 'Swarm.Language.Syntax.Ignite', will
-- initiate combustion on such an entity.
-- Furthermore, combustion can spread to (4-)adjacent entities, depending
-- on the 'ignition' property of that entity.
Expand Down Expand Up @@ -77,7 +77,7 @@ igniteCommand c d = do
-- by placed entities.
-- The "combustion bot" represents the burning of a single
-- entity; propagating the fire to neighbors is handled upstream,
-- within the `ignite` command.
-- within the 'Swarm.Language.Syntax.Ignite' command.
addCombustionBot ::
Has (State GameState) sig m =>
Entity ->
Expand Down Expand Up @@ -143,8 +143,8 @@ ignitionProgram waitTime =
--
-- 1. Create sub-partitions (of say, 10-tick duration) of the combustion duration
-- to re-evaluate opportunities to light adjacent entities on fire.
-- 2. Use the `watch` command to observe for changes to adjacent entities.
-- Note that if we "wake" from our `wait` due to the `watch` being triggered,
-- 2. Use the 'Swarm.Language.Syntax.Watch' command to observe for changes to adjacent entities.
-- Note that if we "wake" from our 'Swarm.Language.Syntax.Wait' due to the 'Swarm.Language.Syntax.Watch' being triggered,
-- we would need to maintain bookkeeping of how much time is left.
-- 3. Spawn more robots whose sole purpose is to observe for changes to neighbor
-- cells. This would avoid polluting the logic of the currently burning cell
Expand All @@ -165,7 +165,7 @@ combustionProgram combustionDuration (Combustibility _ _ maybeCombustionProduct)
Nothing -> (0, "")
Just p -> (1, p)

-- | We treat the 'ignition' field in the 'Combustion' record
-- | We treat the 'ignition' field in the 'Combustibility' record
-- as a /rate/ in a Poisson distribution.
-- Ignition of neighbors depends on that particular neighbor entity's
-- combustion /rate/, but also on the duration
Expand Down Expand Up @@ -197,7 +197,7 @@ igniteNeighbor creationTime sourceDuration loc = do
probabilityOfIgnition = 1 - exp (negate $ rate * fromIntegral sourceDuration)

-- | Construct an invisible "ignition robot" and add it to the world.
-- Its sole purpose is to delay the `ignite` command for a neighbor
-- Its sole purpose is to delay the 'Swarm.Language.Syntax.Ignite' command for a neighbor
-- that has been a priori determined that it shall be ignited.
addIgnitionBot ::
Has (State GameState) sig m =>
Expand Down
Loading

0 comments on commit ab7e5b6

Please sign in to comment.