aeson-tiled 0.0.1.0 → 0.0.2.0
raw patch · 40 files changed
+1178/−536 lines, 40 filesdep +filepathdep +tastydep +tasty-hunitdep −hspecdep −hspec-discoverdep ~aesondep ~bytestringPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: filepath, tasty, tasty-hunit, temporary
Dependencies removed: hspec, hspec-discover
Dependency ranges changed: aeson, bytestring
API changes (from Hackage documentation)
- Data.Aeson.Tiled: Frame :: Int -> LocalId -> Frame
- Data.Aeson.Tiled: GlobalId :: Int -> GlobalId
- Data.Aeson.Tiled: Isometric :: Orientation
- Data.Aeson.Tiled: Layer :: Double -> Double -> Text -> Text -> Bool -> Double -> Double -> Maybe (Vector GlobalId) -> Maybe (Vector Object) -> Map Text Text -> Float -> Text -> Layer
- Data.Aeson.Tiled: LocalId :: Int -> LocalId
- Data.Aeson.Tiled: Object :: Int -> Double -> Double -> Text -> Text -> Map Text Text -> Bool -> Double -> Double -> Float -> Maybe GlobalId -> Bool -> Maybe (Vector (Double, Double)) -> Maybe (Vector (Double, Double)) -> Map Text Text -> Object
- Data.Aeson.Tiled: Orientation :: Text -> Orientation
- Data.Aeson.Tiled: Orthogonal :: Orientation
- Data.Aeson.Tiled: Staggered :: Orientation
- Data.Aeson.Tiled: Terrain :: Text -> LocalId -> Terrain
- Data.Aeson.Tiled: Tile :: LocalId -> Map Text Text -> Maybe Value -> Maybe (Vector Object) -> Maybe (Vector Frame) -> Tile
- Data.Aeson.Tiled: Tiledmap :: Version -> Version -> Int -> Int -> Double -> Double -> Orientation -> Vector Layer -> Vector Tileset -> Maybe Text -> Text -> Map Text Text -> Int -> Tiledmap
- Data.Aeson.Tiled: Tileset :: GlobalId -> FilePath -> Text -> Int -> Int -> Int -> Int -> Map Text Text -> Map Text Text -> Int -> Int -> Map GlobalId (Map Text Text) -> Vector Terrain -> Int -> Int -> Map LocalId Tile -> Tileset
- Data.Aeson.Tiled: TransitiveTilesetMap :: Map LocalId Value -> TransitiveTilesetMap
- Data.Aeson.Tiled: VersionFloat :: Float -> Version
- Data.Aeson.Tiled: VersionText :: Text -> Version
- Data.Aeson.Tiled: XYPair :: a -> a -> XYPair a
- Data.Aeson.Tiled: [frameDuration] :: Frame -> Int
- Data.Aeson.Tiled: [frameTileId] :: Frame -> LocalId
- Data.Aeson.Tiled: [layerData] :: Layer -> Maybe (Vector GlobalId)
- Data.Aeson.Tiled: [layerDraworder] :: Layer -> Text
- Data.Aeson.Tiled: [layerHeight] :: Layer -> Double
- Data.Aeson.Tiled: [layerName] :: Layer -> Text
- Data.Aeson.Tiled: [layerObjects] :: Layer -> Maybe (Vector Object)
- Data.Aeson.Tiled: [layerOpacity] :: Layer -> Float
- Data.Aeson.Tiled: [layerProperties] :: Layer -> Map Text Text
- Data.Aeson.Tiled: [layerType] :: Layer -> Text
- Data.Aeson.Tiled: [layerVisible] :: Layer -> Bool
- Data.Aeson.Tiled: [layerWidth] :: Layer -> Double
- Data.Aeson.Tiled: [layerX] :: Layer -> Double
- Data.Aeson.Tiled: [layerY] :: Layer -> Double
- Data.Aeson.Tiled: [objectEllipse] :: Object -> Bool
- Data.Aeson.Tiled: [objectGid] :: Object -> Maybe GlobalId
- Data.Aeson.Tiled: [objectHeight] :: Object -> Double
- Data.Aeson.Tiled: [objectId] :: Object -> Int
- Data.Aeson.Tiled: [objectName] :: Object -> Text
- Data.Aeson.Tiled: [objectPolygon] :: Object -> Maybe (Vector (Double, Double))
- Data.Aeson.Tiled: [objectPolyline] :: Object -> Maybe (Vector (Double, Double))
- Data.Aeson.Tiled: [objectProperties] :: Object -> Map Text Text
- Data.Aeson.Tiled: [objectRotation] :: Object -> Float
- Data.Aeson.Tiled: [objectText] :: Object -> Map Text Text
- Data.Aeson.Tiled: [objectType] :: Object -> Text
- Data.Aeson.Tiled: [objectVisible] :: Object -> Bool
- Data.Aeson.Tiled: [objectWidth] :: Object -> Double
- Data.Aeson.Tiled: [objectX] :: Object -> Double
- Data.Aeson.Tiled: [objectY] :: Object -> Double
- Data.Aeson.Tiled: [terrainName] :: Terrain -> Text
- Data.Aeson.Tiled: [terrainTile] :: Terrain -> LocalId
- Data.Aeson.Tiled: [tileAnimation] :: Tile -> Maybe (Vector Frame)
- Data.Aeson.Tiled: [tileId] :: Tile -> LocalId
- Data.Aeson.Tiled: [tileImage] :: Tile -> Maybe Value
- Data.Aeson.Tiled: [tileObjectGroup] :: Tile -> Maybe (Vector Object)
- Data.Aeson.Tiled: [tileProperties] :: Tile -> Map Text Text
- Data.Aeson.Tiled: [tiledmapBackgroundcolor] :: Tiledmap -> Maybe Text
- Data.Aeson.Tiled: [tiledmapHeight] :: Tiledmap -> Int
- Data.Aeson.Tiled: [tiledmapLayers] :: Tiledmap -> Vector Layer
- Data.Aeson.Tiled: [tiledmapNextobjectid] :: Tiledmap -> Int
- Data.Aeson.Tiled: [tiledmapOrientation] :: Tiledmap -> Orientation
- Data.Aeson.Tiled: [tiledmapProperties] :: Tiledmap -> Map Text Text
- Data.Aeson.Tiled: [tiledmapRenderorder] :: Tiledmap -> Text
- Data.Aeson.Tiled: [tiledmapTiledversion] :: Tiledmap -> Version
- Data.Aeson.Tiled: [tiledmapTileheight] :: Tiledmap -> Double
- Data.Aeson.Tiled: [tiledmapTilesets] :: Tiledmap -> Vector Tileset
- Data.Aeson.Tiled: [tiledmapTilewidth] :: Tiledmap -> Double
- Data.Aeson.Tiled: [tiledmapVersion] :: Tiledmap -> Version
- Data.Aeson.Tiled: [tiledmapWidth] :: Tiledmap -> Int
- Data.Aeson.Tiled: [tilesetColumns] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetFirstgid] :: Tileset -> GlobalId
- Data.Aeson.Tiled: [tilesetImage] :: Tileset -> FilePath
- Data.Aeson.Tiled: [tilesetImageheight] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetImagewidth] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetMargin] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetName] :: Tileset -> Text
- Data.Aeson.Tiled: [tilesetProperties] :: Tileset -> Map Text Text
- Data.Aeson.Tiled: [tilesetPropertytypes] :: Tileset -> Map Text Text
- Data.Aeson.Tiled: [tilesetSpacing] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetTerrains] :: Tileset -> Vector Terrain
- Data.Aeson.Tiled: [tilesetTilecount] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetTileheight] :: Tileset -> Int
- Data.Aeson.Tiled: [tilesetTileproperties] :: Tileset -> Map GlobalId (Map Text Text)
- Data.Aeson.Tiled: [tilesetTiles] :: Tileset -> Map LocalId Tile
- Data.Aeson.Tiled: [tilesetTilewidth] :: Tileset -> Int
- Data.Aeson.Tiled: [unGlobalId] :: GlobalId -> Int
- Data.Aeson.Tiled: [unLocalId] :: LocalId -> Int
- Data.Aeson.Tiled: data Frame
- Data.Aeson.Tiled: data Layer
- Data.Aeson.Tiled: data Map k a
- Data.Aeson.Tiled: data Object
- Data.Aeson.Tiled: data Orientation
- Data.Aeson.Tiled: data Terrain
- Data.Aeson.Tiled: data Tile
- Data.Aeson.Tiled: data Tiledmap
- Data.Aeson.Tiled: data Tileset
- Data.Aeson.Tiled: data Vector a
- Data.Aeson.Tiled: data Version
- Data.Aeson.Tiled: data XYPair a
- Data.Aeson.Tiled: fromXYPair :: XYPair a -> (a, a)
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Frame
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Layer
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Object
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Orientation
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Terrain
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Tile
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Tiledmap
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Tileset
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.TransitiveTilesetMap
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON Data.Aeson.Tiled.Version
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Data.Aeson.Tiled.XYPair a)
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSONKey Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.FromJSON.FromJSONKey Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Frame
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Layer
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Object
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Orientation
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Terrain
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Tile
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Tiledmap
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Tileset
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON Data.Aeson.Tiled.Version
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.Aeson.Tiled.XYPair a)
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSONKey Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance Data.Aeson.Types.ToJSON.ToJSONKey Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Frame
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Layer
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Object
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Orientation
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Terrain
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Tile
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Tiledmap
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Tileset
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.TransitiveTilesetMap
- Data.Aeson.Tiled: instance GHC.Classes.Eq Data.Aeson.Tiled.Version
- Data.Aeson.Tiled: instance GHC.Classes.Ord Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance GHC.Classes.Ord Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Classes.Ord Data.Aeson.Tiled.Orientation
- Data.Aeson.Tiled: instance GHC.Classes.Ord Data.Aeson.Tiled.Version
- Data.Aeson.Tiled: instance GHC.Enum.Enum Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance GHC.Enum.Enum Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Frame
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Layer
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Object
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Orientation
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Terrain
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Tile
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Tiledmap
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Tileset
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.TransitiveTilesetMap
- Data.Aeson.Tiled: instance GHC.Generics.Generic Data.Aeson.Tiled.Version
- Data.Aeson.Tiled: instance GHC.Num.Num Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance GHC.Num.Num Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Frame
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.GlobalId
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Layer
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.LocalId
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Object
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Orientation
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Terrain
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Tile
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Tiledmap
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Tileset
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.TransitiveTilesetMap
- Data.Aeson.Tiled: instance GHC.Show.Show Data.Aeson.Tiled.Version
- Data.Aeson.Tiled: loadTiledmap :: FilePath -> IO (Either String Tiledmap)
- Data.Aeson.Tiled: newtype GlobalId
- Data.Aeson.Tiled: newtype LocalId
- Data.Aeson.Tiled: newtype TransitiveTilesetMap
- Data.Aeson.Tiled: omitNulls :: Value -> Value
- Data.Aeson.Tiled: parseDefault :: FromJSON a => Object -> Key -> a -> Parser a
- Data.Aeson.Tiled: parseTiles :: Object -> Parser (Map LocalId Tile)
- Data.Aeson.Tiled: toXYPair :: (a, a) -> XYPair a
+ Codec.Tiled: data Chunk
+ Codec.Tiled: data Frame
+ Codec.Tiled: data GID
+ Codec.Tiled: data Grid
+ Codec.Tiled: data Layer
+ Codec.Tiled: data LayerData
+ Codec.Tiled: data Map
+ Codec.Tiled: data Object
+ Codec.Tiled: data Point
+ Codec.Tiled: data Property
+ Codec.Tiled: data Template
+ Codec.Tiled: data Terrain
+ Codec.Tiled: data Text
+ Codec.Tiled: data Tile
+ Codec.Tiled: data TileOffset
+ Codec.Tiled: data Tileset
+ Codec.Tiled: data Transformations
+ Codec.Tiled: data WangColor
+ Codec.Tiled: data WangSet
+ Codec.Tiled: data WangTile
+ Codec.Tiled.Aeson: class FromJSON a
+ Codec.Tiled.Aeson: class ToJSON a
+ Codec.Tiled.Aeson: genericParseJSON :: (Generic a, GFromJSON Zero (Rep a)) => Value -> Parser a
+ Codec.Tiled.Aeson: genericToJSON :: (Generic a, GToJSON' Value Zero (Rep a)) => a -> Value
+ Codec.Tiled.Aeson: mkOptions :: (String -> String) -> Options
+ Codec.Tiled.Aeson: parseJSON :: FromJSON a => Value -> Parser a
+ Codec.Tiled.Aeson: parseJSONList :: FromJSON a => Value -> Parser [a]
+ Codec.Tiled.Aeson: remapFields :: String -> String
+ Codec.Tiled.Aeson: remapFields_ :: String -> String
+ Codec.Tiled.Aeson: toEncoding :: ToJSON a => a -> Encoding
+ Codec.Tiled.Aeson: toEncodingList :: ToJSON a => [a] -> Encoding
+ Codec.Tiled.Aeson: toJSON :: ToJSON a => a -> Value
+ Codec.Tiled.Aeson: toJSONList :: ToJSON a => [a] -> Value
+ Codec.Tiled.Layer: Layer :: Maybe (Vector Chunk) -> Maybe Text -> Maybe LayerData -> Maybe Text -> Maybe Text -> Maybe Int -> Maybe Int -> Maybe FilePath -> Maybe (Vector Layer) -> Maybe Bool -> Text -> Maybe (Vector Object) -> Maybe Double -> Maybe Double -> Double -> Maybe Double -> Maybe Double -> Maybe (Vector Property) -> Maybe Bool -> Maybe Bool -> Maybe Int -> Maybe Int -> Maybe Text -> Maybe Text -> Text -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Layer
+ Codec.Tiled.Layer: [chunks] :: Layer -> Maybe (Vector Chunk)
+ Codec.Tiled.Layer: [compression] :: Layer -> Maybe Text
+ Codec.Tiled.Layer: [data_] :: Layer -> Maybe LayerData
+ Codec.Tiled.Layer: [draworder] :: Layer -> Maybe Text
+ Codec.Tiled.Layer: [encoding] :: Layer -> Maybe Text
+ Codec.Tiled.Layer: [height] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: [id] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: [image] :: Layer -> Maybe FilePath
+ Codec.Tiled.Layer: [layers] :: Layer -> Maybe (Vector Layer)
+ Codec.Tiled.Layer: [locked] :: Layer -> Maybe Bool
+ Codec.Tiled.Layer: [name] :: Layer -> Text
+ Codec.Tiled.Layer: [objects] :: Layer -> Maybe (Vector Object)
+ Codec.Tiled.Layer: [offsetX] :: Layer -> Maybe Double
+ Codec.Tiled.Layer: [offsetY] :: Layer -> Maybe Double
+ Codec.Tiled.Layer: [opacity] :: Layer -> Double
+ Codec.Tiled.Layer: [parallaxX] :: Layer -> Maybe Double
+ Codec.Tiled.Layer: [parallaxY] :: Layer -> Maybe Double
+ Codec.Tiled.Layer: [properties] :: Layer -> Maybe (Vector Property)
+ Codec.Tiled.Layer: [repeatX] :: Layer -> Maybe Bool
+ Codec.Tiled.Layer: [repeatY] :: Layer -> Maybe Bool
+ Codec.Tiled.Layer: [startX] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: [startY] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: [tintColor] :: Layer -> Maybe Text
+ Codec.Tiled.Layer: [transparentColor] :: Layer -> Maybe Text
+ Codec.Tiled.Layer: [type_] :: Layer -> Text
+ Codec.Tiled.Layer: [visible] :: Layer -> Bool
+ Codec.Tiled.Layer: [width] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: [x] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: [y] :: Layer -> Maybe Int
+ Codec.Tiled.Layer: data Layer
+ Codec.Tiled.Layer: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Layer.Layer
+ Codec.Tiled.Layer: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Layer.Layer
+ Codec.Tiled.Layer: instance GHC.Classes.Eq Codec.Tiled.Layer.Layer
+ Codec.Tiled.Layer: instance GHC.Generics.Generic Codec.Tiled.Layer.Layer
+ Codec.Tiled.Layer: instance GHC.Show.Show Codec.Tiled.Layer.Layer
+ Codec.Tiled.Layer.Chunk: Chunk :: LayerData -> Int -> Int -> Int -> Int -> Chunk
+ Codec.Tiled.Layer.Chunk: [data_] :: Chunk -> LayerData
+ Codec.Tiled.Layer.Chunk: [height] :: Chunk -> Int
+ Codec.Tiled.Layer.Chunk: [width] :: Chunk -> Int
+ Codec.Tiled.Layer.Chunk: [x] :: Chunk -> Int
+ Codec.Tiled.Layer.Chunk: [y] :: Chunk -> Int
+ Codec.Tiled.Layer.Chunk: data Chunk
+ Codec.Tiled.Layer.Chunk: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Layer.Chunk.Chunk
+ Codec.Tiled.Layer.Chunk: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Layer.Chunk.Chunk
+ Codec.Tiled.Layer.Chunk: instance GHC.Classes.Eq Codec.Tiled.Layer.Chunk.Chunk
+ Codec.Tiled.Layer.Chunk: instance GHC.Generics.Generic Codec.Tiled.Layer.Chunk.Chunk
+ Codec.Tiled.Layer.Chunk: instance GHC.Show.Show Codec.Tiled.Layer.Chunk.Chunk
+ Codec.Tiled.Layer.Data: Base64 :: Text -> LayerData
+ Codec.Tiled.Layer.Data: GIDs :: Vector GID -> LayerData
+ Codec.Tiled.Layer.Data: data LayerData
+ Codec.Tiled.Layer.Data: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Layer.Data.LayerData
+ Codec.Tiled.Layer.Data: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Layer.Data.LayerData
+ Codec.Tiled.Layer.Data: instance GHC.Classes.Eq Codec.Tiled.Layer.Data.LayerData
+ Codec.Tiled.Layer.Data: instance GHC.Generics.Generic Codec.Tiled.Layer.Data.LayerData
+ Codec.Tiled.Layer.Data: instance GHC.Show.Show Codec.Tiled.Layer.Data.LayerData
+ Codec.Tiled.Map: Map :: Maybe Text -> Maybe Int -> Int -> Maybe Int -> Maybe Bool -> Vector Layer -> Int -> Int -> Text -> Maybe Double -> Maybe Double -> Maybe (Vector Property) -> Maybe Text -> Maybe Text -> Maybe Text -> Text -> Int -> Vector TilesetRef -> Int -> Text -> Text -> Int -> Map
+ Codec.Tiled.Map: [backgroundColor] :: Map -> Maybe Text
+ Codec.Tiled.Map: [compressionLevel] :: Map -> Maybe Int
+ Codec.Tiled.Map: [height] :: Map -> Int
+ Codec.Tiled.Map: [hexSideLength] :: Map -> Maybe Int
+ Codec.Tiled.Map: [infinite] :: Map -> Maybe Bool
+ Codec.Tiled.Map: [layers] :: Map -> Vector Layer
+ Codec.Tiled.Map: [nextLayerId] :: Map -> Int
+ Codec.Tiled.Map: [nextObjectId] :: Map -> Int
+ Codec.Tiled.Map: [orientation] :: Map -> Text
+ Codec.Tiled.Map: [parallaxOriginX] :: Map -> Maybe Double
+ Codec.Tiled.Map: [parallaxOriginY] :: Map -> Maybe Double
+ Codec.Tiled.Map: [properties] :: Map -> Maybe (Vector Property)
+ Codec.Tiled.Map: [renderOrder] :: Map -> Maybe Text
+ Codec.Tiled.Map: [staggerAxis] :: Map -> Maybe Text
+ Codec.Tiled.Map: [staggerIndex] :: Map -> Maybe Text
+ Codec.Tiled.Map: [tileHeight] :: Map -> Int
+ Codec.Tiled.Map: [tileWidth] :: Map -> Int
+ Codec.Tiled.Map: [tiledVersion] :: Map -> Text
+ Codec.Tiled.Map: [tilesets] :: Map -> Vector TilesetRef
+ Codec.Tiled.Map: [type_] :: Map -> Text
+ Codec.Tiled.Map: [version] :: Map -> Text
+ Codec.Tiled.Map: [width] :: Map -> Int
+ Codec.Tiled.Map: data Map
+ Codec.Tiled.Map: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Map.Map
+ Codec.Tiled.Map: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Map.Map
+ Codec.Tiled.Map: instance GHC.Classes.Eq Codec.Tiled.Map.Map
+ Codec.Tiled.Map: instance GHC.Generics.Generic Codec.Tiled.Map.Map
+ Codec.Tiled.Map: instance GHC.Show.Show Codec.Tiled.Map.Map
+ Codec.Tiled.Map.IO: MapError :: Text -> MapError
+ Codec.Tiled.Map.IO: instance GHC.Classes.Eq Codec.Tiled.Map.IO.MapError
+ Codec.Tiled.Map.IO: instance GHC.Exception.Type.Exception Codec.Tiled.Map.IO.MapError
+ Codec.Tiled.Map.IO: instance GHC.Show.Show Codec.Tiled.Map.IO.MapError
+ Codec.Tiled.Map.IO: newtype MapError
+ Codec.Tiled.Map.IO: readFile :: MonadIO m => FilePath -> m Map
+ Codec.Tiled.Map.IO: writeFile :: MonadIO m => FilePath -> Map -> m ()
+ Codec.Tiled.Object: Object :: Maybe Bool -> Maybe GID -> Double -> Int -> Text -> Maybe Bool -> Maybe (Vector Point) -> Maybe (Vector Point) -> Maybe (Vector Property) -> Double -> Maybe FilePath -> Maybe Text -> Text -> Bool -> Double -> Double -> Double -> Object
+ Codec.Tiled.Object: [ellipse] :: Object -> Maybe Bool
+ Codec.Tiled.Object: [gid] :: Object -> Maybe GID
+ Codec.Tiled.Object: [height] :: Object -> Double
+ Codec.Tiled.Object: [id] :: Object -> Int
+ Codec.Tiled.Object: [name] :: Object -> Text
+ Codec.Tiled.Object: [point] :: Object -> Maybe Bool
+ Codec.Tiled.Object: [polygon] :: Object -> Maybe (Vector Point)
+ Codec.Tiled.Object: [polyline] :: Object -> Maybe (Vector Point)
+ Codec.Tiled.Object: [properties] :: Object -> Maybe (Vector Property)
+ Codec.Tiled.Object: [rotation] :: Object -> Double
+ Codec.Tiled.Object: [template] :: Object -> Maybe FilePath
+ Codec.Tiled.Object: [text] :: Object -> Maybe Text
+ Codec.Tiled.Object: [type_] :: Object -> Text
+ Codec.Tiled.Object: [visible] :: Object -> Bool
+ Codec.Tiled.Object: [width] :: Object -> Double
+ Codec.Tiled.Object: [x] :: Object -> Double
+ Codec.Tiled.Object: [y] :: Object -> Double
+ Codec.Tiled.Object: data Object
+ Codec.Tiled.Object: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Object.Object
+ Codec.Tiled.Object: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Object.Object
+ Codec.Tiled.Object: instance GHC.Classes.Eq Codec.Tiled.Object.Object
+ Codec.Tiled.Object: instance GHC.Generics.Generic Codec.Tiled.Object.Object
+ Codec.Tiled.Object: instance GHC.Show.Show Codec.Tiled.Object.Object
+ Codec.Tiled.Object.Point: Point :: Double -> Double -> Point
+ Codec.Tiled.Object.Point: [x] :: Point -> Double
+ Codec.Tiled.Object.Point: [y] :: Point -> Double
+ Codec.Tiled.Object.Point: data Point
+ Codec.Tiled.Object.Point: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Object.Point.Point
+ Codec.Tiled.Object.Point: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Object.Point.Point
+ Codec.Tiled.Object.Point: instance GHC.Classes.Eq Codec.Tiled.Object.Point.Point
+ Codec.Tiled.Object.Point: instance GHC.Generics.Generic Codec.Tiled.Object.Point.Point
+ Codec.Tiled.Object.Point: instance GHC.Show.Show Codec.Tiled.Object.Point.Point
+ Codec.Tiled.Object.Template: Template :: Text -> Maybe Tileset -> Object -> Template
+ Codec.Tiled.Object.Template: [object] :: Template -> Object
+ Codec.Tiled.Object.Template: [tileset] :: Template -> Maybe Tileset
+ Codec.Tiled.Object.Template: [type_] :: Template -> Text
+ Codec.Tiled.Object.Template: data Template
+ Codec.Tiled.Object.Template: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Object.Template.Template
+ Codec.Tiled.Object.Template: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Object.Template.Template
+ Codec.Tiled.Object.Template: instance GHC.Classes.Eq Codec.Tiled.Object.Template.Template
+ Codec.Tiled.Object.Template: instance GHC.Generics.Generic Codec.Tiled.Object.Template.Template
+ Codec.Tiled.Object.Template: instance GHC.Show.Show Codec.Tiled.Object.Template.Template
+ Codec.Tiled.Object.Template.IO: TemplateError :: Text -> TemplateError
+ Codec.Tiled.Object.Template.IO: instance GHC.Classes.Eq Codec.Tiled.Object.Template.IO.TemplateError
+ Codec.Tiled.Object.Template.IO: instance GHC.Exception.Type.Exception Codec.Tiled.Object.Template.IO.TemplateError
+ Codec.Tiled.Object.Template.IO: instance GHC.Show.Show Codec.Tiled.Object.Template.IO.TemplateError
+ Codec.Tiled.Object.Template.IO: newtype TemplateError
+ Codec.Tiled.Object.Template.IO: readFile :: MonadIO m => FilePath -> m Template
+ Codec.Tiled.Object.Template.IO: writeFile :: MonadIO m => FilePath -> Template -> m ()
+ Codec.Tiled.Object.Text: Text :: Maybe Bool -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Bool -> Maybe Bool -> Maybe Int -> Maybe Bool -> Text -> Maybe Bool -> Maybe Text -> Maybe Bool -> Text
+ Codec.Tiled.Object.Text: [bold] :: Text -> Maybe Bool
+ Codec.Tiled.Object.Text: [color] :: Text -> Maybe Text
+ Codec.Tiled.Object.Text: [fontFamily] :: Text -> Maybe Text
+ Codec.Tiled.Object.Text: [hAlign] :: Text -> Maybe Text
+ Codec.Tiled.Object.Text: [italic] :: Text -> Maybe Bool
+ Codec.Tiled.Object.Text: [kerning] :: Text -> Maybe Bool
+ Codec.Tiled.Object.Text: [pixelSize] :: Text -> Maybe Int
+ Codec.Tiled.Object.Text: [strikeout] :: Text -> Maybe Bool
+ Codec.Tiled.Object.Text: [text] :: Text -> Text
+ Codec.Tiled.Object.Text: [underline] :: Text -> Maybe Bool
+ Codec.Tiled.Object.Text: [vAlign] :: Text -> Maybe Text
+ Codec.Tiled.Object.Text: [wrap] :: Text -> Maybe Bool
+ Codec.Tiled.Object.Text: data Text
+ Codec.Tiled.Object.Text: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Object.Text.Text
+ Codec.Tiled.Object.Text: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Object.Text.Text
+ Codec.Tiled.Object.Text: instance GHC.Classes.Eq Codec.Tiled.Object.Text.Text
+ Codec.Tiled.Object.Text: instance GHC.Generics.Generic Codec.Tiled.Object.Text.Text
+ Codec.Tiled.Object.Text: instance GHC.Show.Show Codec.Tiled.Object.Text.Text
+ Codec.Tiled.Property: Property :: Text -> Maybe Text -> Text -> Value -> Property
+ Codec.Tiled.Property: [name] :: Property -> Text
+ Codec.Tiled.Property: [propertyType] :: Property -> Text
+ Codec.Tiled.Property: [type_] :: Property -> Maybe Text
+ Codec.Tiled.Property: [value] :: Property -> Value
+ Codec.Tiled.Property: data Property
+ Codec.Tiled.Property: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Property.Property
+ Codec.Tiled.Property: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Property.Property
+ Codec.Tiled.Property: instance GHC.Classes.Eq Codec.Tiled.Property.Property
+ Codec.Tiled.Property: instance GHC.Generics.Generic Codec.Tiled.Property.Property
+ Codec.Tiled.Property: instance GHC.Show.Show Codec.Tiled.Property.Property
+ Codec.Tiled.Tileset: Tileset :: Maybe Text -> Int -> Maybe GID -> Maybe Grid -> FilePath -> Int -> Int -> Int -> Text -> Maybe Text -> Maybe (Vector Property) -> Maybe FilePath -> Int -> Maybe (Vector Terrain) -> Int -> Maybe Text -> Int -> Maybe TileOffset -> Maybe (Vector Tile) -> Int -> Maybe Transformations -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe (Vector WangSet) -> Tileset
+ Codec.Tiled.Tileset: [backgroundColor] :: Tileset -> Maybe Text
+ Codec.Tiled.Tileset: [columns] :: Tileset -> Int
+ Codec.Tiled.Tileset: [firstGid] :: Tileset -> Maybe GID
+ Codec.Tiled.Tileset: [grid] :: Tileset -> Maybe Grid
+ Codec.Tiled.Tileset: [imageHeight] :: Tileset -> Int
+ Codec.Tiled.Tileset: [imageWidth] :: Tileset -> Int
+ Codec.Tiled.Tileset: [image] :: Tileset -> FilePath
+ Codec.Tiled.Tileset: [margin] :: Tileset -> Int
+ Codec.Tiled.Tileset: [name] :: Tileset -> Text
+ Codec.Tiled.Tileset: [objectAlignment] :: Tileset -> Maybe Text
+ Codec.Tiled.Tileset: [properties] :: Tileset -> Maybe (Vector Property)
+ Codec.Tiled.Tileset: [source] :: Tileset -> Maybe FilePath
+ Codec.Tiled.Tileset: [spacing] :: Tileset -> Int
+ Codec.Tiled.Tileset: [terrains] :: Tileset -> Maybe (Vector Terrain)
+ Codec.Tiled.Tileset: [tileCount] :: Tileset -> Int
+ Codec.Tiled.Tileset: [tileHeight] :: Tileset -> Int
+ Codec.Tiled.Tileset: [tileOffset] :: Tileset -> Maybe TileOffset
+ Codec.Tiled.Tileset: [tileWidth] :: Tileset -> Int
+ Codec.Tiled.Tileset: [tiledVersion] :: Tileset -> Maybe Text
+ Codec.Tiled.Tileset: [tiles] :: Tileset -> Maybe (Vector Tile)
+ Codec.Tiled.Tileset: [transformations] :: Tileset -> Maybe Transformations
+ Codec.Tiled.Tileset: [transparentColor] :: Tileset -> Maybe Text
+ Codec.Tiled.Tileset: [type_] :: Tileset -> Maybe Text
+ Codec.Tiled.Tileset: [version] :: Tileset -> Maybe Text
+ Codec.Tiled.Tileset: [wangSets] :: Tileset -> Maybe (Vector WangSet)
+ Codec.Tiled.Tileset: data Tileset
+ Codec.Tiled.Tileset: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Tileset
+ Codec.Tiled.Tileset: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Tileset
+ Codec.Tiled.Tileset: instance GHC.Classes.Eq Codec.Tiled.Tileset.Tileset
+ Codec.Tiled.Tileset: instance GHC.Generics.Generic Codec.Tiled.Tileset.Tileset
+ Codec.Tiled.Tileset: instance GHC.Show.Show Codec.Tiled.Tileset.Tileset
+ Codec.Tiled.Tileset.Frame: Frame :: Int -> Int -> Frame
+ Codec.Tiled.Tileset.Frame: [duration] :: Frame -> Int
+ Codec.Tiled.Tileset.Frame: [tileId] :: Frame -> Int
+ Codec.Tiled.Tileset.Frame: data Frame
+ Codec.Tiled.Tileset.Frame: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Frame.Frame
+ Codec.Tiled.Tileset.Frame: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Frame.Frame
+ Codec.Tiled.Tileset.Frame: instance GHC.Classes.Eq Codec.Tiled.Tileset.Frame.Frame
+ Codec.Tiled.Tileset.Frame: instance GHC.Generics.Generic Codec.Tiled.Tileset.Frame.Frame
+ Codec.Tiled.Tileset.Frame: instance GHC.Show.Show Codec.Tiled.Tileset.Frame.Frame
+ Codec.Tiled.Tileset.Grid: Grid :: Int -> Maybe Text -> Int -> Grid
+ Codec.Tiled.Tileset.Grid: [height] :: Grid -> Int
+ Codec.Tiled.Tileset.Grid: [orientation] :: Grid -> Maybe Text
+ Codec.Tiled.Tileset.Grid: [width] :: Grid -> Int
+ Codec.Tiled.Tileset.Grid: data Grid
+ Codec.Tiled.Tileset.Grid: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Grid.Grid
+ Codec.Tiled.Tileset.Grid: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Grid.Grid
+ Codec.Tiled.Tileset.Grid: instance GHC.Classes.Eq Codec.Tiled.Tileset.Grid.Grid
+ Codec.Tiled.Tileset.Grid: instance GHC.Generics.Generic Codec.Tiled.Tileset.Grid.Grid
+ Codec.Tiled.Tileset.Grid: instance GHC.Show.Show Codec.Tiled.Tileset.Grid.Grid
+ Codec.Tiled.Tileset.IO: TilesetError :: Text -> TilesetError
+ Codec.Tiled.Tileset.IO: instance GHC.Classes.Eq Codec.Tiled.Tileset.IO.TilesetError
+ Codec.Tiled.Tileset.IO: instance GHC.Exception.Type.Exception Codec.Tiled.Tileset.IO.TilesetError
+ Codec.Tiled.Tileset.IO: instance GHC.Show.Show Codec.Tiled.Tileset.IO.TilesetError
+ Codec.Tiled.Tileset.IO: newtype TilesetError
+ Codec.Tiled.Tileset.IO: readFile :: MonadIO m => FilePath -> m Tileset
+ Codec.Tiled.Tileset.IO: writeFile :: MonadIO m => FilePath -> Tileset -> m ()
+ Codec.Tiled.Tileset.Ref: TilesetEmbedded :: GID -> Tileset -> TilesetRef
+ Codec.Tiled.Tileset.Ref: TilesetRef :: GID -> FilePath -> TilesetRef
+ Codec.Tiled.Tileset.Ref: [embedded] :: TilesetRef -> Tileset
+ Codec.Tiled.Tileset.Ref: [firstGid] :: TilesetRef -> GID
+ Codec.Tiled.Tileset.Ref: [source] :: TilesetRef -> FilePath
+ Codec.Tiled.Tileset.Ref: data TilesetRef
+ Codec.Tiled.Tileset.Ref: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Ref.TilesetRef
+ Codec.Tiled.Tileset.Ref: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Ref.TilesetRef
+ Codec.Tiled.Tileset.Ref: instance GHC.Classes.Eq Codec.Tiled.Tileset.Ref.TilesetRef
+ Codec.Tiled.Tileset.Ref: instance GHC.Generics.Generic Codec.Tiled.Tileset.Ref.TilesetRef
+ Codec.Tiled.Tileset.Ref: instance GHC.Show.Show Codec.Tiled.Tileset.Ref.TilesetRef
+ Codec.Tiled.Tileset.Terrain: Terrain :: Text -> Maybe (Vector Property) -> Int -> Terrain
+ Codec.Tiled.Tileset.Terrain: [name] :: Terrain -> Text
+ Codec.Tiled.Tileset.Terrain: [properties] :: Terrain -> Maybe (Vector Property)
+ Codec.Tiled.Tileset.Terrain: [tile] :: Terrain -> Int
+ Codec.Tiled.Tileset.Terrain: data Terrain
+ Codec.Tiled.Tileset.Terrain: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Terrain.Terrain
+ Codec.Tiled.Tileset.Terrain: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Terrain.Terrain
+ Codec.Tiled.Tileset.Terrain: instance GHC.Classes.Eq Codec.Tiled.Tileset.Terrain.Terrain
+ Codec.Tiled.Tileset.Terrain: instance GHC.Generics.Generic Codec.Tiled.Tileset.Terrain.Terrain
+ Codec.Tiled.Tileset.Terrain: instance GHC.Show.Show Codec.Tiled.Tileset.Terrain.Terrain
+ Codec.Tiled.Tileset.Tile: Tile :: Maybe (Vector Frame) -> Int -> Maybe FilePath -> Int -> Int -> Maybe Layer -> Maybe Double -> Maybe (Vector Property) -> Maybe (Vector Int) -> Maybe Text -> Tile
+ Codec.Tiled.Tileset.Tile: [animation] :: Tile -> Maybe (Vector Frame)
+ Codec.Tiled.Tileset.Tile: [id] :: Tile -> Int
+ Codec.Tiled.Tileset.Tile: [imageHeight] :: Tile -> Int
+ Codec.Tiled.Tileset.Tile: [imageWidth] :: Tile -> Int
+ Codec.Tiled.Tileset.Tile: [image] :: Tile -> Maybe FilePath
+ Codec.Tiled.Tileset.Tile: [objectGroup] :: Tile -> Maybe Layer
+ Codec.Tiled.Tileset.Tile: [probability] :: Tile -> Maybe Double
+ Codec.Tiled.Tileset.Tile: [properties] :: Tile -> Maybe (Vector Property)
+ Codec.Tiled.Tileset.Tile: [terrain] :: Tile -> Maybe (Vector Int)
+ Codec.Tiled.Tileset.Tile: [type_] :: Tile -> Maybe Text
+ Codec.Tiled.Tileset.Tile: data Tile
+ Codec.Tiled.Tileset.Tile: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Tile.Tile
+ Codec.Tiled.Tileset.Tile: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Tile.Tile
+ Codec.Tiled.Tileset.Tile: instance GHC.Classes.Eq Codec.Tiled.Tileset.Tile.Tile
+ Codec.Tiled.Tileset.Tile: instance GHC.Generics.Generic Codec.Tiled.Tileset.Tile.Tile
+ Codec.Tiled.Tileset.Tile: instance GHC.Show.Show Codec.Tiled.Tileset.Tile.Tile
+ Codec.Tiled.Tileset.TileOffset: TileOffset :: Int -> Int -> TileOffset
+ Codec.Tiled.Tileset.TileOffset: [x] :: TileOffset -> Int
+ Codec.Tiled.Tileset.TileOffset: [y] :: TileOffset -> Int
+ Codec.Tiled.Tileset.TileOffset: data TileOffset
+ Codec.Tiled.Tileset.TileOffset: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.TileOffset.TileOffset
+ Codec.Tiled.Tileset.TileOffset: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.TileOffset.TileOffset
+ Codec.Tiled.Tileset.TileOffset: instance GHC.Classes.Eq Codec.Tiled.Tileset.TileOffset.TileOffset
+ Codec.Tiled.Tileset.TileOffset: instance GHC.Generics.Generic Codec.Tiled.Tileset.TileOffset.TileOffset
+ Codec.Tiled.Tileset.TileOffset: instance GHC.Show.Show Codec.Tiled.Tileset.TileOffset.TileOffset
+ Codec.Tiled.Tileset.Transformations: Transformations :: Maybe Bool -> Maybe Bool -> Maybe Bool -> Maybe Bool -> Transformations
+ Codec.Tiled.Tileset.Transformations: [hFlip] :: Transformations -> Maybe Bool
+ Codec.Tiled.Tileset.Transformations: [preferUntransformed] :: Transformations -> Maybe Bool
+ Codec.Tiled.Tileset.Transformations: [rotate] :: Transformations -> Maybe Bool
+ Codec.Tiled.Tileset.Transformations: [vFlip] :: Transformations -> Maybe Bool
+ Codec.Tiled.Tileset.Transformations: data Transformations
+ Codec.Tiled.Tileset.Transformations: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.Transformations.Transformations
+ Codec.Tiled.Tileset.Transformations: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.Transformations.Transformations
+ Codec.Tiled.Tileset.Transformations: instance GHC.Classes.Eq Codec.Tiled.Tileset.Transformations.Transformations
+ Codec.Tiled.Tileset.Transformations: instance GHC.Generics.Generic Codec.Tiled.Tileset.Transformations.Transformations
+ Codec.Tiled.Tileset.Transformations: instance GHC.Show.Show Codec.Tiled.Tileset.Transformations.Transformations
+ Codec.Tiled.Tileset.WangColor: WangColor :: Text -> Text -> Double -> Maybe (Vector Property) -> Int -> WangColor
+ Codec.Tiled.Tileset.WangColor: [color] :: WangColor -> Text
+ Codec.Tiled.Tileset.WangColor: [name] :: WangColor -> Text
+ Codec.Tiled.Tileset.WangColor: [probability] :: WangColor -> Double
+ Codec.Tiled.Tileset.WangColor: [properties] :: WangColor -> Maybe (Vector Property)
+ Codec.Tiled.Tileset.WangColor: [tile] :: WangColor -> Int
+ Codec.Tiled.Tileset.WangColor: data WangColor
+ Codec.Tiled.Tileset.WangColor: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.WangColor.WangColor
+ Codec.Tiled.Tileset.WangColor: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.WangColor.WangColor
+ Codec.Tiled.Tileset.WangColor: instance GHC.Classes.Eq Codec.Tiled.Tileset.WangColor.WangColor
+ Codec.Tiled.Tileset.WangColor: instance GHC.Generics.Generic Codec.Tiled.Tileset.WangColor.WangColor
+ Codec.Tiled.Tileset.WangColor: instance GHC.Show.Show Codec.Tiled.Tileset.WangColor.WangColor
+ Codec.Tiled.Tileset.WangSet: WangSet :: Vector WangColor -> Text -> Maybe (Vector Property) -> Int -> Text -> Vector WangTile -> WangSet
+ Codec.Tiled.Tileset.WangSet: [colors] :: WangSet -> Vector WangColor
+ Codec.Tiled.Tileset.WangSet: [name] :: WangSet -> Text
+ Codec.Tiled.Tileset.WangSet: [properties] :: WangSet -> Maybe (Vector Property)
+ Codec.Tiled.Tileset.WangSet: [tile] :: WangSet -> Int
+ Codec.Tiled.Tileset.WangSet: [type_] :: WangSet -> Text
+ Codec.Tiled.Tileset.WangSet: [wangTiles] :: WangSet -> Vector WangTile
+ Codec.Tiled.Tileset.WangSet: data WangSet
+ Codec.Tiled.Tileset.WangSet: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.WangSet.WangSet
+ Codec.Tiled.Tileset.WangSet: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.WangSet.WangSet
+ Codec.Tiled.Tileset.WangSet: instance GHC.Classes.Eq Codec.Tiled.Tileset.WangSet.WangSet
+ Codec.Tiled.Tileset.WangSet: instance GHC.Generics.Generic Codec.Tiled.Tileset.WangSet.WangSet
+ Codec.Tiled.Tileset.WangSet: instance GHC.Show.Show Codec.Tiled.Tileset.WangSet.WangSet
+ Codec.Tiled.Tileset.WangTile: WangTile :: Int -> Vector Int -> WangTile
+ Codec.Tiled.Tileset.WangTile: [tileId] :: WangTile -> Int
+ Codec.Tiled.Tileset.WangTile: [wangId] :: WangTile -> Vector Int
+ Codec.Tiled.Tileset.WangTile: data WangTile
+ Codec.Tiled.Tileset.WangTile: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.Tileset.WangTile.WangTile
+ Codec.Tiled.Tileset.WangTile: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.Tileset.WangTile.WangTile
+ Codec.Tiled.Tileset.WangTile: instance GHC.Classes.Eq Codec.Tiled.Tileset.WangTile.WangTile
+ Codec.Tiled.Tileset.WangTile: instance GHC.Generics.Generic Codec.Tiled.Tileset.WangTile.WangTile
+ Codec.Tiled.Tileset.WangTile: instance GHC.Show.Show Codec.Tiled.Tileset.WangTile.WangTile
+ Codec.Tiled.World: World :: Maybe (Vector Map) -> Maybe (Vector Pattern) -> Maybe Text -> Maybe Bool -> World
+ Codec.Tiled.World: [maps] :: World -> Maybe (Vector Map)
+ Codec.Tiled.World: [onlyShowAdjacentMaps] :: World -> Maybe Bool
+ Codec.Tiled.World: [patterns] :: World -> Maybe (Vector Pattern)
+ Codec.Tiled.World: [type_] :: World -> Maybe Text
+ Codec.Tiled.World: data World
+ Codec.Tiled.World: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.World.World
+ Codec.Tiled.World: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.World.World
+ Codec.Tiled.World: instance GHC.Classes.Eq Codec.Tiled.World.World
+ Codec.Tiled.World: instance GHC.Generics.Generic Codec.Tiled.World.World
+ Codec.Tiled.World: instance GHC.Show.Show Codec.Tiled.World.World
+ Codec.Tiled.World.Map: Map :: FilePath -> Int -> Int -> Maybe Int -> Maybe Int -> Map
+ Codec.Tiled.World.Map: [fileName] :: Map -> FilePath
+ Codec.Tiled.World.Map: [height] :: Map -> Maybe Int
+ Codec.Tiled.World.Map: [width] :: Map -> Maybe Int
+ Codec.Tiled.World.Map: [x] :: Map -> Int
+ Codec.Tiled.World.Map: [y] :: Map -> Int
+ Codec.Tiled.World.Map: data Map
+ Codec.Tiled.World.Map: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.World.Map.Map
+ Codec.Tiled.World.Map: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.World.Map.Map
+ Codec.Tiled.World.Map: instance GHC.Classes.Eq Codec.Tiled.World.Map.Map
+ Codec.Tiled.World.Map: instance GHC.Generics.Generic Codec.Tiled.World.Map.Map
+ Codec.Tiled.World.Map: instance GHC.Show.Show Codec.Tiled.World.Map.Map
+ Codec.Tiled.World.Pattern: Pattern :: Text -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Int -> Pattern
+ Codec.Tiled.World.Pattern: [mapHeight] :: Pattern -> Maybe Int
+ Codec.Tiled.World.Pattern: [mapWidth] :: Pattern -> Maybe Int
+ Codec.Tiled.World.Pattern: [multiplierX] :: Pattern -> Int
+ Codec.Tiled.World.Pattern: [multiplierY] :: Pattern -> Int
+ Codec.Tiled.World.Pattern: [offsetX] :: Pattern -> Int
+ Codec.Tiled.World.Pattern: [offsetY] :: Pattern -> Int
+ Codec.Tiled.World.Pattern: [regexp] :: Pattern -> Text
+ Codec.Tiled.World.Pattern: data Pattern
+ Codec.Tiled.World.Pattern: instance Data.Aeson.Types.FromJSON.FromJSON Codec.Tiled.World.Pattern.Pattern
+ Codec.Tiled.World.Pattern: instance Data.Aeson.Types.ToJSON.ToJSON Codec.Tiled.World.Pattern.Pattern
+ Codec.Tiled.World.Pattern: instance GHC.Classes.Eq Codec.Tiled.World.Pattern.Pattern
+ Codec.Tiled.World.Pattern: instance GHC.Generics.Generic Codec.Tiled.World.Pattern.Pattern
+ Codec.Tiled.World.Pattern: instance GHC.Show.Show Codec.Tiled.World.Pattern.Pattern
+ Data.Tiled.GID: Flags :: Bool -> Bool -> Bool -> Bool -> Flags
+ Data.Tiled.GID: GID :: Word32 -> GID
+ Data.Tiled.GID: [flippedHorizontally] :: Flags -> Bool
+ Data.Tiled.GID: [flippedVertically] :: Flags -> Bool
+ Data.Tiled.GID: [getGID] :: GID -> Word32
+ Data.Tiled.GID: [rotated120] :: Flags -> Bool
+ Data.Tiled.GID: [rotated60] :: Flags -> Bool
+ Data.Tiled.GID: data Flags
+ Data.Tiled.GID: flagBits :: Word32
+ Data.Tiled.GID: flags :: GID -> Flags
+ Data.Tiled.GID: fromLocal :: Flags -> Int -> GID
+ Data.Tiled.GID: instance Data.Aeson.Types.FromJSON.FromJSON Data.Tiled.GID.GID
+ Data.Tiled.GID: instance Data.Aeson.Types.ToJSON.ToJSON Data.Tiled.GID.GID
+ Data.Tiled.GID: instance Data.Bits.Bits Data.Tiled.GID.GID
+ Data.Tiled.GID: instance Foreign.Storable.Storable Data.Tiled.GID.GID
+ Data.Tiled.GID: instance GHC.Classes.Eq Data.Tiled.GID.Flags
+ Data.Tiled.GID: instance GHC.Classes.Eq Data.Tiled.GID.GID
+ Data.Tiled.GID: instance GHC.Generics.Generic Data.Tiled.GID.Flags
+ Data.Tiled.GID: instance GHC.Generics.Generic Data.Tiled.GID.GID
+ Data.Tiled.GID: instance GHC.Show.Show Data.Tiled.GID.Flags
+ Data.Tiled.GID: instance GHC.Show.Show Data.Tiled.GID.GID
+ Data.Tiled.GID: newtype GID
+ Data.Tiled.GID: pattern FLIPPED_HORIZONTALLY_BIT :: Int
+ Data.Tiled.GID: pattern FLIPPED_VERTICALLY_BIT :: Int
+ Data.Tiled.GID: pattern ROTATED_120_BIT :: Int
+ Data.Tiled.GID: pattern ROTATED_60_BIT :: Int
+ Data.Tiled.GID: toLocal :: GID -> Int
Files
- ChangeLog.md +5/−0
- README.md +19/−1
- aeson-tiled.cabal +97/−39
- maps/microgue/embedded-zstd.tmj +55/−0
- maps/microgue/external-zstd.tmj +37/−0
- maps/microgue/tiles.tsj +21/−0
- src/Codec/Tiled.hs +44/−0
- src/Codec/Tiled/Aeson.hs +48/−0
- src/Codec/Tiled/Layer.hs +50/−0
- src/Codec/Tiled/Layer/Chunk.hs +21/−0
- src/Codec/Tiled/Layer/Data.hs +32/−0
- src/Codec/Tiled/Map.hs +42/−0
- src/Codec/Tiled/Map/IO.hs +37/−0
- src/Codec/Tiled/Object.hs +38/−0
- src/Codec/Tiled/Object/Point.hs +17/−0
- src/Codec/Tiled/Object/Template.hs +21/−0
- src/Codec/Tiled/Object/Template/IO.hs +37/−0
- src/Codec/Tiled/Object/Text.hs +28/−0
- src/Codec/Tiled/Property.hs +21/−0
- src/Codec/Tiled/Tileset.hs +50/−0
- src/Codec/Tiled/Tileset/Frame.hs +17/−0
- src/Codec/Tiled/Tileset/Grid.hs +19/−0
- src/Codec/Tiled/Tileset/IO.hs +37/−0
- src/Codec/Tiled/Tileset/Ref.hs +48/−0
- src/Codec/Tiled/Tileset/Terrain.hs +21/−0
- src/Codec/Tiled/Tileset/Tile.hs +30/−0
- src/Codec/Tiled/Tileset/TileOffset.hs +17/−0
- src/Codec/Tiled/Tileset/Transformations.hs +19/−0
- src/Codec/Tiled/Tileset/WangColor.hs +23/−0
- src/Codec/Tiled/Tileset/WangSet.hs +26/−0
- src/Codec/Tiled/Tileset/WangTile.hs +18/−0
- src/Codec/Tiled/World.hs +24/−0
- src/Codec/Tiled/World/Map.hs +17/−0
- src/Codec/Tiled/World/Pattern.hs +19/−0
- src/Data/Aeson/Tiled.hs +0/−447
- src/Data/Tiled/GID.hs +64/−0
- test/ParseObjectSpec.hs +0/−22
- test/RoundTripSpec.hs +0/−26
- test/Spec.hs +0/−1
- tests/Main.hs +59/−0
ChangeLog.md view
@@ -1,5 +1,9 @@ # Change Log +## [0.0.2.0] - 2022-05-04++Massive rewrite for Tiled 1.8.+ ## [0.0.1.0] - 2022-02-19 Package moved to https://github.com/haskell-game/aeson-tiled@@ -12,5 +16,6 @@ Initial release. +[0.0.2.0]: https://github.com/haskell-game/aeson-tiled/releases/tag/v0.0.2.0 [0.0.1.0]: https://github.com/haskell-game/aeson-tiled/releases/tag/v0.0.1.0 [0.0.0.1]: https://github.com/haskell-game/aeson-tiled/releases/tag/v0.0.0.1
README.md view
@@ -2,9 +2,27 @@ [](https://hackage.haskell.org/package/aeson-tiled) -Types and instances for [Tiled](https://www.mapeditor.org/) map editor `.tmj` files.+Types and instances for [Tiled](https://www.mapeditor.org/) map editor map/`.tmj` and tileset/`.tsj` files. > `aeson-tiled` is the spiritual successor to `htiled`. > `htiled` uses `hxt` which relies too heavily on Arrows and is rather hard to work with. > Tiled's json export supports 100% of Tiled's features, so there doesn't seem to be much of a point to maintaining a large Arrows-based project when writing Aeson instances for Tiled types is much easier. > Hence this project!++The package is geared toward minimal divergence from Tiled type specifications.++Tiled data format is taken at version 1.8.4.+Should be compatible down to 1.6 (where the `version` field changed to string).++GHC versions are supported from 8.10 and follow Stackage LTS + Stackage Nightly + whatever is available on `ghcup`.++## Module structure++The modules are designed for qualified imports and `OverloadedRecordDot` extension.+Everyone has a `Generic` instance so you can use `generic-lens` or `generic-optics` if you wish.++- Modules under `Codec.Tiled.*` are concerned with `aeson` representation, one type at a time.+ They provide JSON `Value` translation to concrete types, but not much beyond that.+ Your application most likely should use its own representation.+- Modules under `Data.Tiled.*` are types specific to this package.+ They are more refined and may be utilized directly.
aeson-tiled.cabal view
@@ -1,33 +1,79 @@-name: aeson-tiled-version: 0.0.1.0-synopsis: Aeson instances for the Tiled map editor.-description: The mighty Tiled 2D map editor is an open source- app for creating tile based level maps. This package provides- types and aeson instances to read Tiled json files.-homepage: https://github.com/haskell-game/aeson-tiled-license: BSD3-license-file: LICENSE-maintainer: aenor.realm@gmai.com-author: Schell Scivally-copyright: (c) 2017 Schell Scivally-category: Game Engine-build-type: Simple-cabal-version: >=1.10+cabal-version: 3.0+name: aeson-tiled+version: 0.0.2.0+synopsis: Aeson instances for the Tiled map editor.+description:+ The mighty Tiled 2D map editor is an open source+ app for creating tile based level maps. This package provides+ types and aeson instances to read Tiled json files.+homepage: https://github.com/haskell-game/aeson-tiled+license: BSD-3-Clause+license-file: LICENSE+maintainer: aenor.realm@gmai.com+author: Schell Scivally+copyright: (c) 2017 Schell Scivally+category: Game Engine+build-type: Simple extra-source-files: README.md,- ChangeLog.md+ ChangeLog.md,+ maps/microgue/*.tmj,+ maps/microgue/*.tsj library- hs-source-dirs: src- exposed-modules: Data.Aeson.Tiled- build-depends: base >= 4.7 && < 5- , bytestring >= 0.10 && < 1- , aeson >= 1.0 && < 3- , containers >= 0.5 && < 1- , text >= 1.2 && < 3- , vector >= 0.11 && < 1- default-language: Haskell2010+ hs-source-dirs: src+ exposed-modules:+ Codec.Tiled+ Codec.Tiled.Aeson+ Codec.Tiled.Layer+ Codec.Tiled.Layer.Chunk+ Codec.Tiled.Layer.Data+ Codec.Tiled.Map+ Codec.Tiled.Map.IO+ Codec.Tiled.Object+ Codec.Tiled.Object.Point+ Codec.Tiled.Object.Template+ Codec.Tiled.Object.Template.IO+ Codec.Tiled.Object.Text+ Codec.Tiled.Property+ Codec.Tiled.Tileset+ Codec.Tiled.Tileset.Frame+ Codec.Tiled.Tileset.Grid+ Codec.Tiled.Tileset.IO+ Codec.Tiled.Tileset.Ref+ Codec.Tiled.Tileset.Terrain+ Codec.Tiled.Tileset.Tile+ Codec.Tiled.Tileset.TileOffset+ Codec.Tiled.Tileset.Transformations+ Codec.Tiled.Tileset.WangColor+ Codec.Tiled.Tileset.WangSet+ Codec.Tiled.Tileset.WangTile+ Codec.Tiled.World+ Codec.Tiled.World.Map+ Codec.Tiled.World.Pattern+ Data.Tiled.GID+ build-depends:+ base >= 4.7 && < 5+ , bytestring >= 0.10 && < 1+ , aeson >= 1.0 && < 3+ , containers >= 0.5 && < 1+ , text >= 1.2 && < 3+ , vector >= 0.11 && < 1+ default-language:+ Haskell2010+ default-extensions:+ BlockArguments,+ DeriveGeneric,+ DerivingStrategies,+ FlexibleContexts,+ GeneralizedNewtypeDeriving,+ ImportQualifiedPost,+ LambdaCase,+ OverloadedStrings,+ PatternSynonyms,+ RecordWildCards,+ StrictData, flag tests manual: True@@ -36,17 +82,29 @@ test-suite aeson-tiled-test if !flag(tests) buildable: False- type: exitcode-stdio-1.0- hs-source-dirs: test- main-is: Spec.hs- build-depends: base- , aeson >= 1.1- , aeson-tiled- , hspec- , hspec-discover- , bytestring- ghc-options: -threaded -rtsopts -with-rtsopts=-N- default-language: Haskell2010- other-modules:- ParseObjectSpec- RoundTripSpec+ type: exitcode-stdio-1.0+ hs-source-dirs: tests+ main-is: Main.hs+ build-depends:+ aeson-tiled,+ base,+ filepath,+ tasty-hunit,+ tasty,+ temporary++ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ default-language:+ Haskell2010+ default-extensions:+ BlockArguments,+ DeriveGeneric,+ DerivingStrategies,+ FlexibleContexts,+ GeneralizedNewtypeDeriving,+ ImportQualifiedPost,+ LambdaCase,+ OverloadedStrings,+ PatternSynonyms,+ RecordWildCards,+ StrictData,
+ maps/microgue/embedded-zstd.tmj view
@@ -0,0 +1,55 @@+{+ "compressionlevel": -1,+ "height": 16,+ "infinite": false,+ "layers": [+ {+ "compression": "zstd",+ "data": "KLUv\/WAAA7UHAFLJGyiAx5kDM8BblCAjKCIixr341LpkwIWrp5ThlTG\/Azb16VQXuqva\/d9SX1B4AgJABLu2Dygq5PHEHZI7E7D0rAsMPNqQ+7HcFeO9OeaLBqWaXKNA\/BA1nMHRCk7gnK0STW\/3yS3J7ryhZzfAfrnlVz+gkVUK6hS00hqgAqKhowPnELMDPDqeTnZdiCFtpwcaj92HaqMQEyWL8C4PYAS\/6WwedAdUsJ1Kf5JZQBoSHK8Gfb2YO8znYIyMtG2wcWVZDuhdN2SGFwxFcAhnQBoD67xGQ9DVoVGTwbIOUW7f6R9PZts4qG\/nRiWz1iEe6EI1qjh6ag==",+ "encoding": "base64",+ "height": 16,+ "id": 1,+ "name": "Calque de Tuiles 1",+ "opacity": 1,+ "type": "tilelayer",+ "visible": true,+ "width": 16,+ "x": 0,+ "y": 0+ }+ ],+ "nextlayerid": 2,+ "nextobjectid": 1,+ "orientation": "orthogonal",+ "renderorder": "right-down",+ "tiledversion": "1.8.4",+ "tileheight": 8,+ "tilesets": [+ {+ "firstgid": 1,+ "columns": 16,+ "image": "tiles.png",+ "imageheight": 80,+ "imagewidth": 128,+ "margin": 0,+ "name": "microtest",+ "spacing": 0,+ "tilecount": 160,+ "tiledversion": "1.8.4",+ "tileheight": 8,+ "tilewidth": 8,+ "transformations": {+ "hflip": false,+ "preferuntransformed": true,+ "rotate": true,+ "vflip": false+ },+ "type": "tileset",+ "version": "1.8"+ }+ ],+ "tilewidth": 8,+ "type": "map",+ "version": "1.8",+ "width": 16+}
+ maps/microgue/external-zstd.tmj view
@@ -0,0 +1,37 @@+{+ "compressionlevel": -1,+ "height": 16,+ "infinite": false,+ "layers": [+ {+ "compression": "zstd",+ "data": "KLUv\/WAAA7UHAFLJGyiAx5kDM8BblCAjKCIixr341LpkwIWrp5ThlTG\/Azb16VQXuqva\/d9SX1B4AgJABLu2Dygq5PHEHZI7E7D0rAsMPNqQ+7HcFeO9OeaLBqWaXKNA\/BA1nMHRCk7gnK0STW\/3yS3J7ryhZzfAfrnlVz+gkVUK6hS00hqgAqKhowPnELMDPDqeTnZdiCFtpwcaj92HaqMQEyWL8C4PYAS\/6WwedAdUsJ1Kf5JZQBoSHK8Gfb2YO8znYIyMtG2wcWVZDuhdN2SGFwxFcAhnQBoD67xGQ9DVoVGTwbIOUW7f6R9PZts4qG\/nRiWz1iEe6EI1qjh6ag==",+ "encoding": "base64",+ "height": 16,+ "id": 1,+ "name": "Calque de Tuiles 1",+ "opacity": 1,+ "type": "tilelayer",+ "visible": true,+ "width": 16,+ "x": 0,+ "y": 0+ }+ ],+ "nextlayerid": 2,+ "nextobjectid": 1,+ "orientation": "orthogonal",+ "renderorder": "right-down",+ "tiledversion": "1.8.4",+ "tileheight": 8,+ "tilesets": [+ {+ "firstgid": 1,+ "source": "tiles.tsj"+ }+ ],+ "tilewidth": 8,+ "type": "map",+ "version": "1.8",+ "width": 16+}
+ maps/microgue/tiles.tsj view
@@ -0,0 +1,21 @@+{+ "columns": 16,+ "image": "tiles.png",+ "imageheight": 80,+ "imagewidth": 128,+ "margin": 0,+ "name": "microtest",+ "spacing": 0,+ "tilecount": 160,+ "tiledversion": "1.8.4",+ "tileheight": 8,+ "tilewidth": 8,+ "transformations": {+ "hflip": false,+ "preferuntransformed": true,+ "rotate": true,+ "vflip": false+ },+ "type": "tileset",+ "version": "1.8"+}
+ src/Codec/Tiled.hs view
@@ -0,0 +1,44 @@+module Codec.Tiled+ ( Chunk+ , Frame+ , Grid+ , Layer+ , LayerData+ , Map+ , Object+ , Point+ , Property+ , Template+ , Terrain+ , Text+ , Tile+ , TileOffset+ , Tileset+ , Transformations+ , WangColor+ , WangSet+ , WangTile++ , GID+ ) where++import Codec.Tiled.Layer (Layer)+import Codec.Tiled.Layer.Chunk (Chunk)+import Codec.Tiled.Layer.Data (LayerData)+import Codec.Tiled.Map (Map)+import Codec.Tiled.Object (Object)+import Codec.Tiled.Object.Point (Point)+import Codec.Tiled.Object.Template (Template)+import Codec.Tiled.Object.Text (Text)+import Codec.Tiled.Property (Property)+import Codec.Tiled.Tileset (Tileset)+import Codec.Tiled.Tileset.Frame (Frame)+import Codec.Tiled.Tileset.Grid (Grid)+import Codec.Tiled.Tileset.Terrain (Terrain)+import Codec.Tiled.Tileset.Tile (Tile)+import Codec.Tiled.Tileset.TileOffset (TileOffset)+import Codec.Tiled.Tileset.Transformations (Transformations)+import Codec.Tiled.Tileset.WangColor (WangColor)+import Codec.Tiled.Tileset.WangSet (WangSet)+import Codec.Tiled.Tileset.WangTile (WangTile)+import Data.Tiled.GID (GID)
+ src/Codec/Tiled/Aeson.hs view
@@ -0,0 +1,48 @@+module Codec.Tiled.Aeson+ ( FromJSON(..)+ , ToJSON(..)+ , genericParseJSON+ , genericToJSON+ , mkOptions+ , remapFields+ , remapFields_+ )+ where++import Data.Aeson (FromJSON(..), ToJSON(..))+import Data.Aeson qualified as Aeson+import Data.Aeson.Types (Parser)+import Data.Char (toLower)+import Data.List (dropWhileEnd)+import GHC.Generics (Generic, Rep)++genericParseJSON+ :: ( Generic a+ , Aeson.GFromJSON Aeson.Zero (Rep a)+ )+ => Aeson.Value+ -> Parser a+genericParseJSON = Aeson.genericParseJSON (mkOptions remapFields)++genericToJSON+ :: ( Generic a+ , Aeson.GToJSON' Aeson.Value Aeson.Zero (Rep a)+ )+ => a+ -> Aeson.Value+genericToJSON = Aeson.genericToJSON (mkOptions remapFields)++mkOptions :: (String -> String) -> Aeson.Options+mkOptions fieldMods = Aeson.defaultOptions+ { Aeson.fieldLabelModifier = fieldMods+ , Aeson.omitNothingFields = True+ , Aeson.rejectUnknownFields = False+ }++-- | Drop trailing @_@ and convert field names to lowercase.+remapFields :: String -> String+remapFields = remapFields_ . map toLower++-- | Only drop trailing @_@.+remapFields_ :: String -> String+remapFields_ = dropWhileEnd (== '_')
+ src/Codec/Tiled/Layer.hs view
@@ -0,0 +1,50 @@+module Codec.Tiled.Layer where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Layer.Chunk (Chunk)+import Codec.Tiled.Layer.Data (LayerData)+import Codec.Tiled.Object (Object)+import Codec.Tiled.Property (Property)++data Layer = Layer+ { chunks :: Maybe (Vector Chunk) -- ^ Array of chunks (optional). tilelayer only.+ , compression :: Maybe Text -- ^ @zlib@, @gzip@, @zstd@ or empty (default). tilelayer only.+ , data_ :: Maybe LayerData -- ^ Array of unsigned int (GIDs) or base64-encoded data. tilelayer only.+ , draworder :: Maybe Text -- ^ @topdown@ (default) or @index@. objectgroup only.+ , encoding :: Maybe Text -- ^ @csv@ (default) or @base64@. tilelayer only.+ , height :: Maybe Int -- ^ Row count. Same as map height for fixed-size maps.+ , id :: Maybe Int -- ^ Incremental ID - unique across all layers+ , image :: Maybe FilePath -- ^ Image used by this layer. imagelayer only.+ , layers :: Maybe (Vector Layer) -- ^ Array of layers. group only.+ , locked :: Maybe Bool -- ^ Whether layer is locked in the editor (default: false). (since Tiled 1.8.2)+ , name :: Text -- ^ Name assigned to this layer+ , objects :: Maybe (Vector Object) -- ^ Array of objects. objectgroup only.+ , offsetX :: Maybe Double -- ^ Horizontal layer offset in pixels (default: 0)+ , offsetY :: Maybe Double -- ^ Vertical layer offset in pixels (default: 0)+ , opacity :: Double -- ^ Value between 0 and 1.+ , parallaxX :: Maybe Double -- ^ Horizontal parallax factor for this layer (default: 1).+ , parallaxY :: Maybe Double -- ^ Vertical parallax factor for this layer (default: 1).+ , properties :: Maybe (Vector Property) -- ^ Array of Properties+ , repeatX :: Maybe Bool -- ^ Whether the image drawn by this layer is repeated along the X axis. imagelayer only.+ , repeatY :: Maybe Bool -- ^ Whether the image drawn by this layer is repeated along the Y axis. imagelayer only.+ , startX :: Maybe Int -- ^ X coordinate where layer content starts (for infinite maps)+ , startY :: Maybe Int -- ^ Y coordinate where layer content starts (for infinite maps)+ , tintColor :: Maybe Text -- ^ Hex-formatted tint color (#RRGGBB or #AARRGGBB) that is multiplied with any graphics drawn by this layer or any child layers (optional).+ , transparentColor :: Maybe Text -- ^ Hex-formatted color (#RRGGBB) (optional). imagelayer only.+ , type_ :: Text -- ^ @tilelayer@, @objectgroup@, @imagelayer@ or @group@+ , visible :: Bool -- ^ Whether layer is shown or hidden in editor+ , width :: Maybe Int -- ^ Column count. Same as map width for fixed-size maps.+ , x :: Maybe Int -- ^ Horizontal layer offset in tiles. Always 0.+ , y :: Maybe Int -- ^ Vertical layer offset in tiles. Always 0.+ }+ deriving (Eq, Show, Generic)++instance FromJSON Layer where+ parseJSON = genericParseJSON++instance ToJSON Layer where+ toJSON = genericToJSON
+ src/Codec/Tiled/Layer/Chunk.hs view
@@ -0,0 +1,21 @@+module Codec.Tiled.Layer.Chunk where++import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Layer.Data (LayerData)++data Chunk = Chunk+ { data_ :: LayerData -- ^ Array of unsigned int (GIDs) or base64-encoded data+ , height :: Int -- ^ Height in tiles+ , width :: Int -- ^ Width in tiles+ , x :: Int -- ^ X coordinate in tiles+ , y :: Int -- ^ Y coordinate in tiles+ }+ deriving (Eq, Show, Generic)++instance FromJSON Chunk where+ parseJSON = genericParseJSON++instance ToJSON Chunk where+ toJSON = genericToJSON
+ src/Codec/Tiled/Layer/Data.hs view
@@ -0,0 +1,32 @@+module Codec.Tiled.Layer.Data where++import Control.Applicative ((<|>))+import Data.Aeson (FromJSON(..), ToJSON(..), withArray, withText)+import Data.Text (Text)+import Data.Vector.Storable qualified as Storable+import GHC.Generics (Generic)++import Data.Tiled.GID (GID)++data LayerData+ = Base64 Text+ | GIDs (Storable.Vector GID)+ deriving (Eq, Show, Generic)++instance FromJSON LayerData where+ parseJSON v = encoded v <|> csv v+ where+ encoded =+ withText "Base64" $+ pure . Base64++ csv =+ withArray "GIDs" $+ fmap (GIDs . Storable.convert) . traverse parseJSON++instance ToJSON LayerData where+ toJSON = \case+ Base64 text ->+ toJSON text+ GIDs ints ->+ toJSON ints
+ src/Codec/Tiled/Map.hs view
@@ -0,0 +1,42 @@+module Codec.Tiled.Map where++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Layer (Layer)+import Codec.Tiled.Property (Property)+import Codec.Tiled.Tileset.Ref (TilesetRef)++data Map = Map+ { backgroundColor :: Maybe Text -- ^ Hex-formatted color (#RRGGBB or #AARRGGBB) (optional)+ , compressionLevel :: Maybe Int -- ^ The compression level to use for tile layer data (defaults to -1, which means to use the algorithm default)+ , height :: Int -- ^ Number of tile rows+ , hexSideLength :: Maybe Int -- ^ Length of the side of a hex tile in pixels (hexagonal maps only)+ , infinite :: Maybe Bool -- ^ Whether the map has infinite dimensions+ , layers :: Vector Layer -- ^ Array of Layers+ , nextLayerId :: Int -- ^ Auto-increments for each layer+ , nextObjectId :: Int -- ^ Auto-increments for each placed object+ , orientation :: Text -- ^ @orthogonal@, @isometric@, @staggered@ or @hexagonal@+ , parallaxOriginX :: Maybe Double -- ^ X coordinate of the parallax origin in pixels (default: 0)+ , parallaxOriginY :: Maybe Double -- ^ Y coordinate of the parallax origin in pixels (default: 0)+ , properties :: Maybe (Vector Property) -- ^ Array of Properties+ , renderOrder :: Maybe Text -- ^ @right-down@ (the default), @right-up@, @left-down@ or @left-up@ (currently only supported for orthogonal maps)+ , staggerAxis :: Maybe Text -- ^ x or y (staggered / hexagonal maps only)+ , staggerIndex :: Maybe Text -- ^ odd or even (staggered / hexagonal maps only)+ , tiledVersion :: Text -- ^ The Tiled version used to save the file+ , tileHeight :: Int -- ^ Map grid height+ , tilesets :: Vector TilesetRef -- ^ Array of Tilesets+ , tileWidth :: Int -- ^ Map grid width+ , type_ :: Text -- ^ @map@+ , version :: Text -- ^ The JSON format version+ , width :: Int -- ^ Number of tile columns+ }+ deriving (Eq, Show, Generic)++instance FromJSON Map where+ parseJSON = genericParseJSON++instance ToJSON Map where+ toJSON = genericToJSON
+ src/Codec/Tiled/Map/IO.hs view
@@ -0,0 +1,37 @@+module Codec.Tiled.Map.IO+ ( MapError(..)+ , readFile+ , writeFile+ ) where++import Prelude hiding (readFile, writeFile)++import Control.Exception (Exception, throwIO)+import Control.Monad.IO.Class (MonadIO(..))+import Data.Aeson qualified as Aeson+import Data.ByteString (ByteString)+import Data.ByteString qualified as ByteString+import Data.Text (Text)+import Data.Text qualified as Text++import Codec.Tiled.Map (Map)++newtype MapError = MapError Text+ deriving (Eq, Show)++instance Exception MapError++readFile :: MonadIO m => FilePath -> m Map+readFile source = liftIO do+ bytes <- ByteString.readFile source+ case decodeMap bytes of+ Left msg ->+ throwIO $ MapError (Text.pack msg)+ Right res ->+ pure res++decodeMap :: ByteString -> Either String Map+decodeMap = Aeson.eitherDecodeStrict'++writeFile :: MonadIO m => FilePath -> Map -> m ()+writeFile destination = liftIO . Aeson.encodeFile destination
+ src/Codec/Tiled/Object.hs view
@@ -0,0 +1,38 @@+module Codec.Tiled.Object where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Object.Point (Point)+import Codec.Tiled.Object.Text qualified as Object (Text)+import Codec.Tiled.Property (Property)+import Data.Tiled.GID (GID)++data Object = Object+ { ellipse :: Maybe Bool -- ^ Used to mark an object as an ellipse+ , gid :: Maybe GID -- ^ Global tile ID, only if object represents a tile+ , height :: Double -- ^ Height in pixels.+ , id :: Int -- ^ Incremental ID, unique across all objects+ , name :: Text -- ^ String assigned to name field in editor+ , point :: Maybe Bool -- ^ Used to mark an object as a point+ , polygon :: Maybe (Vector Point) -- ^ Array of Points, in case the object is a polygon+ , polyline :: Maybe (Vector Point) -- ^ Array of Points, in case the object is a polyline+ , properties :: Maybe (Vector Property) -- ^ Array of Properties+ , rotation :: Double -- ^ Angle in degrees clockwise+ , template :: Maybe FilePath -- ^ Reference to a template file, in case object is a template instance+ , text :: Maybe Object.Text -- ^ Only used for text objects+ , type_ :: Text -- ^ String assigned to type field in editor+ , visible :: Bool -- ^ Whether object is shown in editor.+ , width :: Double -- ^ Width in pixels.+ , x :: Double -- ^ X coordinate in pixels+ , y :: Double -- ^ Y coordinate in pixels+ }+ deriving (Eq, Show, Generic)++instance FromJSON Object where+ parseJSON = genericParseJSON++instance ToJSON Object where+ toJSON = genericToJSON
+ src/Codec/Tiled/Object/Point.hs view
@@ -0,0 +1,17 @@+module Codec.Tiled.Object.Point where++import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data Point = Point+ { x :: Double -- ^ X coordinate in pixels+ , y :: Double -- ^ Y coordinate in pixels+ }+ deriving (Eq, Show, Generic)++instance FromJSON Point where+ parseJSON = genericParseJSON++instance ToJSON Point where+ toJSON = genericToJSON
+ src/Codec/Tiled/Object/Template.hs view
@@ -0,0 +1,21 @@+module Codec.Tiled.Object.Template where++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Data.Text (Text)+import GHC.Generics (Generic)++import Codec.Tiled.Object (Object)+import Codec.Tiled.Tileset (Tileset)++data Template = Template+ { type_ :: Text -- ^ template+ , tileset :: Maybe Tileset -- ^ External tileset used by the template (optional)+ , object :: Object -- ^ The object instantiated by this template+ }+ deriving (Eq, Show, Generic)++instance FromJSON Template where+ parseJSON = genericParseJSON++instance ToJSON Template where+ toJSON = genericToJSON
+ src/Codec/Tiled/Object/Template/IO.hs view
@@ -0,0 +1,37 @@+module Codec.Tiled.Object.Template.IO+ ( TemplateError(..)+ , readFile+ , writeFile+ ) where++import Prelude hiding (readFile, writeFile)++import Control.Exception (Exception, throwIO)+import Control.Monad.IO.Class (MonadIO(..))+import Data.Aeson qualified as Aeson+import Data.ByteString (ByteString)+import Data.ByteString qualified as ByteString+import Data.Text (Text)+import Data.Text qualified as Text++import Codec.Tiled.Object.Template (Template)++newtype TemplateError = TemplateError Text+ deriving (Eq, Show)++instance Exception TemplateError++readFile :: MonadIO m => FilePath -> m Template+readFile source = liftIO do+ bytes <- ByteString.readFile source+ case decodeMap bytes of+ Left msg ->+ throwIO $ TemplateError (Text.pack msg)+ Right res ->+ pure res++decodeMap :: ByteString -> Either String Template+decodeMap = Aeson.eitherDecodeStrict'++writeFile :: MonadIO m => FilePath -> Template -> m ()+writeFile destination = liftIO . Aeson.encodeFile destination
+ src/Codec/Tiled/Object/Text.hs view
@@ -0,0 +1,28 @@+module Codec.Tiled.Object.Text where++import Data.Text qualified as The+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data Text = Text+ { bold :: Maybe Bool -- ^ Whether to use a bold font (default: false)+ , color :: Maybe The.Text -- ^ Hex-formatted color (#RRGGBB or #AARRGGBB) (default: #000000)+ , fontFamily :: Maybe The.Text -- ^ Font family (default: sans-serif)+ , hAlign :: Maybe The.Text -- ^ Horizontal alignment (center, right, justify or left (default))+ , italic :: Maybe Bool -- ^ Whether to use an italic font (default: false)+ , kerning :: Maybe Bool -- ^ Whether to use kerning when placing characters (default: true)+ , pixelSize :: Maybe Int -- ^ Pixel size of font (default: 16)+ , strikeout :: Maybe Bool -- ^ Whether to strike out the text (default: false)+ , text :: The.Text -- ^ Text+ , underline :: Maybe Bool -- ^ Whether to underline the text (default: false)+ , vAlign :: Maybe The.Text -- ^ Vertical alignment (center, bottom or top (default))+ , wrap :: Maybe Bool -- ^ Whether the text is wrapped within the object bounds (default: false)+ }+ deriving (Eq, Show, Generic)++instance FromJSON Text where+ parseJSON = genericParseJSON++instance ToJSON Text where+ toJSON = genericToJSON
+ src/Codec/Tiled/Property.hs view
@@ -0,0 +1,21 @@+module Codec.Tiled.Property where++import Data.Aeson (Value)+import Data.Text (Text)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data Property = Property+ { name :: Text -- ^ Name of the property+ , type_ :: Maybe Text -- ^ Type of the property (@string@ (default), @int@, @float@, @bool@, @color@, @file@, @object@ or @class@)+ , propertyType :: Text -- ^ Name of the custom property type, when applicable+ , value :: Value -- ^ Value of the property+ }+ deriving (Eq, Show, Generic)++instance FromJSON Property where+ parseJSON = genericParseJSON++instance ToJSON Property where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset.hs view
@@ -0,0 +1,50 @@+module Codec.Tiled.Tileset where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Property (Property)+import Codec.Tiled.Tileset.Grid (Grid)+import Codec.Tiled.Tileset.Terrain (Terrain)+import Codec.Tiled.Tileset.Tile (Tile)+import Codec.Tiled.Tileset.TileOffset (TileOffset)+import Codec.Tiled.Tileset.Transformations (Transformations)+import Codec.Tiled.Tileset.WangSet (WangSet)+import Data.Tiled.GID (GID)++data Tileset = Tileset+ { backgroundColor :: Maybe Text -- ^ Hex-formatted color (#RRGGBB or #AARRGGBB) (optional)+ , columns :: Int -- ^ The number of tile columns in the tileset+ , firstGid :: Maybe GID -- ^ GID corresponding to the first tile in the set+ , grid :: Maybe Grid -- ^ (optional)+ , image :: FilePath -- ^ Image used for tiles in this set+ , imageHeight :: Int -- ^ Height of source image in pixels+ , imageWidth :: Int -- ^ Width of source image in pixels+ , margin :: Int -- ^ Buffer between image edge and first tile (pixels)+ , name :: Text -- ^ Name given to this tileset+ , objectAlignment :: Maybe Text -- ^ Alignment to use for tile objects (unspecified (default), @topleft@, @top@, @topright@, @left@, @center@, @right@, @bottomleft@, @bottom@ or @bottomright@)+ , properties :: Maybe (Vector Property) -- ^ Array of Properties+ , source :: Maybe FilePath -- ^ The external file that contains this tilesets data+ , spacing :: Int -- ^ Spacing between adjacent tiles in image (pixels)+ , terrains :: Maybe (Vector Terrain) -- ^ Array of Terrains (optional)+ , tileCount :: Int -- ^ The number of tiles in this tileset+ , tiledVersion :: Maybe Text -- ^ The Tiled version used to save the file+ , tileHeight :: Int -- ^ Maximum height of tiles in this set+ , tileOffset :: Maybe TileOffset -- ^ (optional)+ , tiles :: Maybe (Vector Tile) -- ^ Array of Tiles (optional)+ , tileWidth :: Int -- ^ Maximum width of tiles in this set+ , transformations :: Maybe Transformations -- ^ Allowed transformations (optional)+ , transparentColor :: Maybe Text -- ^ Hex-formatted color (#RRGGBB) (optional)+ , type_ :: Maybe Text -- ^ @tileset@ (for tileset files)+ , version :: Maybe Text -- ^ The JSON format version+ , wangSets :: Maybe (Vector WangSet) -- ^ Array of Wang sets+ }+ deriving (Eq, Show, Generic)++instance FromJSON Tileset where+ parseJSON = genericParseJSON++instance ToJSON Tileset where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/Frame.hs view
@@ -0,0 +1,17 @@+module Codec.Tiled.Tileset.Frame where++import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data Frame = Frame+ { duration :: Int -- ^ Frame duration in milliseconds+ , tileId :: Int -- ^ Local tile ID representing this frame+ }+ deriving (Eq, Show, Generic)++instance FromJSON Frame where+ parseJSON = genericParseJSON++instance ToJSON Frame where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/Grid.hs view
@@ -0,0 +1,19 @@+module Codec.Tiled.Tileset.Grid where++import Data.Text (Text)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data Grid = Grid+ { height :: Int -- ^ Cell height of tile grid+ , orientation :: Maybe Text -- ^ orthogonal (default) or isometric+ , width :: Int -- ^ Cell width of tile grid+ }+ deriving (Eq, Show, Generic)++instance FromJSON Grid where+ parseJSON = genericParseJSON++instance ToJSON Grid where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/IO.hs view
@@ -0,0 +1,37 @@+module Codec.Tiled.Tileset.IO+ ( TilesetError(..)+ , readFile+ , writeFile+ ) where++import Prelude hiding (readFile, writeFile)++import Control.Exception (Exception, throwIO)+import Control.Monad.IO.Class (MonadIO(..))+import Data.Aeson qualified as Aeson+import Data.ByteString (ByteString)+import Data.ByteString qualified as ByteString+import Data.Text (Text)+import Data.Text qualified as Text++import Codec.Tiled.Tileset (Tileset)++newtype TilesetError = TilesetError Text+ deriving (Eq, Show)++instance Exception TilesetError++readFile :: MonadIO m => FilePath -> m Tileset+readFile source = liftIO do+ bytes <- ByteString.readFile source+ case decodeMap bytes of+ Left msg ->+ throwIO $ TilesetError (Text.pack msg)+ Right res ->+ pure res++decodeMap :: ByteString -> Either String Tileset+decodeMap = Aeson.eitherDecodeStrict'++writeFile :: MonadIO m => FilePath -> Tileset -> m ()+writeFile destination = liftIO . Aeson.encodeFile destination
+ src/Codec/Tiled/Tileset/Ref.hs view
@@ -0,0 +1,48 @@+module Codec.Tiled.Tileset.Ref where++import Control.Applicative ((<|>))+import Data.Aeson (FromJSON(..), ToJSON(..), (.:), (.=))+import Data.Aeson.KeyMap qualified as KeyMap+import Data.Aeson qualified as Aeson+import GHC.Generics (Generic)++import Codec.Tiled.Tileset (Tileset)+import Data.Tiled.GID (GID)++data TilesetRef+ = TilesetRef+ { firstGid :: GID -- ^ GID corresponding to the first tile in the set+ , source :: FilePath -- ^ The external file that contains this tilesets data+ }+ | TilesetEmbedded+ { firstGid :: GID+ , embedded :: Tileset+ }+ deriving (Eq, Show, Generic)++instance FromJSON TilesetRef where+ parseJSON v = refP v <|> embeddedP v+ where+ refP = Aeson.withObject "TilesetRef" \o -> do+ source <- o .: "source"+ firstGid <- o .: "firstgid"+ pure TilesetRef{..}++ embeddedP = Aeson.withObject "TilesetEmbedded" \o -> do+ embedded <- parseJSON (Aeson.Object o)+ firstGid <- o .: "firstgid"+ pure TilesetEmbedded{..}++instance ToJSON TilesetRef where+ toJSON = \case+ TilesetRef{..} -> Aeson.object+ [ "firstgid" .= firstGid+ , "source" .= source+ ]+ TilesetEmbedded{..} ->+ case toJSON embedded of+ Aeson.Object o ->+ Aeson.Object $+ KeyMap.insert "firstGid" (toJSON firstGid) o+ _nonObject ->+ error "assert: TilesetRef is Object"
+ src/Codec/Tiled/Tileset/Terrain.hs view
@@ -0,0 +1,21 @@+module Codec.Tiled.Tileset.Terrain where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Property (Property)++data Terrain = Terrain+ { name :: Text -- ^ Name of terrain+ , properties :: Maybe (Vector Property) -- ^ array Array of Properties+ , tile :: Int -- ^ Local ID of tile representing terrain+ }+ deriving (Eq, Show, Generic)++instance FromJSON Terrain where+ parseJSON = genericParseJSON++instance ToJSON Terrain where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/Tile.hs view
@@ -0,0 +1,30 @@+module Codec.Tiled.Tileset.Tile where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Layer (Layer)+import Codec.Tiled.Property (Property)+import Codec.Tiled.Tileset.Frame (Frame)++data Tile = Tile+ { animation :: Maybe (Vector Frame) -- ^ Array of Frames+ , id :: Int -- ^ Local ID of the tile+ , image :: Maybe FilePath -- ^ Image representing this tile (optional)+ , imageHeight :: Int -- ^ Height of the tile image in pixels+ , imageWidth :: Int -- ^ Width of the tile image in pixels+ , objectGroup :: Maybe Layer -- ^ Layer with type objectgroup, when collision shapes are specified (optional)+ , probability :: Maybe Double -- ^ Percentage chance this tile is chosen when competing with others in the editor (optional)+ , properties :: Maybe (Vector Property) -- ^ Array of Properties+ , terrain :: Maybe (Vector Int) -- ^ Index of terrain for each corner of tile (optional)+ , type_ :: Maybe Text -- ^ The type of the tile (optional)+ }+ deriving (Eq, Show, Generic)++instance FromJSON Tile where+ parseJSON = genericParseJSON++instance ToJSON Tile where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/TileOffset.hs view
@@ -0,0 +1,17 @@+module Codec.Tiled.Tileset.TileOffset where++import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data TileOffset = TileOffset+ { x :: Int -- ^ Horizontal offset in pixels+ , y :: Int -- ^ Vertical offset in pixels (positive is down)+ }+ deriving (Eq, Show, Generic)++instance FromJSON TileOffset where+ parseJSON = genericParseJSON++instance ToJSON TileOffset where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/Transformations.hs view
@@ -0,0 +1,19 @@+module Codec.Tiled.Tileset.Transformations where++import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data Transformations = Transformations+ { hFlip :: Maybe Bool -- ^ Tiles can be flipped horizontally+ , vFlip :: Maybe Bool -- ^ Tiles can be flipped vertically+ , rotate :: Maybe Bool -- ^ Tiles can be rotated in 90-degree increments+ , preferUntransformed :: Maybe Bool -- ^ Whether untransformed tiles remain preferred, otherwise transformed tiles are used to produce more variations+ }+ deriving (Eq, Show, Generic)++instance FromJSON Transformations where+ parseJSON = genericParseJSON++instance ToJSON Transformations where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/WangColor.hs view
@@ -0,0 +1,23 @@+module Codec.Tiled.Tileset.WangColor where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Property (Property)++data WangColor = WangColor+ { color :: Text -- ^ Hex-formatted color (#RRGGBB or #AARRGGBB)+ , name :: Text -- ^ Name of Wang color+ , probability :: Double -- ^ Probability used when randomizing+ , properties :: Maybe (Vector Property) -- ^ Array of Properties+ , tile :: Int -- ^ Local ID of tile representing terrain+ }+ deriving (Eq, Show, Generic)++instance FromJSON WangColor where+ parseJSON = genericParseJSON++instance ToJSON WangColor where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/WangSet.hs view
@@ -0,0 +1,26 @@+module Codec.Tiled.Tileset.WangSet where++import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Codec.Tiled.Property (Property)+import Codec.Tiled.Tileset.WangColor (WangColor)+import Codec.Tiled.Tileset.WangTile (WangTile)++data WangSet = WangSet+ { colors :: Vector WangColor -- ^ Array of Wang colors (since 1.5)+ , name :: Text -- ^ Name of terrain+ , properties :: Maybe (Vector Property) -- ^ array Array of Properties+ , tile :: Int -- ^ Local ID of tile representing terrain+ , type_ :: Text -- ^ @corner@, @edge@ or @mixed@ (since 1.5)+ , wangTiles :: Vector WangTile -- ^ Array of Wang tiles+ }+ deriving (Eq, Show, Generic)++instance FromJSON WangSet where+ parseJSON = genericParseJSON++instance ToJSON WangSet where+ toJSON = genericToJSON
+ src/Codec/Tiled/Tileset/WangTile.hs view
@@ -0,0 +1,18 @@+module Codec.Tiled.Tileset.WangTile where++import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)++data WangTile = WangTile+ { tileId :: Int -- ^ Local ID of tile+ , wangId :: Vector Int -- ^ Array of Wang color indexes (uchar[8])+ }+ deriving (Eq, Show, Generic)++instance FromJSON WangTile where+ parseJSON = genericParseJSON++instance ToJSON WangTile where+ toJSON = genericToJSON
+ src/Codec/Tiled/World.hs view
@@ -0,0 +1,24 @@+module Codec.Tiled.World where++import Data.Aeson (FromJSON(..), ToJSON(..), genericParseJSON, genericToJSON)+import Data.Text (Text)+import Data.Vector (Vector)+import GHC.Generics (Generic)++import Codec.Tiled.Aeson (mkOptions, remapFields_)+import Codec.Tiled.World.Map (Map)+import Codec.Tiled.World.Pattern (Pattern)++data World = World+ { maps :: Maybe (Vector Map)+ , patterns :: Maybe (Vector Pattern)+ , type_ :: Maybe Text -- ^ @world@ (for world files)+ , onlyShowAdjacentMaps :: Maybe Bool+ }+ deriving (Eq, Show, Generic)++instance FromJSON World where+ parseJSON = genericParseJSON (mkOptions remapFields_)++instance ToJSON World where+ toJSON = genericToJSON (mkOptions remapFields_)
+ src/Codec/Tiled/World/Map.hs view
@@ -0,0 +1,17 @@+module Codec.Tiled.World.Map where++import Data.Aeson (FromJSON(..), ToJSON(..))+import GHC.Generics (Generic)++data Map = Map+ { fileName :: FilePath+ , x :: Int -- ^ Global position X, in pixels+ , y :: Int -- ^ Global position Y, in pixels+ , width :: Maybe Int+ , height :: Maybe Int+ }+ deriving (Eq, Show, Generic)++-- XXX: don't transform, fileName field+instance FromJSON Map+instance ToJSON Map
+ src/Codec/Tiled/World/Pattern.hs view
@@ -0,0 +1,19 @@+module Codec.Tiled.World.Pattern where++import Data.Aeson (FromJSON(..), ToJSON(..))+import Data.Text (Text)+import GHC.Generics (Generic)++data Pattern = Pattern+ { regexp :: Text+ , mapHeight :: Maybe Int+ , mapWidth :: Maybe Int+ , multiplierX :: Int+ , multiplierY :: Int+ , offsetX :: Int+ , offsetY :: Int+ }+ deriving (Eq, Show, Generic)++instance FromJSON Pattern+instance ToJSON Pattern
− src/Data/Aeson/Tiled.hs
@@ -1,447 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}--- | This module provides Haskell types for Tiled's JSON exports, which you can--- read about at http://doc.mapeditor.org/en/latest/reference/json-map-format/.--- That said - as of the writing of this module the JSON documentation does not--- cover some of the types and records that are available in the format. For--- those you should read the TMX documentation at--- http://doc.mapeditor.org/en/latest/reference/tmx-map-format/-module Data.Aeson.Tiled- ( -- * Tiled map editor types, their aeson instances and map loading- module Data.Aeson.Tiled- -- * Re-exports for working with Tiled types- , module Data.Map- , module Data.Vector- ) where--import Control.Applicative ((<|>))-import Control.Monad (forM)-import Data.Aeson hiding (Object)-import qualified Data.Aeson as A-import Data.Aeson.Types (Parser, typeMismatch)-import qualified Data.ByteString.Lazy.Char8 as C8-import Data.Map (Map)-import qualified Data.Map as M-import Data.Maybe (fromMaybe)-import Data.Text (Text)-import Data.Vector (Vector)-import GHC.Exts (fromList, toList)-import GHC.Generics (Generic)----- | A globally indexed identifier.-newtype GlobalId = GlobalId { unGlobalId :: Int }- deriving (Ord, Eq, Enum, Num, Generic, Show, FromJSON, ToJSON, FromJSONKey, ToJSONKey)----- | A locally indexed identifier.-newtype LocalId = LocalId { unLocalId :: Int }- deriving (Ord, Eq, Enum, Num, Generic, Show, FromJSON, ToJSON, FromJSONKey, ToJSONKey)---data XYPair a = XYPair a a--instance FromJSON a => FromJSON (XYPair a) where- parseJSON (A.Object o) =- XYPair <$> o .: "x"- <*> o .: "y"- parseJSON invalid = typeMismatch "Object" invalid--instance ToJSON a => ToJSON (XYPair a) where- toJSON (XYPair x y) =- object [ "x" .= x- , "y" .= y- ]--fromXYPair :: XYPair a -> (a, a)-fromXYPair (XYPair x y) = (x, y)--toXYPair :: (a, a) -> XYPair a-toXYPair (x, y) = XYPair x y--omitNulls :: Value -> Value-omitNulls (A.Object hs) = A.Object- . fromList- . filter ((/= Null) . snd)- $ toList hs-omitNulls x = x--#if MIN_VERSION_aeson(2,0,0)-parseDefault :: FromJSON a => A.Object -> A.Key -> a -> Parser a-#else-parseDefault :: FromJSON a => A.Object -> Text -> a -> Parser a-#endif-parseDefault o s d = fromMaybe d <$> o .:? s---data Object = Object { objectId :: Int- -- ^ Incremental id - unique across all objects- , objectWidth :: Double- -- ^ Width in pixels. Ignored if using a gid.- , objectHeight :: Double- -- ^ Height in pixels. Ignored if using a gid.- , objectName :: Text- -- ^ String assigned to name field in editor- , objectType :: Text- -- ^ String assigned to type field in editor- , objectProperties :: Map Text Text- -- ^ String key-value pairs- , objectVisible :: Bool- -- ^ Whether object is shown in editor.- , objectX :: Double- -- ^ x coordinate in pixels- , objectY :: Double- -- ^ y coordinate in pixels- , objectRotation :: Float- -- ^ Angle in degrees clockwise- , objectGid :: Maybe GlobalId- -- ^ GID, only if object comes from a Tilemap- , objectEllipse :: Bool- -- ^ Used to mark an object as an ellipse- , objectPolygon :: Maybe (Vector (Double, Double))- -- ^ A list of x,y coordinates in pixels- , objectPolyline :: Maybe (Vector (Double, Double))- -- ^ A list of x,y coordinates in pixels- , objectText :: Map Text Text- -- ^ String key-value pairs- } deriving (Eq, Generic, Show)--instance FromJSON Object where- parseJSON (A.Object o) = Object <$> o .: "id"- <*> o .: "width"- <*> o .: "height"- <*> o .: "name"- <*> o .: "type"- <*> parseDefault o "properties" M.empty- <*> o .: "visible"- <*> o .: "x"- <*> o .: "y"- <*> o .: "rotation"- <*> o .:? "gid"- <*> parseDefault o "ellipse" False- <*> (fmap . fmap . fmap) fromXYPair (o .:? "polygon")- <*> (fmap . fmap . fmap) fromXYPair (o .:? "polyline")- <*> parseDefault o "text" M.empty- parseJSON invalid = typeMismatch "Object" invalid--instance ToJSON Object where- toJSON Object{..} = omitNulls $- object [ "id" .= objectId- , "width" .= objectWidth- , "height" .= objectHeight- , "name" .= objectName- , "type" .= objectType- , "properties" .= objectProperties- , "visible" .= objectVisible- , "x" .= objectX- , "y" .= objectY- , "rotation" .= objectRotation- , "gid" .= objectGid- , "ellipse" .= objectEllipse- , "polygon" .= (fmap . fmap) toXYPair objectPolygon- , "polyline" .= (fmap . fmap) toXYPair objectPolyline- , "text" .= objectText- ]---data Layer = Layer { layerWidth :: Double- -- ^ Column count. Same as map width for fixed-size maps.- , layerHeight :: Double- -- ^ Row count. Same as map height for fixed-size maps.- , layerName :: Text- -- ^ Name assigned to this layer- , layerType :: Text -- TODO: LayerType- -- ^ “tilelayer”, “objectgroup”, or “imagelayer”- , layerVisible :: Bool- -- ^ Whether layer is shown or hidden in editor- , layerX :: Double- -- ^ Horizontal layer offset in tiles. Always 0.- , layerY :: Double- -- ^ Vertical layer offset in tiles. Always 0.- , layerData :: Maybe (Vector GlobalId)- -- ^ Array of GIDs. tilelayer only.- , layerObjects :: Maybe (Vector Object)- -- ^ Array of Objects. objectgroup only.- , layerProperties :: Map Text Text- -- ^ string key-value pairs.- , layerOpacity :: Float- -- ^ Value between 0 and 1- , layerDraworder :: Text -- TODO: DrawOrder- -- ^ “topdown” (default) or “index”. objectgroup only.- } deriving (Eq, Generic, Show)--instance FromJSON Layer where- parseJSON (A.Object o) = Layer <$> (o .: "width" <|> pure 0)- <*> (o .: "height" <|> pure 0)- <*> o .: "name"- <*> o .: "type"- <*> o .: "visible"- <*> o .: "x"- <*> o .: "y"- <*> (o .: "data" <|> pure Nothing)- <*> o .:? "objects"- <*> (o .: "properties" <|> pure mempty)- <*> o .: "opacity"- <*> (o .: "draworder" <|> pure "topdown")- parseJSON invalid = typeMismatch "Layer" invalid--instance ToJSON Layer where- toJSON Layer{..} = omitNulls $- object [ "width" .= layerWidth- , "height" .= layerHeight- , "name" .= layerName- , "type" .= layerType- , "visible" .= layerVisible- , "x" .= layerX- , "y" .= layerY- , "data" .= layerData- , "objects" .= layerObjects- , "properties" .= layerProperties- , "opacity" .= layerOpacity- , "draworder" .= layerDraworder- ]---data Terrain = Terrain { terrainName :: Text- -- ^ Name of terrain- , terrainTile :: LocalId- -- ^ Local ID of tile representing terrain- } deriving (Eq, Generic, Show)--instance FromJSON Terrain where- parseJSON (A.Object o) = Terrain <$> o .: "name"- <*> o .: "tile"- parseJSON invalid = typeMismatch "Terrain" invalid--instance ToJSON Terrain where- toJSON Terrain{..} = object [ "name" .= terrainName- , "tile" .= terrainTile- ]----data Frame = Frame { frameDuration :: Int- , frameTileId :: LocalId- } deriving (Eq, Generic, Show)--instance FromJSON Frame where- parseJSON (A.Object o) = Frame <$> o .: "duration"- <*> o .: "tileid"- parseJSON invalid = typeMismatch "Frame" invalid--instance ToJSON Frame where- toJSON Frame{..} = object [ "duration" .= frameDuration- , "tileid" .= frameTileId- ]---data Tile = Tile { tileId :: LocalId- , tileProperties :: Map Text Text- , tileImage :: Maybe Value- , tileObjectGroup :: Maybe (Vector Object)- , tileAnimation :: Maybe (Vector Frame)- } deriving (Eq, Generic, Show)--instance FromJSON Tile where- parseJSON (A.Object o) = Tile 0 <$> (o .: "properties" <|> pure mempty)- <*> (o .: "image" <|> pure Nothing)- <*> (o .: "objectGroup" <|> pure mempty)- <*> (o .: "animation" <|> pure mempty)- parseJSON invalid = typeMismatch "Tile" invalid--instance ToJSON Tile where- toJSON Tile{..} = object [ "properties" .= tileProperties- , "image" .= tileImage- , "objectGroup" .= tileObjectGroup- , "animation" .= tileAnimation- ]---data Tileset = Tileset { tilesetFirstgid :: GlobalId- -- ^ GID corresponding to the first tile in the set- , tilesetImage :: FilePath- -- ^ Image used for tiles in this set- , tilesetName :: Text- -- ^ Name given to this tileset- , tilesetTilewidth :: Int- -- ^ Maximum width of tiles in this set- , tilesetTileheight :: Int- -- ^ Maximum height of tiles in this set- , tilesetImagewidth :: Int- -- ^ Width of source image in pixels- , tilesetImageheight :: Int- -- ^ Height of source image in pixels- , tilesetProperties :: Map Text Text- -- ^ String key-value pairs- , tilesetPropertytypes :: Map Text Text- -- ^ String key-value pairs- , tilesetMargin :: Int- -- ^ Buffer between image edge and first tile (pixels)- , tilesetSpacing :: Int- -- ^ Spacing between adjacent tiles in image (pixels)- , tilesetTileproperties :: Map GlobalId (Map Text Text)- -- ^ Per-tile properties, indexed by gid as string- , tilesetTerrains :: Vector Terrain- -- ^ Array of Terrains (optional)- , tilesetColumns :: Int- -- ^ The number of tile columns in the tileset- , tilesetTilecount :: Int- -- ^ The number of tiles in this tileset- , tilesetTiles :: Map LocalId Tile- -- ^ Tiles (optional)- } deriving (Eq, Generic, Show)--newtype TransitiveTilesetMap = TransitiveTilesetMap (Map LocalId Value)- deriving (Show, Eq, Generic, FromJSON)--parseTiles :: A.Object -> Parser (Map LocalId Tile)-parseTiles o = do- TransitiveTilesetMap localId2Value <- o .: "tiles"- localIdAndTiles <- forM (M.toList localId2Value) $ \(lid, val) -> do- tile <- parseJSON val- return (lid, tile{ tileId = lid })- return $ M.fromList localIdAndTiles--instance FromJSON Tileset where- parseJSON (A.Object o) = Tileset <$> o .: "firstgid"- <*> o .: "image"- <*> o .: "name"- <*> o .: "tilewidth"- <*> o .: "tileheight"- <*> o .: "imagewidth"- <*> o .: "imageheight"- <*> (o .: "properties" <|> pure mempty)- <*> (o .: "propertytypes" <|> pure mempty)- <*> o .: "margin"- <*> o .: "spacing"- <*> (o .: "tileproperties" <|> pure mempty)- <*> (o .: "terrains" <|> pure mempty)- <*> o .: "columns"- <*> o .: "tilecount"- <*> (parseTiles o <|> pure mempty)- parseJSON invalid = typeMismatch "Tileset" invalid--instance ToJSON Tileset where- toJSON Tileset{..} = object [ "firstgid" .= tilesetFirstgid- , "image" .= tilesetImage- , "name" .= tilesetName- , "tilewidth" .= tilesetTilewidth- , "tileheight" .= tilesetTileheight- , "imagewidth" .= tilesetImagewidth- , "imageheight" .= tilesetImageheight- , "properties" .= tilesetProperties- , "propertytypes" .= tilesetPropertytypes- , "margin" .= tilesetMargin- , "spacing" .= tilesetSpacing- , "tileproperties" .= tilesetTileproperties- , "terrains" .= tilesetTerrains- , "columns" .= tilesetColumns- , "tilecount" .= tilesetTilecount- , "tiles" .= tilesetTiles- ]--data Version- = VersionFloat Float- | VersionText Text- deriving (Eq, Ord, Show, Generic)--instance FromJSON Version where- parseJSON v =- fmap VersionFloat (parseJSON v) <|>- fmap VersionText (parseJSON v)--instance ToJSON Version where- toJSON version = case version of- VersionFloat f -> toJSON f- VersionText t -> toJSON t--data Orientation- = Orthogonal- | Isometric- | Staggered- | Orientation Text- deriving (Eq, Ord, Show, Generic)--instance FromJSON Orientation where- parseJSON = withText "Orientation" $ \t ->- case t of- "orthogonal" -> pure Orthogonal- "isometric" -> pure Isometric- "staggered" -> pure Staggered- _otherwise -> pure $ Orientation t--instance ToJSON Orientation where- toJSON o = toJSON $ case o of- Orthogonal -> "orthogonal"- Isometric -> "isometric"- Staggered -> "staggered"- Orientation t -> t---- | The full monty.-data Tiledmap = Tiledmap { tiledmapVersion :: Version- -- ^ The JSON format version- , tiledmapTiledversion :: Version- -- ^ The Tiled version used to save the file- , tiledmapWidth :: Int- -- ^ Number of tile columns- , tiledmapHeight :: Int- -- ^ Number of tile rows- , tiledmapTilewidth :: Double- -- ^ Map grid width.- , tiledmapTileheight :: Double- -- ^ Map grid height.- , tiledmapOrientation :: Orientation- -- ^ Orthogonal, isometric, or staggered- , tiledmapLayers :: Vector Layer- -- ^ Array of Layers- , tiledmapTilesets :: Vector Tileset- -- ^ Array of Tilesets- , tiledmapBackgroundcolor :: Maybe Text- -- ^ Hex-formatted color (#RRGGBB or #AARRGGBB) (optional)- , tiledmapRenderorder :: Text -- TODO: RenderOrder- -- ^ Rendering direction (orthogonal maps only)- , tiledmapProperties :: Map Text Text- -- ^ String key-value pairs- , tiledmapNextobjectid :: Int- -- ^ Auto-increments for each placed object- } deriving (Eq, Generic, Show)--instance FromJSON Tiledmap where- parseJSON (A.Object o) = Tiledmap <$> o .: "version"- <*> o .: "tiledversion"- <*> o .: "width"- <*> o .: "height"- <*> o .: "tilewidth"- <*> o .: "tileheight"- <*> o .: "orientation"- <*> o .: "layers"- <*> o .: "tilesets"- <*> (o .: "backgroundcolor" <|> pure Nothing)- <*> o .: "renderorder"- <*> (o .: "properties" <|> pure mempty)- <*> o .: "nextobjectid"- parseJSON invalid = typeMismatch "Tiledmap" invalid--instance ToJSON Tiledmap where- toJSON Tiledmap{..} = object [ "version" .= tiledmapVersion- , "tiledversion" .= tiledmapTiledversion- , "width" .= tiledmapWidth- , "height" .= tiledmapHeight- , "tilewidth" .= tiledmapTilewidth- , "tileheight" .= tiledmapTileheight- , "orientation" .= tiledmapOrientation- , "layers" .= tiledmapLayers- , "tilesets" .= tiledmapTilesets- , "backgroundcolor" .= tiledmapBackgroundcolor- , "renderorder" .= tiledmapRenderorder- , "properties" .= tiledmapProperties- , "nextobjectid" .= tiledmapNextobjectid- ]----- | Load a Tiled map from the given 'FilePath'.-loadTiledmap :: FilePath -> IO (Either String Tiledmap)-loadTiledmap = fmap eitherDecode . C8.readFile
+ src/Data/Tiled/GID.hs view
@@ -0,0 +1,64 @@+{- | Global Tile IDs++https://doc.mapeditor.org/en/latest/reference/global-tile-ids/++-}++module Data.Tiled.GID where++import Data.Aeson (FromJSON(..), ToJSON(..))+import Data.Bits (Bits(..), (.&.))+import Data.Bool (bool)+import Data.Word (Word32)+import Foreign (Storable(..))+import GHC.Generics (Generic)++newtype GID = GID { getGID :: Word32 }+ deriving (Eq, Show, Generic)+ deriving newtype (FromJSON, ToJSON, Storable, Bits)++pattern FLIPPED_HORIZONTALLY_BIT :: Int+pattern FLIPPED_HORIZONTALLY_BIT = 32++pattern FLIPPED_VERTICALLY_BIT :: Int+pattern FLIPPED_VERTICALLY_BIT = 31++pattern ROTATED_60_BIT :: Int+pattern ROTATED_60_BIT = 30++pattern ROTATED_120_BIT :: Int+pattern ROTATED_120_BIT = 29++data Flags = Flags+ { flippedHorizontally :: Bool+ , flippedVertically :: Bool+ , rotated60 :: Bool+ , rotated120 :: Bool+ } deriving (Eq, Show, Generic)++flags :: GID -> Flags+flags (GID bits) = Flags+ { flippedHorizontally = testBit bits FLIPPED_HORIZONTALLY_BIT+ , flippedVertically = testBit bits FLIPPED_VERTICALLY_BIT+ , rotated60 = testBit bits ROTATED_60_BIT+ , rotated120 = testBit bits ROTATED_120_BIT+ }++flagBits :: Word32+flagBits =+ bit FLIPPED_HORIZONTALLY_BIT .|.+ bit FLIPPED_VERTICALLY_BIT .|.+ bit ROTATED_60_BIT .|.+ bit ROTATED_120_BIT++toLocal :: GID -> Int+toLocal (GID bits) = fromIntegral $ bits .&. complement flagBits++fromLocal :: Flags -> Int -> GID+fromLocal Flags{..} localId =+ GID . fromIntegral $+ localId+ .|. bool 0 FLIPPED_HORIZONTALLY_BIT flippedHorizontally+ .|. bool 0 FLIPPED_VERTICALLY_BIT flippedVertically+ .|. bool 0 ROTATED_60_BIT rotated60+ .|. bool 0 ROTATED_120_BIT rotated120
− test/ParseObjectSpec.hs
@@ -1,22 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeApplications #-}--module ParseObjectSpec where--import Data.Aeson (encode, eitherDecode)-import Test.Hspec-import Data.Either (isRight)-import Control.Monad (forM_)-import qualified Data.ByteString.Lazy.Char8 as C8--import Data.Aeson.Tiled--file :: FilePath-file = "maps/objects/obj1.json"--spec :: Spec-spec = describe "Obj1" $ do- it "should parse just fine" $ do- eobj <- fmap (eitherDecode @Object) $ C8.readFile file- eobj `shouldSatisfy` isRight-
− test/RoundTripSpec.hs
@@ -1,26 +0,0 @@-{-# LANGUAGE LambdaCase #-}--module RoundTripSpec where--import Data.Aeson (encode, eitherDecode)-import Test.Hspec-import Control.Monad (forM_)--import Data.Aeson.Tiled--files :: [FilePath]-files = [ "maps/example.json"- , "maps/test1.json"- , "maps/test2.json"- , "maps/test3.json"- , "maps/test4.json"- ]--spec :: Spec-spec = describe "Round tripping" . forM_ files $ \file ->- it (file ++ " should roundtrip and end up with the same Tiledmap") $- loadTiledmap file >>= \case- Right tm -> do- let bs = encode tm- eitherDecode bs `shouldBe` Right tm- Left x -> fail x
− test/Spec.hs
@@ -1,1 +0,0 @@-{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ tests/Main.hs view
@@ -0,0 +1,59 @@+module Main where++import Test.Tasty+import Test.Tasty.HUnit++import System.FilePath ((</>))+import System.IO.Temp (withSystemTempDirectory)++import qualified Codec.Tiled.Map.IO as Map+import qualified Codec.Tiled.Tileset.IO as Tileset++main :: IO ()+main = defaultMain tests++tests :: TestTree+tests = testGroup "Codec"+ [ mapCodecTests+ , tilesetCodecTests+ ]++mapCodecTests :: TestTree+mapCodecTests = testGroup "Map"+ [ testGroup "Roundtrip"+ [ testCase "Embedded tileset" mapTestRoundtripEmbedded+ , testCase "External tileset" mapTestRoundtripExternal+ ]+ ]++mapTestRoundtripEmbedded :: IO ()+mapTestRoundtripEmbedded = do+ embeddedZstd <- Map.readFile "maps/microgue/embedded-zstd.tmj"+ withSystemTempDirectory "" \path -> do+ let out = path </> "map.tsj"+ Map.writeFile out embeddedZstd+ embeddedZstdOut <- Map.readFile out+ embeddedZstd @?= embeddedZstdOut++mapTestRoundtripExternal :: IO ()+mapTestRoundtripExternal = do+ embeddedZstd <- Map.readFile "maps/microgue/external-zstd.tmj"+ withSystemTempDirectory "" \path -> do+ let out = path </> "map.tsj"+ Map.writeFile out embeddedZstd+ embeddedZstdOut <- Map.readFile out+ embeddedZstd @?= embeddedZstdOut++tilesetCodecTests :: TestTree+tilesetCodecTests = testGroup "Tileset"+ [ testCase "Roundtrip" tilesetCodecRoundtrip+ ]++tilesetCodecRoundtrip :: IO ()+tilesetCodecRoundtrip = do+ tiles <- Tileset.readFile "maps/microgue/tiles.tsj"+ withSystemTempDirectory "" \path -> do+ let out = path </> "tiles.tsj"+ Tileset.writeFile out tiles+ embeddedZstdOut <- Tileset.readFile out+ tiles @?= embeddedZstdOut