summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Properties.hs126
1 files changed, 69 insertions, 57 deletions
diff --git a/lib/Properties.hs b/lib/Properties.hs
index 395bc87..c2f5c81 100644
--- a/lib/Properties.hs
+++ b/lib/Properties.hs
@@ -18,17 +18,71 @@ import Types (Dep (Link, Local, LocalMap, MapLink))
--- | the point of this module
+-- | Checks an entire map for "general" lints.
--
--- given a property, check if it is valid. It gets a reference
--- to its own layer since sometimes the presense of one property
--- implies the presence or absense of another.
+-- Note that it does /not/ call checkMapProperty; this is handled
+-- seperately in CheckMap.hs, since these lints go into a different
+-- field of the resulting json.
+checkMap :: Tiledmap -> LintWriter ()
+checkMap tiledmap = do
+ -- check properties
+ mapM_ (checkMapProperty tiledmap) (tiledmapProperties tiledmap)
+ -- check tilesets
+ mapM_ checkTileset (tiledmapTilesets tiledmap)
+
+ -- some layers should exist
+ hasLayerNamed "start" (const True)
+ "The map must have one layer named \"start\""
+ hasLayerNamed "floorLayer" ((==) "objectgroup" . layerType)
+ "The map must have one layer named \"floorLayer\" of type \"objectgroup\""
+ hasLayer (flip containsProperty "exitUrl" . layerProperties)
+ "The map must contain at least one layer with the property \"exitUrl\" set"
+
+ -- reject maps not suitable for workadventure
+ unless (tiledmapOrientation tiledmap == "orthogonal")
+ $ complain "The map's orientation must be set to \"orthogonal\""
+ unless (tiledmapTileheight tiledmap == 32 && tiledmapTilewidth tiledmap == 32)
+ $ complain "The map's tile size must be 32 by 32 pixels"
+ where
+ layers = tiledmapLayers tiledmap
+ hasLayerNamed name pred = hasLayer (\l -> layerName l == name && pred l)
+ hasLayer pred err =
+ unless (any pred layers)
+ $ complain err
+
+
+-- | Checks a single property of a map.
--
--- The tests in here are meant to comply with the informal spec
--- at https://workadventu.re/map-building
+-- Doesn't really do all that much, but could in theory be expanded into a
+-- longer function same as checkLayerProperty.
+checkMapProperty :: Tiledmap -> Property -> LintWriter ()
+checkMapProperty map (Property name value) = case name of
+ "script" -> isForbidden
+ _ -> complain $ "unknown map property " <> name
+ where
+ -- | this property is forbidden and should not be used
+ isForbidden = forbid $ "property " <> prettyprint name <> " should not be used"
+
+
+-- | check an embedded tile set.
--
--- I've attempted to build the LintWriter monad in a way
--- that should make this readable even to non-Haskellers
+-- Important to collect dependency files
+checkTileset :: Tileset -> LintWriter ()
+checkTileset tileset = do
+ -- TODO: can tilesets be non-local dependencies?
+ dependsOn $ Local (tilesetImage tileset)
+
+ -- reject tilesets unsuitable for workadventure
+ unless (tilesetTilewidth tileset == 32 && tilesetTileheight tileset == 32)
+ $ complain $ "Tileset " <> tilesetName tileset <> " must have tile size 32 by 32"
+
+
+
+
+-- | Checks a single (custom) property of a layer
+--
+-- It gets a reference to its own layer since sometimes the presence
+-- of one property implies the presence or absense of another.
checkLayerProperty :: Layer -> Property -> LintWriter ()
checkLayerProperty layer p@(Property name value) = case name of
"jitsiRoom" -> do
@@ -110,59 +164,17 @@ checkLayerProperty layer p@(Property name value) = case name of
uselessEmptyLayer = when (layerIsEmpty layer)
$ warn ("property" <> name <> " was set on an empty layer and is thereby useless")
--- | Checks a single property of a map.
---
--- Doesn't really do all that much, but could in theory be expanded into a
--- longer function same as checkLayerProperty.
-checkMapProperty :: Tiledmap -> Property -> LintWriter ()
-checkMapProperty map (Property name value) = case name of
- "script" -> isForbidden
- _ -> complain $ "unknown map property " <> name
- where
- -- | this property is forbidden and should not be used
- isForbidden = forbid $ "property " <> prettyprint name <> " should not be used"
--- | Checks an entire map for "general" lints.
---
--- Note that it does /not/ call checkMapProperty; this is handled
--- seperately in CheckMap.hs, since these lints go into a different
--- field of the resulting json.
-checkMap :: Tiledmap -> LintWriter ()
-checkMap tiledmap = do
- -- check properties
- mapM_ (checkMapProperty tiledmap) (tiledmapProperties tiledmap)
- mapM_ checkTileset (tiledmapTilesets tiledmap)
- -- some layers should exist
- hasLayerNamed "start" (const True)
- "The map must have one layer named \"start\""
- hasLayerNamed "floorLayer" ((==) "objectgroup" . layerType)
- "The map must have one layer named \"floorLayer\" of type \"objectgroup\""
- hasLayer (flip containsProperty "exitUrl" . layerProperties)
- "The map must contain at least one layer with the property \"exitUrl\" set"
- -- reject maps not suitable for workadventure
- unless (tiledmapOrientation tiledmap == "orthogonal")
- $ complain "The map's orientation must be set to \"orthogonal\""
- unless (tiledmapTileheight tiledmap == 32 && tiledmapTilewidth tiledmap == 32)
- $ complain "The map's tile size must be 32 by 32 pixels"
- where
- layers = tiledmapLayers tiledmap
- hasLayerNamed name pred = hasLayer (\l -> layerName l == name && pred l)
- hasLayer pred err =
- unless (any pred layers)
- $ complain err
--- | check an embedded tile set.
---
--- Important to collect dependency files
-checkTileset :: Tileset -> LintWriter ()
-checkTileset tileset = do
- -- TODO: can tilesets be non-local dependencies?
- dependsOn $ Local (tilesetImage tileset)
- -- reject tilesets unsuitable for workadventure
- unless (tilesetTilewidth tileset == 32 && tilesetTileheight tileset == 32)
- $ complain $ "Tileset " <> tilesetName tileset <> " must have tile size 32 by 32"
+
+
+
+
+
+--------- Helper functions & stuff ---------
+
-- | does this layer have the given property?
containsProperty :: [Property] -> Text -> Bool