From 4aebf1d67b8735afd1e5525b483f51562f49c4c9 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 21:24:09 +0200 Subject: [PATCH 01/12] Remove old maps from tests and seperate model more --- DotTiled.Benchmark/Program.cs | 2 +- DotTiled.Tests/Serialization/TestData.cs | 2 + .../TestData/Map/default-map/default-map.cs | 96 ++++++++++ .../default-map.tmj} | 0 .../default-map.tmx} | 0 .../TestData/Map/empty-map-base64-gzip.tmj | 30 --- .../TestData/Map/empty-map-base64-gzip.tmx | 8 - .../TestData/Map/empty-map-base64-zlib.tmj | 30 --- .../TestData/Map/empty-map-base64-zlib.tmx | 8 - .../TestData/Map/empty-map-base64.tmj | 30 --- .../TestData/Map/empty-map-base64.tmx | 8 - .../TestData/Map/empty-map-properties.cs | 56 ------ .../TestData/Map/empty-map-properties.tmj | 69 ------- .../TestData/Map/empty-map-properties.tmx | 21 --- .../Serialization/TestData/Map/empty-map.cs | 47 ----- .../TestData/Map/map-with-group.cs | 94 ---------- .../TestData/Map/map-with-group.tmj | 80 -------- .../TestData/Map/map-with-group.tmx | 26 --- .../TestData/Map/map-with-object-template.cs | 125 ------------- .../TestData/Map/map-with-object-template.tmj | 104 ----------- .../TestData/Map/map-with-object-template.tmx | 35 ---- .../TestData/Map/simple-tileset-embed.cs | 65 ------- .../TestData/Map/simple-tileset-embed.tmj | 45 ----- .../TestData/Map/simple-tileset-embed.tmx | 15 -- .../Template/map-with-object-template.tj | 28 --- .../Template/map-with-object-template.tx | 14 -- .../Serialization/Tmj/TmjMapReaderTests.cs | 37 +--- .../Serialization/Tmx/TmxMapReaderTests.cs | 148 +-------------- DotTiled/Model/IProperty.cs | 173 ------------------ DotTiled/Model/Map.cs | 1 - DotTiled/Model/Properties/BoolProperty.cs | 14 ++ DotTiled/Model/Properties/ClassProperty.cs | 19 ++ DotTiled/Model/Properties/ColorProperty.cs | 14 ++ .../CustomTypes/CustomClassDefinition.cs | 27 +++ .../CustomTypes/CustomEnumDefinition.cs | 16 ++ .../CustomTypes/CustomTypeDefinition.cs | 7 + DotTiled/Model/Properties/FileProperty.cs | 14 ++ DotTiled/Model/Properties/FloatProperty.cs | 14 ++ DotTiled/Model/Properties/IProperty.cs | 9 + DotTiled/Model/Properties/IntProperty.cs | 14 ++ DotTiled/Model/Properties/ObjectProperty.cs | 14 ++ DotTiled/Model/Properties/PropertyType.cs | 13 ++ DotTiled/Model/Properties/StringProperty.cs | 14 ++ 43 files changed, 290 insertions(+), 1296 deletions(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs rename DotTiled.Tests/Serialization/TestData/Map/{empty-map-csv.tmj => default-map/default-map.tmj} (100%) rename DotTiled.Tests/Serialization/TestData/Map/{empty-map-csv.tmx => default-map/default-map.tmx} (100%) delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/empty-map.cs delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-group.cs delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.cs delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.cs delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmj delete mode 100644 DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx delete mode 100644 DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tj delete mode 100644 DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tx delete mode 100644 DotTiled/Model/IProperty.cs create mode 100644 DotTiled/Model/Properties/BoolProperty.cs create mode 100644 DotTiled/Model/Properties/ClassProperty.cs create mode 100644 DotTiled/Model/Properties/ColorProperty.cs create mode 100644 DotTiled/Model/Properties/CustomTypes/CustomClassDefinition.cs create mode 100644 DotTiled/Model/Properties/CustomTypes/CustomEnumDefinition.cs create mode 100644 DotTiled/Model/Properties/CustomTypes/CustomTypeDefinition.cs create mode 100644 DotTiled/Model/Properties/FileProperty.cs create mode 100644 DotTiled/Model/Properties/FloatProperty.cs create mode 100644 DotTiled/Model/Properties/IProperty.cs create mode 100644 DotTiled/Model/Properties/IntProperty.cs create mode 100644 DotTiled/Model/Properties/ObjectProperty.cs create mode 100644 DotTiled/Model/Properties/PropertyType.cs create mode 100644 DotTiled/Model/Properties/StringProperty.cs diff --git a/DotTiled.Benchmark/Program.cs b/DotTiled.Benchmark/Program.cs index 8397495..b432b7e 100644 --- a/DotTiled.Benchmark/Program.cs +++ b/DotTiled.Benchmark/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Immutable; using System.Security.Cryptography; using System.Text; diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index d31956f..9b3b13f 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -6,6 +6,8 @@ public static partial class TestData { public static XmlReader GetXmlReaderFor(string testDataFile) { + var names = typeof(TestData).Assembly.GetManifestResourceNames(); + var fullyQualifiedTestDataFile = $"DotTiled.Tests.{testDataFile}"; using var stream = typeof(TestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) ?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found"); diff --git a/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs new file mode 100644 index 0000000..44c909e --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs @@ -0,0 +1,96 @@ +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map DefaultMap() => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = new Color { R = 0, G = 0, B = 0, A = 0 }, + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + FlippingFlags = [ + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None, + FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-csv.tmj b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.tmj similarity index 100% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-csv.tmj rename to DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.tmj diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-csv.tmx b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.tmx similarity index 100% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-csv.tmx rename to DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.tmx diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmj b/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmj deleted file mode 100644 index de94421..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmj +++ /dev/null @@ -1,30 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "compression":"gzip", - "data":"H4sIAAAAAAAACmNgoD0AAMrGiJlkAAAA", - "encoding":"base64", - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }], - "nextlayerid":2, - "nextobjectid":1, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx b/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx deleted file mode 100644 index d3e0f29..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx +++ /dev/null @@ -1,8 +0,0 @@ - - - - - H4sIAAAAAAAACmNgoD0AAMrGiJlkAAAA - - - diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmj b/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmj deleted file mode 100644 index 4cf9e84..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmj +++ /dev/null @@ -1,30 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "compression":"zlib", - "data":"eJxjYKA9AAAAZAAB", - "encoding":"base64", - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }], - "nextlayerid":2, - "nextobjectid":1, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx b/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx deleted file mode 100644 index d35b438..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx +++ /dev/null @@ -1,8 +0,0 @@ - - - - - eJxjYKA9AAAAZAAB - - - diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmj b/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmj deleted file mode 100644 index b13707c..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmj +++ /dev/null @@ -1,30 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "compression":"", - "data":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "encoding":"base64", - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }], - "nextlayerid":2, - "nextobjectid":1, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx b/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx deleted file mode 100644 index 0e98f67..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx +++ /dev/null @@ -1,8 +0,0 @@ - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== - - - diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs b/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs deleted file mode 100644 index 79df5a5..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace DotTiled.Tests; - -public partial class TestData -{ - public static Map EmptyMapWithProperties() => new Map - { - Version = "1.10", - TiledVersion = "1.11.0", - Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, - Width = 5, - Height = 5, - TileWidth = 32, - TileHeight = 32, - Infinite = false, - NextLayerID = 2, - NextObjectID = 1, - Layers = [ - new TileLayer - { - ID = 1, - Name = "Tile Layer 1", - Width = 5, - Height = 5, - Data = new Data - { - Encoding = DataEncoding.Csv, - GlobalTileIDs = [ - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0 - ], - FlippingFlags = [ - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None - ] - } - } - ], - Properties = new Dictionary - { - ["MapBool"] = new BoolProperty { Name = "MapBool", Value = true }, - ["MapColor"] = new ColorProperty { Name = "MapColor", Value = new Color { R = 255, G = 0, B = 0, A = 255 } }, - ["MapFile"] = new FileProperty { Name = "MapFile", Value = "file.png" }, - ["MapFloat"] = new FloatProperty { Name = "MapFloat", Value = 5.2f }, - ["MapInt"] = new IntProperty { Name = "MapInt", Value = 42 }, - ["MapObject"] = new ObjectProperty { Name = "MapObject", Value = 5 }, - ["MapString"] = new StringProperty { Name = "MapString", Value = "string in map" } - } - }; -} diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmj b/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmj deleted file mode 100644 index 237546d..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmj +++ /dev/null @@ -1,69 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0], - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }], - "nextlayerid":2, - "nextobjectid":1, - "orientation":"orthogonal", - "properties":[ - { - "name":"MapBool", - "type":"bool", - "value":true - }, - { - "name":"MapColor", - "type":"color", - "value":"#ffff0000" - }, - { - "name":"MapFile", - "type":"file", - "value":"file.png" - }, - { - "name":"MapFloat", - "type":"float", - "value":5.2 - }, - { - "name":"MapInt", - "type":"int", - "value":42 - }, - - { - "name":"MapObject", - "type":"object", - "value":5 - }, - { - "name":"MapString", - "type":"string", - "value":"string in map" - }], - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmx b/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmx deleted file mode 100644 index 5a14d94..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmx +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0 - - - diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map.cs b/DotTiled.Tests/Serialization/TestData/Map/empty-map.cs deleted file mode 100644 index b51aeba..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace DotTiled.Tests; - -public partial class TestData -{ - public static Map EmptyMapWithEncodingAndCompression(DataEncoding dataEncoding, DataCompression? compression) => new Map - { - Version = "1.10", - TiledVersion = "1.11.0", - Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, - Width = 5, - Height = 5, - TileWidth = 32, - TileHeight = 32, - Infinite = false, - NextLayerID = 2, - NextObjectID = 1, - Layers = [ - new TileLayer - { - ID = 1, - Name = "Tile Layer 1", - Width = 5, - Height = 5, - Data = new Data - { - Encoding = dataEncoding, - Compression = compression, - GlobalTileIDs = [ - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0 - ], - FlippingFlags = [ - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None - ] - } - } - ] - }; -} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-group.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-group.cs deleted file mode 100644 index 14a2c8c..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-group.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace DotTiled.Tests; - -public partial class TestData -{ - public static Map MapWithGroup() => new Map - { - Version = "1.10", - TiledVersion = "1.11.0", - Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, - Width = 5, - Height = 5, - TileWidth = 32, - TileHeight = 32, - Infinite = false, - NextLayerID = 5, - NextObjectID = 2, - Layers = [ - new TileLayer - { - ID = 4, - Name = "Tile Layer 2", - Width = 5, - Height = 5, - Data = new Data - { - Encoding = DataEncoding.Csv, - GlobalTileIDs = [ - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0 - ], - FlippingFlags = [ - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None - ] - } - }, - new Group - { - ID = 3, - Name = "Group 1", - Layers = [ - new TileLayer - { - ID = 1, - Name = "Tile Layer 1", - Width = 5, - Height = 5, - Data = new Data - { - Encoding = DataEncoding.Csv, - GlobalTileIDs = [ - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0 - ], - FlippingFlags = [ - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None - ] - } - }, - new ObjectLayer - { - ID = 2, - Name = "Object Layer 1", - Objects = [ - new RectangleObject - { - ID = 1, - Name = "Name", - X = 35.5f, - Y = 26, - Width = 64.5f, - Height = 64.5f, - } - ] - } - ] - } - ] - }; -} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmj deleted file mode 100644 index 6bce8c8..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmj +++ /dev/null @@ -1,80 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0], - "height":5, - "id":4, - "name":"Tile Layer 2", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }, - { - "id":3, - "layers":[ - { - "data":[0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0], - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }, - { - "draworder":"topdown", - "id":2, - "name":"Object Layer 1", - "objects":[ - { - "height":64.5, - "id":1, - "name":"Name", - "rotation":0, - "type":"", - "visible":true, - "width":64.5, - "x":35.5, - "y":26 - }], - "opacity":1, - "type":"objectgroup", - "visible":true, - "x":0, - "y":0 - }], - "name":"Group 1", - "opacity":1, - "type":"group", - "visible":true, - "x":0, - "y":0 - }], - "nextlayerid":5, - "nextobjectid":2, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmx deleted file mode 100644 index 61191c4..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-group.tmx +++ /dev/null @@ -1,26 +0,0 @@ - - - - -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0 - - - - - -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0 - - - - - - - diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.cs deleted file mode 100644 index 1f9cb1c..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.cs +++ /dev/null @@ -1,125 +0,0 @@ -namespace DotTiled.Tests; - -public partial class TestData -{ - public static Map MapWithObjectTemplate(string templateExtension) => new Map - { - Version = "1.10", - TiledVersion = "1.11.0", - Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, - Width = 5, - Height = 5, - TileWidth = 32, - TileHeight = 32, - Infinite = false, - NextLayerID = 3, - NextObjectID = 3, - Layers = [ - new TileLayer - { - ID = 1, - Name = "Tile Layer 1", - Width = 5, - Height = 5, - Data = new Data - { - Encoding = DataEncoding.Csv, - GlobalTileIDs = [ - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0 - ], - FlippingFlags = [ - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None - ] - } - }, - new ObjectLayer - { - ID = 2, - Name = "Object Layer 1", - Objects = [ - new RectangleObject - { - ID = 1, - Template = $"map-with-object-template.{templateExtension}", - Name = "Thingy 2", - X = 94.5749f, - Y = 33.6842f, - Width = 37.0156f, - Height = 37.0156f, - Properties = new Dictionary - { - ["Bool"] = new BoolProperty { Name = "Bool", Value = true }, - ["TestClassInTemplate"] = new ClassProperty - { - Name = "TestClassInTemplate", - PropertyType = "TestClass", - Properties = new Dictionary - { - ["Amount"] = new FloatProperty { Name = "Amount", Value = 37 }, - ["Name"] = new StringProperty { Name = "Name", Value = "I am here" } - } - } - } - }, - new RectangleObject - { - ID = 2, - Template = $"map-with-object-template.{templateExtension}", - Name = "Thingy", - X = 29.7976f, - Y = 33.8693f, - Width = 37.0156f, - Height = 37.0156f, - Properties = new Dictionary - { - ["Bool"] = new BoolProperty { Name = "Bool", Value = true }, - ["TestClassInTemplate"] = new ClassProperty - { - Name = "TestClassInTemplate", - PropertyType = "TestClass", - Properties = new Dictionary - { - ["Amount"] = new FloatProperty { Name = "Amount", Value = 4.2f }, - ["Name"] = new StringProperty { Name = "Name", Value = "Hello there" } - } - } - } - }, - new RectangleObject - { - ID = 3, - Template = $"map-with-object-template.{templateExtension}", - Name = "Thingy 3", - X = 5, - Y = 5, - Width = 37.0156f, - Height = 37.0156f, - Properties = new Dictionary - { - ["Bool"] = new BoolProperty { Name = "Bool", Value = true }, - ["TestClassInTemplate"] = new ClassProperty - { - Name = "TestClassInTemplate", - PropertyType = "TestClass", - Properties = new Dictionary - { - ["Amount"] = new FloatProperty { Name = "Amount", Value = 0.0f }, - ["Name"] = new StringProperty { Name = "Name", Value = "I am here 3" } - } - } - } - } - ] - } - ] - }; -} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmj deleted file mode 100644 index 398403b..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmj +++ /dev/null @@ -1,104 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0], - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }, - { - "draworder":"topdown", - "id":2, - "name":"Object Layer 1", - "objects":[ - { - "height":37.0156, - "id":1, - "template":"map-with-object-template.tj", - "name":"Thingy 2", - "properties":[ - { - "name":"Bool", - "type":"bool", - "value":true - }, - { - "name":"TestClassInTemplate", - "propertytype":"TestClass", - "type":"class", - "value": - { - "Amount":37, - "Name":"I am here" - } - }], - "rotation":0, - "type":"", - "visible":true, - "width":37.0156, - "x":94.5749, - "y":33.6842 - }, - { - "id":2, - "template":"map-with-object-template.tj", - "x":29.7976, - "y":33.8693 - }, - { - "height":37.0156, - "id":3, - "template":"map-with-object-template.tj", - "name":"Thingy 3", - "properties":[ - { - "name":"Bool", - "type":"bool", - "value":true - }, - { - "name":"TestClassInTemplate", - "propertytype":"TestClass", - "type":"class", - "value": - { - "Name":"I am here 3" - } - }], - "rotation":0, - "type":"", - "visible":true, - "width":37.0156, - "x":5, - "y":5 - }], - "opacity":1, - "type":"objectgroup", - "visible":true, - "x":0, - "y":0 - }], - "nextlayerid":3, - "nextobjectid":3, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmx deleted file mode 100644 index 83716a0..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-object-template.tmx +++ /dev/null @@ -1,35 +0,0 @@ - - - - -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0, -0,0,0,0,0 - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.cs b/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.cs deleted file mode 100644 index d6a5f10..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace DotTiled.Tests; - -public partial class TestData -{ - public static Map SimpleMapWithEmbeddedTileset() => new Map - { - Version = "1.10", - TiledVersion = "1.11.0", - Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, - Width = 5, - Height = 5, - TileWidth = 32, - TileHeight = 32, - Infinite = false, - NextLayerID = 2, - NextObjectID = 1, - Tilesets = [ - new Tileset - { - FirstGID = 1, - Name = "Tileset 1", - TileWidth = 32, - TileHeight = 32, - TileCount = 8, - Columns = 4, - Image = new Image - { - Format = ImageFormat.Png, - Source = "tiles.png", - Width = 128, - Height = 64 - } - } - ], - Layers = [ - new TileLayer - { - ID = 1, - Name = "Tile Layer 1", - Width = 5, - Height = 5, - Data = new Data - { - Encoding = DataEncoding.Csv, - Compression = null, - GlobalTileIDs = [ - 1,1,1,1,1, - 1,1,1,1,1, - 1,1,1,1,1, - 2,2,2,2,2, - 2,2,2,2,2 - ], - FlippingFlags = [ - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, - FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None - ] - }, - } - ] - }; -} diff --git a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmj b/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmj deleted file mode 100644 index fa5a4ef..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmj +++ /dev/null @@ -1,45 +0,0 @@ -{ "compressionlevel":-1, - "height":5, - "infinite":false, - "layers":[ - { - "data":[1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2], - "height":5, - "id":1, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":5, - "x":0, - "y":0 - }], - "nextlayerid":2, - "nextobjectid":1, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.11.0", - "tileheight":32, - "tilesets":[ - { - "columns":4, - "firstgid":1, - "image":"tiles.png", - "imageheight":64, - "imagewidth":128, - "margin":0, - "name":"Tileset 1", - "spacing":0, - "tilecount":8, - "tileheight":32, - "tilewidth":32 - }], - "tilewidth":32, - "type":"map", - "version":"1.10", - "width":5 -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx b/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx deleted file mode 100644 index 3d91b9d..0000000 --- a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - -1,1,1,1,1, -1,1,1,1,1, -1,1,1,1,1, -2,2,2,2,2, -2,2,2,2,2 - - - diff --git a/DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tj b/DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tj deleted file mode 100644 index ec2b065..0000000 --- a/DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tj +++ /dev/null @@ -1,28 +0,0 @@ -{ "object": - { - "height":37.0156, - "id":2, - "name":"Thingy", - "properties":[ - { - "name":"Bool", - "type":"bool", - "value":true - }, - { - "name":"TestClassInTemplate", - "propertytype":"TestClass", - "type":"class", - "value": - { - "Amount":4.2, - "Name":"Hello there" - } - }], - "rotation":0, - "type":"", - "visible":true, - "width":37.0156 - }, - "type":"template" -} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tx b/DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tx deleted file mode 100644 index 3039be2..0000000 --- a/DotTiled.Tests/Serialization/TestData/Template/map-with-object-template.tx +++ /dev/null @@ -1,14 +0,0 @@ - - diff --git a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs index 7e220a9..e04423b 100644 --- a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs @@ -2,44 +2,9 @@ namespace DotTiled.Tests; public partial class TmjMapReaderTests { - public static IEnumerable DeserializeMap_ValidTmjNoExternalTilesets_ReturnsMapWithoutThrowing_Data => - [ - ["Serialization.TestData.Map.empty-map-csv.tmj", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Csv, null)], - ["Serialization.TestData.Map.empty-map-base64.tmj", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Base64, null)], - ["Serialization.TestData.Map.empty-map-base64-gzip.tmj", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.GZip)], - ["Serialization.TestData.Map.empty-map-base64-zlib.tmj", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.ZLib)], - ["Serialization.TestData.Map.simple-tileset-embed.tmj", TestData.SimpleMapWithEmbeddedTileset()], - ["Serialization.TestData.Map.empty-map-properties.tmj", TestData.EmptyMapWithProperties()], - ]; - - [Theory] - [MemberData(nameof(DeserializeMap_ValidTmjNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void TmxMapReaderReadMap_ValidTmjNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) - { - // Arrange - var json = TestData.GetRawStringFor(testDataFile); - static Template ResolveTemplate(string source) - { - throw new NotSupportedException("External templates are not supported in this test."); - } - static Tileset ResolveTileset(string source) - { - throw new NotSupportedException("External tilesets are not supported in this test."); - } - using var mapReader = new TmjMapReader(json, ResolveTileset, ResolveTemplate, []); - - // Act - var map = mapReader.ReadMap(); - - // Assert - Assert.NotNull(map); - DotTiledAssert.AssertMap(expectedMap, map); - } - public static IEnumerable DeserializeMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data => [ - ["Serialization.TestData.Map.map-with-object-template.tmj", TestData.MapWithObjectTemplate("tj")], - ["Serialization.TestData.Map.map-with-group.tmj", TestData.MapWithGroup()], + ["Serialization.TestData.Map.default_map.default-map.tmj", TestData.DefaultMap()] ]; [Theory] diff --git a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs index 3556893..5ee162f 100644 --- a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs @@ -4,155 +4,9 @@ namespace DotTiled.Tests; public partial class TmxMapReaderTests { - [Fact] - public void TmxMapReaderConstructor_XmlReaderIsNull_ThrowsArgumentNullException() - { - // Arrange - XmlReader xmlReader = null!; - Func externalTilesetResolver = (_) => new Tileset(); - Func externalTemplateResolver = (_) => new Template { Object = new RectangleObject { } }; - - // Act - Action act = () => - { - using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []); - }; - - // Assert - Assert.Throws(act); - } - - [Fact] - public void TmxMapReaderConstructor_ExternalTilesetResolverIsNull_ThrowsArgumentNullException() - { - // Arrange - using var stringReader = new StringReader(""); - using var xmlReader = XmlReader.Create(stringReader); - Func externalTilesetResolver = null!; - Func externalTemplateResolver = (_) => new Template { Object = new RectangleObject { } }; - - // Act - Action act = () => - { - using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []); - }; - - // Assert - Assert.Throws(act); - } - - [Fact] - public void TmxMapReaderConstructor_ExternalTemplateResolverIsNull_ThrowsArgumentNullException() - { - // Arrange - using var stringReader = new StringReader(""); - using var xmlReader = XmlReader.Create(stringReader); - Func externalTilesetResolver = (_) => new Tileset(); - Func externalTemplateResolver = null!; - - // Act - Action act = () => - { - using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []); - }; - - // Assert - Assert.Throws(act); - } - - [Fact] - public void TmxMapReaderConstructor_NoneNull_DoesNotThrow() - { - // Arrange - using var stringReader = new StringReader(""); - using var xmlReader = XmlReader.Create(stringReader); - Func externalTilesetResolver = (_) => new Tileset(); - Func externalTemplateResolver = (_) => new Template { Object = new RectangleObject { } }; - - // Act - using var tmxMapReader = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []); - - // Assert - Assert.NotNull(tmxMapReader); - } - - public static IEnumerable DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data => - [ - ["Serialization.TestData.Map.empty-map-csv.tmx", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Csv, null)], - ["Serialization.TestData.Map.empty-map-base64.tmx", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Base64, null)], - ["Serialization.TestData.Map.empty-map-base64-gzip.tmx", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.GZip)], - ["Serialization.TestData.Map.empty-map-base64-zlib.tmx", TestData.EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.ZLib)], - ["Serialization.TestData.Map.simple-tileset-embed.tmx", TestData.SimpleMapWithEmbeddedTileset()], - ["Serialization.TestData.Map.empty-map-properties.tmx", TestData.EmptyMapWithProperties()], - ]; - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void TmxMapReaderReadMap_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) - { - // Arrange - CustomTypeDefinition[] customTypeDefinitions = [ - new CustomClassDefinition - { - Name = "TestClass", - ID = 1, - UseAs = CustomClassUseAs.Property, - Members = [ - new StringProperty - { - Name = "Name", - Value = "" - }, - new FloatProperty - { - Name = "Amount", - Value = 0f - } - ] - }, - new CustomClassDefinition - { - Name = "Test", - ID = 2, - UseAs = CustomClassUseAs.All, - Members = [ - new ClassProperty - { - Name = "Yep", - PropertyType = "TestClass", - Properties = [] - } - ] - } - ]; - - using var reader = TestData.GetXmlReaderFor(testDataFile); - Template ResolveTemplate(string source) - { - using var xmlTemplateReader = TestData.GetXmlReaderFor($"Serialization.TestData.Template.{source}"); - using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate, customTypeDefinitions); - return templateReader.ReadTemplate(); - } - Tileset ResolveTileset(string source) - { - using var xmlTilesetReader = TestData.GetXmlReaderFor($"Serialization.TestData.Tileset.{source}"); - using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate, customTypeDefinitions); - return tilesetReader.ReadTileset(); - } - using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate, customTypeDefinitions); - - // Act - var map = mapReader.ReadMap(); - - // Assert - Assert.NotNull(map); - DotTiledAssert.AssertMap(expectedMap, map); - } - public static IEnumerable DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data => [ - ["Serialization.TestData.Map.map-with-object-template.tmx", TestData.MapWithObjectTemplate("tx")], - ["Serialization.TestData.Map.map-with-group.tmx", TestData.MapWithGroup()], + ["Serialization.TestData.Map.default_map.default-map.tmx", TestData.DefaultMap()] ]; [Theory] diff --git a/DotTiled/Model/IProperty.cs b/DotTiled/Model/IProperty.cs deleted file mode 100644 index ae522f2..0000000 --- a/DotTiled/Model/IProperty.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace DotTiled; - -public enum PropertyType -{ - String, - Int, - Float, - Bool, - Color, - File, - Object, - Class -} - -public interface IProperty -{ - public string Name { get; set; } - public PropertyType Type { get; } - - IProperty Clone(); -} - -public class StringProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.String; - public required string Value { get; set; } - - public IProperty Clone() => new StringProperty - { - Name = Name, - Value = Value - }; -} - -public class IntProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.Int; - public required int Value { get; set; } - - public IProperty Clone() => new IntProperty - { - Name = Name, - Value = Value - }; -} - -public class FloatProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.Float; - public required float Value { get; set; } - - public IProperty Clone() => new FloatProperty - { - Name = Name, - Value = Value - }; -} - -public class BoolProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.Bool; - public required bool Value { get; set; } - - public IProperty Clone() => new BoolProperty - { - Name = Name, - Value = Value - }; -} - -public class ColorProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.Color; - public required Color Value { get; set; } - - public IProperty Clone() => new ColorProperty - { - Name = Name, - Value = Value - }; -} - -public class FileProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.File; - public required string Value { get; set; } - - public IProperty Clone() => new FileProperty - { - Name = Name, - Value = Value - }; -} - -public class ObjectProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => PropertyType.Object; - public required uint Value { get; set; } - - public IProperty Clone() => new ObjectProperty - { - Name = Name, - Value = Value - }; -} - -public class ClassProperty : IProperty -{ - public required string Name { get; set; } - public PropertyType Type => DotTiled.PropertyType.Class; - public required string PropertyType { get; set; } - public required Dictionary Properties { get; set; } - - public IProperty Clone() => new ClassProperty - { - Name = Name, - PropertyType = PropertyType, - Properties = Properties.ToDictionary(p => p.Key, p => p.Value.Clone()) - }; -} - -public abstract class CustomTypeDefinition -{ - public uint ID { get; set; } - public string Name { get; set; } = ""; -} - -[Flags] -public enum CustomClassUseAs -{ - Property, - Map, - Layer, - Object, - Tile, - Tileset, - WangColor, - Wangset, - Project, - All = Property | Map | Layer | Object | Tile | Tileset | WangColor | Wangset | Project -} - -public class CustomClassDefinition : CustomTypeDefinition -{ - public Color Color { get; set; } - public bool DrawFill { get; set; } - public CustomClassUseAs UseAs { get; set; } - public List Members { get; set; } -} - -public enum CustomEnumStorageType -{ - Int, - String -} - -public class CustomEnumDefinition : CustomTypeDefinition -{ - public CustomEnumStorageType StorageType { get; set; } - public List Values { get; set; } = []; - public bool ValueAsFlags { get; set; } -} diff --git a/DotTiled/Model/Map.cs b/DotTiled/Model/Map.cs index 246f21c..fdcdbd1 100644 --- a/DotTiled/Model/Map.cs +++ b/DotTiled/Model/Map.cs @@ -60,5 +60,4 @@ public class Map // Any number of public List Tilesets { get; set; } = []; public List Layers { get; set; } = []; - public List Groups { get; set; } = []; } diff --git a/DotTiled/Model/Properties/BoolProperty.cs b/DotTiled/Model/Properties/BoolProperty.cs new file mode 100644 index 0000000..949858f --- /dev/null +++ b/DotTiled/Model/Properties/BoolProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class BoolProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.Bool; + public required bool Value { get; set; } + + public IProperty Clone() => new BoolProperty + { + Name = Name, + Value = Value + }; +} diff --git a/DotTiled/Model/Properties/ClassProperty.cs b/DotTiled/Model/Properties/ClassProperty.cs new file mode 100644 index 0000000..0b1391d --- /dev/null +++ b/DotTiled/Model/Properties/ClassProperty.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Linq; + +namespace DotTiled; + +public class ClassProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => DotTiled.PropertyType.Class; + public required string PropertyType { get; set; } + public required Dictionary Properties { get; set; } + + public IProperty Clone() => new ClassProperty + { + Name = Name, + PropertyType = PropertyType, + Properties = Properties.ToDictionary(p => p.Key, p => p.Value.Clone()) + }; +} diff --git a/DotTiled/Model/Properties/ColorProperty.cs b/DotTiled/Model/Properties/ColorProperty.cs new file mode 100644 index 0000000..07ca25e --- /dev/null +++ b/DotTiled/Model/Properties/ColorProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class ColorProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.Color; + public required Color Value { get; set; } + + public IProperty Clone() => new ColorProperty + { + Name = Name, + Value = Value + }; +} diff --git a/DotTiled/Model/Properties/CustomTypes/CustomClassDefinition.cs b/DotTiled/Model/Properties/CustomTypes/CustomClassDefinition.cs new file mode 100644 index 0000000..ec92b3f --- /dev/null +++ b/DotTiled/Model/Properties/CustomTypes/CustomClassDefinition.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace DotTiled; + +[Flags] +public enum CustomClassUseAs +{ + Property, + Map, + Layer, + Object, + Tile, + Tileset, + WangColor, + Wangset, + Project, + All = Property | Map | Layer | Object | Tile | Tileset | WangColor | Wangset | Project +} + +public class CustomClassDefinition : CustomTypeDefinition +{ + public Color? Color { get; set; } + public bool DrawFill { get; set; } + public CustomClassUseAs UseAs { get; set; } + public List Members { get; set; } = []; +} diff --git a/DotTiled/Model/Properties/CustomTypes/CustomEnumDefinition.cs b/DotTiled/Model/Properties/CustomTypes/CustomEnumDefinition.cs new file mode 100644 index 0000000..d570442 --- /dev/null +++ b/DotTiled/Model/Properties/CustomTypes/CustomEnumDefinition.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace DotTiled; + +public enum CustomEnumStorageType +{ + Int, + String +} + +public class CustomEnumDefinition : CustomTypeDefinition +{ + public CustomEnumStorageType StorageType { get; set; } + public List Values { get; set; } = []; + public bool ValueAsFlags { get; set; } +} diff --git a/DotTiled/Model/Properties/CustomTypes/CustomTypeDefinition.cs b/DotTiled/Model/Properties/CustomTypes/CustomTypeDefinition.cs new file mode 100644 index 0000000..1f50462 --- /dev/null +++ b/DotTiled/Model/Properties/CustomTypes/CustomTypeDefinition.cs @@ -0,0 +1,7 @@ +namespace DotTiled; + +public abstract class CustomTypeDefinition +{ + public uint ID { get; set; } + public string Name { get; set; } = ""; +} diff --git a/DotTiled/Model/Properties/FileProperty.cs b/DotTiled/Model/Properties/FileProperty.cs new file mode 100644 index 0000000..edc939c --- /dev/null +++ b/DotTiled/Model/Properties/FileProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class FileProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.File; + public required string Value { get; set; } + + public IProperty Clone() => new FileProperty + { + Name = Name, + Value = Value + }; +} diff --git a/DotTiled/Model/Properties/FloatProperty.cs b/DotTiled/Model/Properties/FloatProperty.cs new file mode 100644 index 0000000..469cc45 --- /dev/null +++ b/DotTiled/Model/Properties/FloatProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class FloatProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.Float; + public required float Value { get; set; } + + public IProperty Clone() => new FloatProperty + { + Name = Name, + Value = Value + }; +} diff --git a/DotTiled/Model/Properties/IProperty.cs b/DotTiled/Model/Properties/IProperty.cs new file mode 100644 index 0000000..f4294cd --- /dev/null +++ b/DotTiled/Model/Properties/IProperty.cs @@ -0,0 +1,9 @@ +namespace DotTiled; + +public interface IProperty +{ + public string Name { get; set; } + public PropertyType Type { get; } + + IProperty Clone(); +} diff --git a/DotTiled/Model/Properties/IntProperty.cs b/DotTiled/Model/Properties/IntProperty.cs new file mode 100644 index 0000000..b8fb02a --- /dev/null +++ b/DotTiled/Model/Properties/IntProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class IntProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.Int; + public required int Value { get; set; } + + public IProperty Clone() => new IntProperty + { + Name = Name, + Value = Value + }; +} diff --git a/DotTiled/Model/Properties/ObjectProperty.cs b/DotTiled/Model/Properties/ObjectProperty.cs new file mode 100644 index 0000000..1591319 --- /dev/null +++ b/DotTiled/Model/Properties/ObjectProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class ObjectProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.Object; + public required uint Value { get; set; } + + public IProperty Clone() => new ObjectProperty + { + Name = Name, + Value = Value + }; +} diff --git a/DotTiled/Model/Properties/PropertyType.cs b/DotTiled/Model/Properties/PropertyType.cs new file mode 100644 index 0000000..79b05cb --- /dev/null +++ b/DotTiled/Model/Properties/PropertyType.cs @@ -0,0 +1,13 @@ +namespace DotTiled; + +public enum PropertyType +{ + String, + Int, + Float, + Bool, + Color, + File, + Object, + Class +} diff --git a/DotTiled/Model/Properties/StringProperty.cs b/DotTiled/Model/Properties/StringProperty.cs new file mode 100644 index 0000000..655b7b4 --- /dev/null +++ b/DotTiled/Model/Properties/StringProperty.cs @@ -0,0 +1,14 @@ +namespace DotTiled; + +public class StringProperty : IProperty +{ + public required string Name { get; set; } + public PropertyType Type => PropertyType.String; + public required string Value { get; set; } + + public IProperty Clone() => new StringProperty + { + Name = Name, + Value = Value + }; +} From da5bf73ca02e402418ab5ff9631f6ec13fc1f04b Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 22:00:59 +0200 Subject: [PATCH 02/12] Make assertions tell you where they fail --- DotTiled.Tests/Assert/AssertData.cs | 22 ++--- DotTiled.Tests/Assert/AssertImage.cs | 10 +- DotTiled.Tests/Assert/AssertLayer.cs | 46 ++++----- DotTiled.Tests/Assert/AssertMap.cs | 67 ++++++++----- DotTiled.Tests/Assert/AssertObject.cs | 50 +++++----- DotTiled.Tests/Assert/AssertProperties.cs | 22 ++--- DotTiled.Tests/Assert/AssertTileset.cs | 94 +++++++++---------- .../TestData/Map/default-map/default-map.cs | 60 ++---------- 8 files changed, 178 insertions(+), 193 deletions(-) diff --git a/DotTiled.Tests/Assert/AssertData.cs b/DotTiled.Tests/Assert/AssertData.cs index d4b54f0..31ffff2 100644 --- a/DotTiled.Tests/Assert/AssertData.cs +++ b/DotTiled.Tests/Assert/AssertData.cs @@ -12,17 +12,17 @@ public static partial class DotTiledAssert // Attributes Assert.NotNull(actual); - Assert.Equal(expected.Encoding, actual.Encoding); - Assert.Equal(expected.Compression, actual.Compression); + AssertEqual(expected.Encoding, actual.Encoding, nameof(Data.Encoding)); + AssertEqual(expected.Compression, actual.Compression, nameof(Data.Compression)); // Data - Assert.Equal(expected.GlobalTileIDs, actual.GlobalTileIDs); - Assert.Equal(expected.FlippingFlags, actual.FlippingFlags); + AssertEqual(expected.GlobalTileIDs, actual.GlobalTileIDs, nameof(Data.GlobalTileIDs)); + AssertEqual(expected.FlippingFlags, actual.FlippingFlags, nameof(Data.FlippingFlags)); if (expected.Chunks is not null) { Assert.NotNull(actual.Chunks); - Assert.Equal(expected.Chunks.Length, actual.Chunks.Length); + AssertEqual(expected.Chunks.Length, actual.Chunks.Length, "Chunks.Length"); for (var i = 0; i < expected.Chunks.Length; i++) AssertChunk(expected.Chunks[i], actual.Chunks[i]); } @@ -31,13 +31,13 @@ public static partial class DotTiledAssert private static void AssertChunk(Chunk expected, Chunk actual) { // Attributes - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); + AssertEqual(expected.X, actual.X, nameof(Chunk.X)); + AssertEqual(expected.Y, actual.Y, nameof(Chunk.Y)); + AssertEqual(expected.Width, actual.Width, nameof(Chunk.Width)); + AssertEqual(expected.Height, actual.Height, nameof(Chunk.Height)); // Data - Assert.Equal(expected.GlobalTileIDs, actual.GlobalTileIDs); - Assert.Equal(expected.FlippingFlags, actual.FlippingFlags); + AssertEqual(expected.GlobalTileIDs, actual.GlobalTileIDs, nameof(Chunk.GlobalTileIDs)); + AssertEqual(expected.FlippingFlags, actual.FlippingFlags, nameof(Chunk.FlippingFlags)); } } diff --git a/DotTiled.Tests/Assert/AssertImage.cs b/DotTiled.Tests/Assert/AssertImage.cs index 9943c46..a674faa 100644 --- a/DotTiled.Tests/Assert/AssertImage.cs +++ b/DotTiled.Tests/Assert/AssertImage.cs @@ -12,10 +12,10 @@ public static partial class DotTiledAssert // Attributes Assert.NotNull(actual); - Assert.Equal(expected.Format, actual.Format); - Assert.Equal(expected.Source, actual.Source); - Assert.Equal(expected.TransparentColor, actual.TransparentColor); - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); + AssertEqual(expected.Format, actual.Format, nameof(Image.Format)); + AssertEqual(expected.Source, actual.Source, nameof(Image.Source)); + AssertEqual(expected.TransparentColor, actual.TransparentColor, nameof(Image.TransparentColor)); + AssertEqual(expected.Width, actual.Width, nameof(Image.Width)); + AssertEqual(expected.Height, actual.Height, nameof(Image.Height)); } } diff --git a/DotTiled.Tests/Assert/AssertLayer.cs b/DotTiled.Tests/Assert/AssertLayer.cs index 57df04d..5432d62 100644 --- a/DotTiled.Tests/Assert/AssertLayer.cs +++ b/DotTiled.Tests/Assert/AssertLayer.cs @@ -12,16 +12,16 @@ public static partial class DotTiledAssert // Attributes Assert.NotNull(actual); - Assert.Equal(expected.ID, actual.ID); - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.Class, actual.Class); - Assert.Equal(expected.Opacity, actual.Opacity); - Assert.Equal(expected.Visible, actual.Visible); - Assert.Equal(expected.TintColor, actual.TintColor); - Assert.Equal(expected.OffsetX, actual.OffsetX); - Assert.Equal(expected.OffsetY, actual.OffsetY); - Assert.Equal(expected.ParallaxX, actual.ParallaxX); - Assert.Equal(expected.ParallaxY, actual.ParallaxY); + AssertEqual(expected.ID, actual.ID, nameof(BaseLayer.ID)); + AssertEqual(expected.Name, actual.Name, nameof(BaseLayer.Name)); + AssertEqual(expected.Class, actual.Class, nameof(BaseLayer.Class)); + AssertEqual(expected.Opacity, actual.Opacity, nameof(BaseLayer.Opacity)); + AssertEqual(expected.Visible, actual.Visible, nameof(BaseLayer.Visible)); + AssertEqual(expected.TintColor, actual.TintColor, nameof(BaseLayer.TintColor)); + AssertEqual(expected.OffsetX, actual.OffsetX, nameof(BaseLayer.OffsetX)); + AssertEqual(expected.OffsetY, actual.OffsetY, nameof(BaseLayer.OffsetY)); + AssertEqual(expected.ParallaxX, actual.ParallaxX, nameof(BaseLayer.ParallaxX)); + AssertEqual(expected.ParallaxY, actual.ParallaxY, nameof(BaseLayer.ParallaxY)); AssertProperties(expected.Properties, actual.Properties); AssertLayer((dynamic)expected, (dynamic)actual); @@ -30,10 +30,10 @@ public static partial class DotTiledAssert private static void AssertLayer(TileLayer expected, TileLayer actual) { // Attributes - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); + AssertEqual(expected.Width, actual.Width, nameof(TileLayer.Width)); + AssertEqual(expected.Height, actual.Height, nameof(TileLayer.Height)); + AssertEqual(expected.X, actual.X, nameof(TileLayer.X)); + AssertEqual(expected.Y, actual.Y, nameof(TileLayer.Y)); Assert.NotNull(actual.Data); AssertData(expected.Data, actual.Data); @@ -42,12 +42,12 @@ public static partial class DotTiledAssert private static void AssertLayer(ObjectLayer expected, ObjectLayer actual) { // Attributes - Assert.Equal(expected.DrawOrder, actual.DrawOrder); - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); + AssertEqual(expected.DrawOrder, actual.DrawOrder, nameof(ObjectLayer.DrawOrder)); + AssertEqual(expected.X, actual.X, nameof(ObjectLayer.X)); + AssertEqual(expected.Y, actual.Y, nameof(ObjectLayer.Y)); Assert.NotNull(actual.Objects); - Assert.Equal(expected.Objects.Count, actual.Objects.Count); + AssertEqual(expected.Objects.Count, actual.Objects.Count, "Objects.Count"); for (var i = 0; i < expected.Objects.Count; i++) AssertObject(expected.Objects[i], actual.Objects[i]); } @@ -55,10 +55,10 @@ public static partial class DotTiledAssert private static void AssertLayer(ImageLayer expected, ImageLayer actual) { // Attributes - Assert.Equal(expected.RepeatX, actual.RepeatX); - Assert.Equal(expected.RepeatY, actual.RepeatY); - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); + AssertEqual(expected.RepeatX, actual.RepeatX, nameof(ImageLayer.RepeatX)); + AssertEqual(expected.RepeatY, actual.RepeatY, nameof(ImageLayer.RepeatY)); + AssertEqual(expected.X, actual.X, nameof(ImageLayer.X)); + AssertEqual(expected.Y, actual.Y, nameof(ImageLayer.Y)); Assert.NotNull(actual.Image); AssertImage(expected.Image, actual.Image); @@ -68,7 +68,7 @@ public static partial class DotTiledAssert { // Attributes Assert.NotNull(actual.Layers); - Assert.Equal(expected.Layers.Count, actual.Layers.Count); + AssertEqual(expected.Layers.Count, actual.Layers.Count, "Layers.Count"); for (var i = 0; i < expected.Layers.Count; i++) AssertLayer(expected.Layers[i], actual.Layers[i]); } diff --git a/DotTiled.Tests/Assert/AssertMap.cs b/DotTiled.Tests/Assert/AssertMap.cs index e831063..6596ee8 100644 --- a/DotTiled.Tests/Assert/AssertMap.cs +++ b/DotTiled.Tests/Assert/AssertMap.cs @@ -2,38 +2,63 @@ namespace DotTiled.Tests; public static partial class DotTiledAssert { + private static void AssertEqual(T expected, T actual, string nameof) + { + if (expected == null) + { + Assert.Null(actual); + return; + } + + if (typeof(T).IsArray) + { + var expectedArray = (Array)(object)expected; + var actualArray = (Array)(object)actual!; + + Assert.NotNull(actualArray); + AssertEqual(expectedArray.Length, actualArray.Length, $"{nameof}.Length"); + + for (var i = 0; i < expectedArray.Length; i++) + AssertEqual(expectedArray.GetValue(i), actualArray.GetValue(i), $"{nameof}[{i}]"); + + return; + } + + Assert.True(expected.Equals(actual), $"Expected {nameof} '{expected}' but got '{actual}'"); + } + internal static void AssertMap(Map expected, Map actual) { // Attributes - Assert.Equal(expected.Version, actual.Version); - Assert.Equal(expected.TiledVersion, actual.TiledVersion); - Assert.Equal(expected.Class, actual.Class); - Assert.Equal(expected.Orientation, actual.Orientation); - Assert.Equal(expected.RenderOrder, actual.RenderOrder); - Assert.Equal(expected.CompressionLevel, actual.CompressionLevel); - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); - Assert.Equal(expected.TileWidth, actual.TileWidth); - Assert.Equal(expected.TileHeight, actual.TileHeight); - Assert.Equal(expected.HexSideLength, actual.HexSideLength); - Assert.Equal(expected.StaggerAxis, actual.StaggerAxis); - Assert.Equal(expected.StaggerIndex, actual.StaggerIndex); - Assert.Equal(expected.ParallaxOriginX, actual.ParallaxOriginX); - Assert.Equal(expected.ParallaxOriginY, actual.ParallaxOriginY); - Assert.Equal(expected.BackgroundColor, actual.BackgroundColor); - Assert.Equal(expected.NextLayerID, actual.NextLayerID); - Assert.Equal(expected.NextObjectID, actual.NextObjectID); - Assert.Equal(expected.Infinite, actual.Infinite); + AssertEqual(expected.Version, actual.Version, nameof(Map.Version)); + AssertEqual(expected.TiledVersion, actual.TiledVersion, nameof(Map.TiledVersion)); + AssertEqual(expected.Class, actual.Class, nameof(Map.Class)); + AssertEqual(expected.Orientation, actual.Orientation, nameof(Map.Orientation)); + AssertEqual(expected.RenderOrder, actual.RenderOrder, nameof(Map.RenderOrder)); + AssertEqual(expected.CompressionLevel, actual.CompressionLevel, nameof(Map.CompressionLevel)); + AssertEqual(expected.Width, actual.Width, nameof(Map.Width)); + AssertEqual(expected.Height, actual.Height, nameof(Map.Height)); + AssertEqual(expected.TileWidth, actual.TileWidth, nameof(Map.TileWidth)); + AssertEqual(expected.TileHeight, actual.TileHeight, nameof(Map.TileHeight)); + AssertEqual(expected.HexSideLength, actual.HexSideLength, nameof(Map.HexSideLength)); + AssertEqual(expected.StaggerAxis, actual.StaggerAxis, nameof(Map.StaggerAxis)); + AssertEqual(expected.StaggerIndex, actual.StaggerIndex, nameof(Map.StaggerIndex)); + AssertEqual(expected.ParallaxOriginX, actual.ParallaxOriginX, nameof(Map.ParallaxOriginX)); + AssertEqual(expected.ParallaxOriginY, actual.ParallaxOriginY, nameof(Map.ParallaxOriginY)); + AssertEqual(expected.BackgroundColor, actual.BackgroundColor, nameof(Map.BackgroundColor)); + AssertEqual(expected.NextLayerID, actual.NextLayerID, nameof(Map.NextLayerID)); + AssertEqual(expected.NextObjectID, actual.NextObjectID, nameof(Map.NextObjectID)); + AssertEqual(expected.Infinite, actual.Infinite, nameof(Map.Infinite)); AssertProperties(actual.Properties, expected.Properties); Assert.NotNull(actual.Tilesets); - Assert.Equal(expected.Tilesets.Count, actual.Tilesets.Count); + AssertEqual(expected.Tilesets.Count, actual.Tilesets.Count, "Tilesets.Count"); for (var i = 0; i < expected.Tilesets.Count; i++) AssertTileset(expected.Tilesets[i], actual.Tilesets[i]); Assert.NotNull(actual.Layers); - Assert.Equal(expected.Layers.Count, actual.Layers.Count); + AssertEqual(expected.Layers.Count, actual.Layers.Count, "Layers.Count"); for (var i = 0; i < expected.Layers.Count; i++) AssertLayer(expected.Layers[i], actual.Layers[i]); } diff --git a/DotTiled.Tests/Assert/AssertObject.cs b/DotTiled.Tests/Assert/AssertObject.cs index 3b08744..c49b6e7 100644 --- a/DotTiled.Tests/Assert/AssertObject.cs +++ b/DotTiled.Tests/Assert/AssertObject.cs @@ -5,17 +5,17 @@ public static partial class DotTiledAssert internal static void AssertObject(Object expected, Object actual) { // Attributes - Assert.Equal(expected.ID, actual.ID); - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.Type, actual.Type); - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); - Assert.Equal(expected.Rotation, actual.Rotation); - Assert.Equal(expected.GID, actual.GID); - Assert.Equal(expected.Visible, actual.Visible); - Assert.Equal(expected.Template, actual.Template); + AssertEqual(expected.ID, actual.ID, nameof(Object.ID)); + AssertEqual(expected.Name, actual.Name, nameof(Object.Name)); + AssertEqual(expected.Type, actual.Type, nameof(Object.Type)); + AssertEqual(expected.X, actual.X, nameof(Object.X)); + AssertEqual(expected.Y, actual.Y, nameof(Object.Y)); + AssertEqual(expected.Width, actual.Width, nameof(Object.Width)); + AssertEqual(expected.Height, actual.Height, nameof(Object.Height)); + AssertEqual(expected.Rotation, actual.Rotation, nameof(Object.Rotation)); + AssertEqual(expected.GID, actual.GID, nameof(Object.GID)); + AssertEqual(expected.Visible, actual.Visible, nameof(Object.Visible)); + AssertEqual(expected.Template, actual.Template, nameof(Object.Template)); AssertProperties(expected.Properties, actual.Properties); AssertObject((dynamic)expected, (dynamic)actual); @@ -38,29 +38,29 @@ public static partial class DotTiledAssert private static void AssertObject(PolygonObject expected, PolygonObject actual) { - Assert.Equal(expected.Points, actual.Points); + AssertEqual(expected.Points, actual.Points, nameof(PolygonObject.Points)); } private static void AssertObject(PolylineObject expected, PolylineObject actual) { - Assert.Equal(expected.Points, actual.Points); + AssertEqual(expected.Points, actual.Points, nameof(PolylineObject.Points)); } private static void AssertObject(TextObject expected, TextObject actual) { // Attributes - Assert.Equal(expected.FontFamily, actual.FontFamily); - Assert.Equal(expected.PixelSize, actual.PixelSize); - Assert.Equal(expected.Wrap, actual.Wrap); - Assert.Equal(expected.Color, actual.Color); - Assert.Equal(expected.Bold, actual.Bold); - Assert.Equal(expected.Italic, actual.Italic); - Assert.Equal(expected.Underline, actual.Underline); - Assert.Equal(expected.Strikeout, actual.Strikeout); - Assert.Equal(expected.Kerning, actual.Kerning); - Assert.Equal(expected.HorizontalAlignment, actual.HorizontalAlignment); - Assert.Equal(expected.VerticalAlignment, actual.VerticalAlignment); + AssertEqual(expected.FontFamily, actual.FontFamily, nameof(TextObject.FontFamily)); + AssertEqual(expected.PixelSize, actual.PixelSize, nameof(TextObject.PixelSize)); + AssertEqual(expected.Wrap, actual.Wrap, nameof(TextObject.Wrap)); + AssertEqual(expected.Color, actual.Color, nameof(TextObject.Color)); + AssertEqual(expected.Bold, actual.Bold, nameof(TextObject.Bold)); + AssertEqual(expected.Italic, actual.Italic, nameof(TextObject.Italic)); + AssertEqual(expected.Underline, actual.Underline, nameof(TextObject.Underline)); + AssertEqual(expected.Strikeout, actual.Strikeout, nameof(TextObject.Strikeout)); + AssertEqual(expected.Kerning, actual.Kerning, nameof(TextObject.Kerning)); + AssertEqual(expected.HorizontalAlignment, actual.HorizontalAlignment, nameof(TextObject.HorizontalAlignment)); + AssertEqual(expected.VerticalAlignment, actual.VerticalAlignment, nameof(TextObject.VerticalAlignment)); - Assert.Equal(expected.Text, actual.Text); + AssertEqual(expected.Text, actual.Text, nameof(TextObject.Text)); } } diff --git a/DotTiled.Tests/Assert/AssertProperties.cs b/DotTiled.Tests/Assert/AssertProperties.cs index afd28c2..740ba2b 100644 --- a/DotTiled.Tests/Assert/AssertProperties.cs +++ b/DotTiled.Tests/Assert/AssertProperties.cs @@ -11,7 +11,7 @@ public static partial class DotTiledAssert } Assert.NotNull(actual); - Assert.Equal(expected.Count, actual.Count); + AssertEqual(expected.Count, actual.Count, "Properties.Count"); foreach (var kvp in expected) { Assert.Contains(kvp.Key, actual.Keys); @@ -21,49 +21,49 @@ public static partial class DotTiledAssert private static void AssertProperty(IProperty expected, IProperty actual) { - Assert.Equal(expected.Type, actual.Type); - Assert.Equal(expected.Name, actual.Name); + AssertEqual(expected.Type, actual.Type, "Property.Type"); + AssertEqual(expected.Name, actual.Name, "Property.Name"); AssertProperties((dynamic)actual, (dynamic)expected); } private static void AssertProperty(StringProperty expected, StringProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "StringProperty.Value"); } private static void AssertProperty(IntProperty expected, IntProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "IntProperty.Value"); } private static void AssertProperty(FloatProperty expected, FloatProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "FloatProperty.Value"); } private static void AssertProperty(BoolProperty expected, BoolProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "BoolProperty.Value"); } private static void AssertProperty(ColorProperty expected, ColorProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "ColorProperty.Value"); } private static void AssertProperty(FileProperty expected, FileProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "FileProperty.Value"); } private static void AssertProperty(ObjectProperty expected, ObjectProperty actual) { - Assert.Equal(expected.Value, actual.Value); + AssertEqual(expected.Value, actual.Value, "ObjectProperty.Value"); } private static void AssertProperty(ClassProperty expected, ClassProperty actual) { - Assert.Equal(expected.PropertyType, actual.PropertyType); + AssertEqual(expected.PropertyType, actual.PropertyType, "ClassProperty.PropertyType"); AssertProperties(expected.Properties, actual.Properties); } } diff --git a/DotTiled.Tests/Assert/AssertTileset.cs b/DotTiled.Tests/Assert/AssertTileset.cs index 8421bd0..e6b39bb 100644 --- a/DotTiled.Tests/Assert/AssertTileset.cs +++ b/DotTiled.Tests/Assert/AssertTileset.cs @@ -5,21 +5,21 @@ public static partial class DotTiledAssert internal static void AssertTileset(Tileset expected, Tileset actual) { // Attributes - Assert.Equal(expected.Version, actual.Version); - Assert.Equal(expected.TiledVersion, actual.TiledVersion); - Assert.Equal(expected.FirstGID, actual.FirstGID); - Assert.Equal(expected.Source, actual.Source); - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.Class, actual.Class); - Assert.Equal(expected.TileWidth, actual.TileWidth); - Assert.Equal(expected.TileHeight, actual.TileHeight); - Assert.Equal(expected.Spacing, actual.Spacing); - Assert.Equal(expected.Margin, actual.Margin); - Assert.Equal(expected.TileCount, actual.TileCount); - Assert.Equal(expected.Columns, actual.Columns); - Assert.Equal(expected.ObjectAlignment, actual.ObjectAlignment); - Assert.Equal(expected.RenderSize, actual.RenderSize); - Assert.Equal(expected.FillMode, actual.FillMode); + AssertEqual(expected.Version, actual.Version, nameof(Tileset.Version)); + AssertEqual(expected.TiledVersion, actual.TiledVersion, nameof(Tileset.TiledVersion)); + AssertEqual(expected.FirstGID, actual.FirstGID, nameof(Tileset.FirstGID)); + AssertEqual(expected.Source, actual.Source, nameof(Tileset.Source)); + AssertEqual(expected.Name, actual.Name, nameof(Tileset.Name)); + AssertEqual(expected.Class, actual.Class, nameof(Tileset.Class)); + AssertEqual(expected.TileWidth, actual.TileWidth, nameof(Tileset.TileWidth)); + AssertEqual(expected.TileHeight, actual.TileHeight, nameof(Tileset.TileHeight)); + AssertEqual(expected.Spacing, actual.Spacing, nameof(Tileset.Spacing)); + AssertEqual(expected.Margin, actual.Margin, nameof(Tileset.Margin)); + AssertEqual(expected.TileCount, actual.TileCount, nameof(Tileset.TileCount)); + AssertEqual(expected.Columns, actual.Columns, nameof(Tileset.Columns)); + AssertEqual(expected.ObjectAlignment, actual.ObjectAlignment, nameof(Tileset.ObjectAlignment)); + AssertEqual(expected.RenderSize, actual.RenderSize, nameof(Tileset.RenderSize)); + AssertEqual(expected.FillMode, actual.FillMode, nameof(Tileset.FillMode)); // At most one of AssertImage(expected.Image, actual.Image); @@ -30,7 +30,7 @@ public static partial class DotTiledAssert if (expected.Wangsets is not null) { Assert.NotNull(actual.Wangsets); - Assert.Equal(expected.Wangsets.Count, actual.Wangsets.Count); + AssertEqual(expected.Wangsets.Count, actual.Wangsets.Count, "Wangsets.Count"); for (var i = 0; i < expected.Wangsets.Count; i++) AssertWangset(expected.Wangsets[i], actual.Wangsets[i]); } @@ -38,7 +38,7 @@ public static partial class DotTiledAssert // Any number of Assert.NotNull(actual.Tiles); - Assert.Equal(expected.Tiles.Count, actual.Tiles.Count); + AssertEqual(expected.Tiles.Count, actual.Tiles.Count, "Tiles.Count"); for (var i = 0; i < expected.Tiles.Count; i++) AssertTile(expected.Tiles[i], actual.Tiles[i]); } @@ -53,8 +53,8 @@ public static partial class DotTiledAssert // Attributes Assert.NotNull(actual); - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); + AssertEqual(expected.X, actual.X, nameof(TileOffset.X)); + AssertEqual(expected.Y, actual.Y, nameof(TileOffset.Y)); } private static void AssertGrid(Grid? expected, Grid? actual) @@ -67,24 +67,24 @@ public static partial class DotTiledAssert // Attributes Assert.NotNull(actual); - Assert.Equal(expected.Orientation, actual.Orientation); - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); + AssertEqual(expected.Orientation, actual.Orientation, nameof(Grid.Orientation)); + AssertEqual(expected.Width, actual.Width, nameof(Grid.Width)); + AssertEqual(expected.Height, actual.Height, nameof(Grid.Height)); } private static void AssertWangset(Wangset expected, Wangset actual) { // Attributes - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.Class, actual.Class); - Assert.Equal(expected.Tile, actual.Tile); + AssertEqual(expected.Name, actual.Name, nameof(Wangset.Name)); + AssertEqual(expected.Class, actual.Class, nameof(Wangset.Class)); + AssertEqual(expected.Tile, actual.Tile, nameof(Wangset.Tile)); // At most one of AssertProperties(expected.Properties, actual.Properties); if (expected.WangColors is not null) { Assert.NotNull(actual.WangColors); - Assert.Equal(expected.WangColors.Count, actual.WangColors.Count); + AssertEqual(expected.WangColors.Count, actual.WangColors.Count, "WangColors.Count"); for (var i = 0; i < expected.WangColors.Count; i++) AssertWangColor(expected.WangColors[i], actual.WangColors[i]); } @@ -95,11 +95,11 @@ public static partial class DotTiledAssert private static void AssertWangColor(WangColor expected, WangColor actual) { // Attributes - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.Class, actual.Class); - Assert.Equal(expected.Color, actual.Color); - Assert.Equal(expected.Tile, actual.Tile); - Assert.Equal(expected.Probability, actual.Probability); + AssertEqual(expected.Name, actual.Name, nameof(WangColor.Name)); + AssertEqual(expected.Class, actual.Class, nameof(WangColor.Class)); + AssertEqual(expected.Color, actual.Color, nameof(WangColor.Color)); + AssertEqual(expected.Tile, actual.Tile, nameof(WangColor.Tile)); + AssertEqual(expected.Probability, actual.Probability, nameof(WangColor.Probability)); AssertProperties(expected.Properties, actual.Properties); } @@ -107,8 +107,8 @@ public static partial class DotTiledAssert private static void AssertWangTile(WangTile expected, WangTile actual) { // Attributes - Assert.Equal(expected.TileID, actual.TileID); - Assert.Equal(expected.WangID, actual.WangID); + AssertEqual(expected.TileID, actual.TileID, nameof(WangTile.TileID)); + AssertEqual(expected.WangID, actual.WangID, nameof(WangTile.WangID)); } private static void AssertTransformations(Transformations? expected, Transformations? actual) @@ -121,22 +121,22 @@ public static partial class DotTiledAssert // Attributes Assert.NotNull(actual); - Assert.Equal(expected.HFlip, actual.HFlip); - Assert.Equal(expected.VFlip, actual.VFlip); - Assert.Equal(expected.Rotate, actual.Rotate); - Assert.Equal(expected.PreferUntransformed, actual.PreferUntransformed); + AssertEqual(expected.HFlip, actual.HFlip, nameof(Transformations.HFlip)); + AssertEqual(expected.VFlip, actual.VFlip, nameof(Transformations.VFlip)); + AssertEqual(expected.Rotate, actual.Rotate, nameof(Transformations.Rotate)); + AssertEqual(expected.PreferUntransformed, actual.PreferUntransformed, nameof(Transformations.PreferUntransformed)); } private static void AssertTile(Tile expected, Tile actual) { // Attributes - Assert.Equal(expected.ID, actual.ID); - Assert.Equal(expected.Type, actual.Type); - Assert.Equal(expected.Probability, actual.Probability); - Assert.Equal(expected.X, actual.X); - Assert.Equal(expected.Y, actual.Y); - Assert.Equal(expected.Width, actual.Width); - Assert.Equal(expected.Height, actual.Height); + AssertEqual(expected.ID, actual.ID, nameof(Tile.ID)); + AssertEqual(expected.Type, actual.Type, nameof(Tile.Type)); + AssertEqual(expected.Probability, actual.Probability, nameof(Tile.Probability)); + AssertEqual(expected.X, actual.X, nameof(Tile.X)); + AssertEqual(expected.Y, actual.Y, nameof(Tile.Y)); + AssertEqual(expected.Width, actual.Width, nameof(Tile.Width)); + AssertEqual(expected.Height, actual.Height, nameof(Tile.Height)); // Elements AssertProperties(actual.Properties, expected.Properties); @@ -145,7 +145,7 @@ public static partial class DotTiledAssert if (expected.Animation is not null) { Assert.NotNull(actual.Animation); - Assert.Equal(expected.Animation.Count, actual.Animation.Count); + AssertEqual(expected.Animation.Count, actual.Animation.Count, "Animation.Count"); for (var i = 0; i < expected.Animation.Count; i++) AssertFrame(expected.Animation[i], actual.Animation[i]); } @@ -154,7 +154,7 @@ public static partial class DotTiledAssert private static void AssertFrame(Frame expected, Frame actual) { // Attributes - Assert.Equal(expected.TileID, actual.TileID); - Assert.Equal(expected.Duration, actual.Duration); + AssertEqual(expected.TileID, actual.TileID, nameof(Frame.TileID)); + AssertEqual(expected.Duration, actual.Duration, nameof(Frame.Duration)); } } diff --git a/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs index 44c909e..eff73d9 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs +++ b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs @@ -36,58 +36,18 @@ public partial class TestData Chunks = null, Compression = null, GlobalTileIDs = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 ], FlippingFlags = [ - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None, - FlippingFlags.None + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None ] } } From 46d5127c72396a8901286f7bf0d4d4d4b7c14e01 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 22:07:30 +0200 Subject: [PATCH 03/12] Tests are automatically created when populating the available test data --- DotTiled.Tests/Serialization/TestData.cs | 40 +++++++++++++++ .../Serialization/Tmj/TmjMapReaderTests.cs | 49 +++---------------- .../Serialization/Tmx/TmxMapReaderTests.cs | 48 +++--------------- 3 files changed, 54 insertions(+), 83 deletions(-) diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 9b3b13f..8fc9b9e 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -27,4 +27,44 @@ public static partial class TestData using var stringReader = new StreamReader(stream); return stringReader.ReadToEnd(); } + + public static IEnumerable MapsThatHaveTmxAndTmj => + [ + ["Serialization.TestData.Map.default_map.default-map", TestData.DefaultMap(), Array.Empty()] + ]; + + private static CustomTypeDefinition[] typedefs = [ + new CustomClassDefinition + { + Name = "TestClass", + ID = 1, + UseAs = CustomClassUseAs.Property, + Members = [ + new StringProperty + { + Name = "Name", + Value = "" + }, + new FloatProperty + { + Name = "Amount", + Value = 0f + } + ] + }, + new CustomClassDefinition + { + Name = "Test", + ID = 2, + UseAs = CustomClassUseAs.All, + Members = [ + new ClassProperty + { + Name = "Yep", + PropertyType = "TestClass", + Properties = [] + } + ] + } + ]; } diff --git a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs index e04423b..0cdad90 100644 --- a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs @@ -2,51 +2,16 @@ namespace DotTiled.Tests; public partial class TmjMapReaderTests { - public static IEnumerable DeserializeMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data => - [ - ["Serialization.TestData.Map.default_map.default-map.tmj", TestData.DefaultMap()] - ]; - + public static IEnumerable Maps => TestData.MapsThatHaveTmxAndTmj; [Theory] - [MemberData(nameof(DeserializeMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) + [MemberData(nameof(Maps))] + public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( + string testDataFile, + Map expectedMap, + IReadOnlyCollection customTypeDefinitions) { // Arrange - CustomTypeDefinition[] customTypeDefinitions = [ - new CustomClassDefinition - { - Name = "TestClass", - ID = 1, - UseAs = CustomClassUseAs.Property, - Members = [ - new StringProperty - { - Name = "Name", - Value = "" - }, - new FloatProperty - { - Name = "Amount", - Value = 0f - } - ] - }, - new CustomClassDefinition - { - Name = "Test", - ID = 2, - UseAs = CustomClassUseAs.All, - Members = [ - new ClassProperty - { - Name = "Yep", - PropertyType = "TestClass", - Properties = [] - } - ] - } - ]; - + testDataFile += ".tmj"; var json = TestData.GetRawStringFor(testDataFile); Template ResolveTemplate(string source) { diff --git a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs index 5ee162f..3134863 100644 --- a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs @@ -4,50 +4,16 @@ namespace DotTiled.Tests; public partial class TmxMapReaderTests { - public static IEnumerable DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data => - [ - ["Serialization.TestData.Map.default_map.default-map.tmx", TestData.DefaultMap()] - ]; - + public static IEnumerable Maps => TestData.MapsThatHaveTmxAndTmj; [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) + [MemberData(nameof(Maps))] + public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( + string testDataFile, + Map expectedMap, + IReadOnlyCollection customTypeDefinitions) { // Arrange - CustomTypeDefinition[] customTypeDefinitions = [ - new CustomClassDefinition - { - Name = "TestClass", - ID = 1, - UseAs = CustomClassUseAs.Property, - Members = [ - new StringProperty - { - Name = "Name", - Value = "" - }, - new FloatProperty - { - Name = "Amount", - Value = 0f - } - ] - }, - new CustomClassDefinition - { - Name = "Test", - ID = 2, - UseAs = CustomClassUseAs.All, - Members = [ - new ClassProperty - { - Name = "Yep", - PropertyType = "TestClass", - Properties = [] - } - ] - } - ]; + testDataFile += ".tmx"; using var reader = TestData.GetXmlReaderFor(testDataFile); Template ResolveTemplate(string source) { From 5fd05683f61b61c0d57ca010b13b5bb07131e210 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 22:17:13 +0200 Subject: [PATCH 04/12] Add tests for common properties in maps --- DotTiled.Tests/Serialization/TestData.cs | 3 +- .../map-with-common-props.cs | 68 ++++++++++++++++++ .../map-with-common-props.tmj | 70 +++++++++++++++++++ .../map-with-common-props.tmx | 21 ++++++ 4 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmx diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 8fc9b9e..5cdf444 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -30,7 +30,8 @@ public static partial class TestData public static IEnumerable MapsThatHaveTmxAndTmj => [ - ["Serialization.TestData.Map.default_map.default-map", TestData.DefaultMap(), Array.Empty()] + ["Serialization.TestData.Map.default_map.default-map", TestData.DefaultMap(), Array.Empty()], + ["Serialization.TestData.Map.map_with_common_props.map-with-common-props", TestData.MapWithCommonProps(), Array.Empty()] ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.cs new file mode 100644 index 0000000..8c3283e --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.cs @@ -0,0 +1,68 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithCommonProps() => new Map + { + Class = "", + Orientation = MapOrientation.Isometric, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 16, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00ff00", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ], + Properties = new Dictionary + { + ["boolprop"] = new BoolProperty { Name = "boolprop", Value = true }, + ["colorprop"] = new ColorProperty { Name = "colorprop", Value = Color.Parse("#ff55ffff", CultureInfo.InvariantCulture) }, + ["fileprop"] = new FileProperty { Name = "fileprop", Value = "file.txt" }, + ["floatprop"] = new FloatProperty { Name = "floatprop", Value = 4.2f }, + ["intprop"] = new IntProperty { Name = "intprop", Value = 8 }, + ["objectprop"] = new ObjectProperty { Name = "objectprop", Value = 5 }, + ["stringprop"] = new StringProperty { Name = "stringprop", Value = "This is a string, hello world!" } + } + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj new file mode 100644 index 0000000..c7182ef --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj @@ -0,0 +1,70 @@ +{ "backgroundcolor":"#00ff00", + "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"isometric", + "properties":[ + { + "name":"boolprop", + "type":"bool", + "value":true + }, + { + "name":"colorprop", + "type":"color", + "value":"#ff55ffff" + }, + { + "name":"fileprop", + "type":"file", + "value":"file.txt" + }, + { + "name":"floatprop", + "type":"float", + "value":4.2 + }, + { + "name":"intprop", + "type":"int", + "value":8 + }, + + { + "name":"objectprop", + "type":"object", + "value":5 + }, + { + "name":"stringprop", + "type":"string", + "value":"This is a string, hello world!" + }], + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":16, + "tilesets":[], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmx new file mode 100644 index 0000000..b4b36cd --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmx @@ -0,0 +1,21 @@ + + + + + + + + + + + + + +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0 + + + From 7b7e499b0de16325f067def1e3ba8fe61182737f Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 22:33:00 +0200 Subject: [PATCH 05/12] Add tests for custom type properties in maps --- DotTiled.Tests/Serialization/TestData.cs | 5 +- .../map-with-custom-type-props.cs | 122 ++++++++++++++++++ .../map-with-custom-type-props.tmj | 44 +++++++ .../map-with-custom-type-props.tmx | 21 +++ .../propertytypes.json | 49 +++++++ .../Serialization/Tmj/TmjMapReaderTests.cs | 2 +- .../Serialization/Tmx/TmxMapReaderTests.cs | 2 +- DotTiled/Model/Color.cs | 2 + 8 files changed, 243 insertions(+), 4 deletions(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/propertytypes.json diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 5cdf444..371e8b7 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -28,10 +28,11 @@ public static partial class TestData return stringReader.ReadToEnd(); } - public static IEnumerable MapsThatHaveTmxAndTmj => + public static IEnumerable MapTests => [ ["Serialization.TestData.Map.default_map.default-map", TestData.DefaultMap(), Array.Empty()], - ["Serialization.TestData.Map.map_with_common_props.map-with-common-props", TestData.MapWithCommonProps(), Array.Empty()] + ["Serialization.TestData.Map.map_with_common_props.map-with-common-props", TestData.MapWithCommonProps(), Array.Empty()], + ["Serialization.TestData.Map.map_with_custom_type_props.map-with-custom-type-props", TestData.MapWithCustomTypeProps(), TestData.MapWithCustomTypePropsCustomTypeDefinitions()] ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.cs new file mode 100644 index 0000000..1343f62 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.cs @@ -0,0 +1,122 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithCustomTypeProps() => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ], + Properties = new Dictionary + { + ["customclassprop"] = new ClassProperty + { + Name = "customclassprop", + PropertyType = "CustomClass", + Properties = new Dictionary + { + ["boolinclass"] = new BoolProperty { Name = "boolinclass", Value = true }, + ["colorinclass"] = new ColorProperty { Name = "colorinclass", Value = Color.Parse("#000000ff", CultureInfo.InvariantCulture) }, + ["fileinclass"] = new FileProperty { Name = "fileinclass", Value = "" }, + ["floatinclass"] = new FloatProperty { Name = "floatinclass", Value = 13.37f }, + ["intinclass"] = new IntProperty { Name = "intinclass", Value = 0 }, + ["objectinclass"] = new ObjectProperty { Name = "objectinclass", Value = 0 }, + ["stringinclass"] = new StringProperty { Name = "stringinclass", Value = "This is a set string" } + } + } + } + }; + + // This comes from map-with-custom-type-props/propertytypes.json + public static IReadOnlyCollection MapWithCustomTypePropsCustomTypeDefinitions() => [ + new CustomClassDefinition + { + Name = "CustomClass", + UseAs = CustomClassUseAs.Property, + Members = [ + new BoolProperty + { + Name = "boolinclass", + Value = false + }, + new ColorProperty + { + Name = "colorinclass", + Value = Color.Parse("#000000ff", CultureInfo.InvariantCulture) + }, + new FileProperty + { + Name = "fileinclass", + Value = "" + }, + new FloatProperty + { + Name = "floatinclass", + Value = 0f + }, + new IntProperty + { + Name = "intinclass", + Value = 0 + }, + new ObjectProperty + { + Name = "objectinclass", + Value = 0 + }, + new StringProperty + { + Name = "stringinclass", + Value = "" + } + ] + } + ]; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmj new file mode 100644 index 0000000..a8c7f43 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmj @@ -0,0 +1,44 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "properties":[ + { + "name":"customclassprop", + "propertytype":"CustomClass", + "type":"class", + "value": + { + "boolinclass":true, + "floatinclass":13.37, + "stringinclass":"This is a set string" + } + }], + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx new file mode 100644 index 0000000..c364577 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx @@ -0,0 +1,21 @@ + + + + + + + + + + + + + +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/propertytypes.json b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/propertytypes.json new file mode 100644 index 0000000..16c42fb --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/propertytypes.json @@ -0,0 +1,49 @@ +[ + { + "color": "#ffa0a0a4", + "drawFill": true, + "id": 8, + "members": [ + { + "name": "boolinclass", + "type": "bool", + "value": false + }, + { + "name": "colorinclass", + "type": "color", + "value": "" + }, + { + "name": "fileinclass", + "type": "file", + "value": "" + }, + { + "name": "floatinclass", + "type": "float", + "value": 0 + }, + { + "name": "intinclass", + "type": "int", + "value": 0 + }, + { + "name": "objectinclass", + "type": "object", + "value": 0 + }, + { + "name": "stringinclass", + "type": "string", + "value": "" + } + ], + "name": "CustomClass", + "type": "class", + "useAs": [ + "property" + ] + } +] diff --git a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs index 0cdad90..71e5304 100644 --- a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs @@ -2,7 +2,7 @@ namespace DotTiled.Tests; public partial class TmjMapReaderTests { - public static IEnumerable Maps => TestData.MapsThatHaveTmxAndTmj; + public static IEnumerable Maps => TestData.MapTests; [Theory] [MemberData(nameof(Maps))] public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( diff --git a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs index 3134863..c0dc083 100644 --- a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs @@ -4,7 +4,7 @@ namespace DotTiled.Tests; public partial class TmxMapReaderTests { - public static IEnumerable Maps => TestData.MapsThatHaveTmxAndTmj; + public static IEnumerable Maps => TestData.MapTests; [Theory] [MemberData(nameof(Maps))] public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( diff --git a/DotTiled/Model/Color.cs b/DotTiled/Model/Color.cs index 29bafe9..ae74d0d 100644 --- a/DotTiled/Model/Color.cs +++ b/DotTiled/Model/Color.cs @@ -66,4 +66,6 @@ public class Color : IParsable, IEquatable public override bool Equals(object? obj) => obj is Color other && Equals(other); public override int GetHashCode() => HashCode.Combine(R, G, B, A); + + public override string ToString() => $"#{A:x2}{R:x2}{G:x2}{B:x2}"; } From f82487f46a6179cc742b1ef007ffd5de60150ed8 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 22:44:55 +0200 Subject: [PATCH 06/12] Add embedded tileset test case --- DotTiled.Tests/Serialization/TestData.cs | 3 +- .../map-with-embedded-tileset.cs | 76 ++++++++++++++++++ .../map-with-embedded-tileset.tmj | 45 +++++++++++ .../map-with-embedded-tileset.tmx | 15 ++++ .../Map/map-with-embedded-tileset/tileset.png | Bin 0 -> 11908 bytes 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/tileset.png diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 371e8b7..eac8d05 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -32,7 +32,8 @@ public static partial class TestData [ ["Serialization.TestData.Map.default_map.default-map", TestData.DefaultMap(), Array.Empty()], ["Serialization.TestData.Map.map_with_common_props.map-with-common-props", TestData.MapWithCommonProps(), Array.Empty()], - ["Serialization.TestData.Map.map_with_custom_type_props.map-with-custom-type-props", TestData.MapWithCustomTypeProps(), TestData.MapWithCustomTypePropsCustomTypeDefinitions()] + ["Serialization.TestData.Map.map_with_custom_type_props.map-with-custom-type-props", TestData.MapWithCustomTypeProps(), TestData.MapWithCustomTypePropsCustomTypeDefinitions()], + ["Serialization.TestData.Map.map_with_embedded_tileset.map-with-embedded-tileset", TestData.MapWithEmbeddedTileset(), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs new file mode 100644 index 0000000..fb3c95f --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs @@ -0,0 +1,76 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithEmbeddedTileset() => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Tilesets = [ + new Tileset + { + FirstGID = 1, + Name = "tileset", + TileWidth = 32, + TileHeight = 32, + TileCount = 24, + Columns = 8, + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96, + } + } + ], + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 1, 1, 0, 0, 7, + 1, 1, 0, 0, 7, + 0, 0, 0, 0, 7, + 9, 10, 0, 0, 7, + 17, 18, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmj new file mode 100644 index 0000000..41d5e7b --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmj @@ -0,0 +1,45 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[1, 1, 0, 0, 7, + 1, 1, 0, 0, 7, + 0, 0, 0, 0, 7, + 9, 10, 0, 0, 7, + 17, 18, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[ + { + "columns":8, + "firstgid":1, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":24, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx new file mode 100644 index 0000000..43ca51c --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx @@ -0,0 +1,15 @@ + + + + + + + +1,1,0,0,7, +1,1,0,0,7, +0,0,0,0,7, +9,10,0,0,7, +17,18,0,0,0 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1fb31b1fa4dcf1214b8fe9b2e2b8e287c72d0 GIT binary patch literal 11908 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 Pn-8F-q^(#jZyEZ3BaoJ| literal 0 HcmV?d00001 From a1a2e3d3733a75138c647facee32df521f99de80 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 23:03:53 +0200 Subject: [PATCH 07/12] Add tests for external tilesets in maps --- DotTiled.Tests/Serialization/TestData.cs | 18 +-- .../CustomTypes/large-propertytypes.json | 103 ------------------ ...ap-with-object-template-propertytypes.json | 24 ---- .../map-with-external-tileset.cs | 79 ++++++++++++++ .../map-with-external-tileset.tmj | 36 ++++++ .../map-with-external-tileset.tmx | 13 +++ .../Map/map-with-external-tileset/tileset.png | Bin 0 -> 11908 bytes .../Map/map-with-external-tileset/tileset.tsj | 14 +++ .../Map/map-with-external-tileset/tileset.tsx | 4 + .../Serialization/Tmj/TmjMapReaderTests.cs | 9 +- .../Serialization/Tmx/TmxMapReaderTests.cs | 9 +- DotTiled/Serialization/Tmx/Tmx.Tileset.cs | 2 +- 12 files changed, 167 insertions(+), 144 deletions(-) delete mode 100644 DotTiled.Tests/Serialization/TestData/CustomTypes/large-propertytypes.json delete mode 100644 DotTiled.Tests/Serialization/TestData/CustomTypes/map-with-object-template-propertytypes.json create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.png create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsx diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index eac8d05..254cba7 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -6,9 +6,7 @@ public static partial class TestData { public static XmlReader GetXmlReaderFor(string testDataFile) { - var names = typeof(TestData).Assembly.GetManifestResourceNames(); - - var fullyQualifiedTestDataFile = $"DotTiled.Tests.{testDataFile}"; + var fullyQualifiedTestDataFile = $"DotTiled.Tests.{ConvertPathToAssemblyResourcePath(testDataFile)}"; using var stream = typeof(TestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) ?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found"); @@ -20,7 +18,7 @@ public static partial class TestData public static string GetRawStringFor(string testDataFile) { - var fullyQualifiedTestDataFile = $"DotTiled.Tests.{testDataFile}"; + var fullyQualifiedTestDataFile = $"DotTiled.Tests.{ConvertPathToAssemblyResourcePath(testDataFile)}"; using var stream = typeof(TestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) ?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found"); @@ -28,12 +26,16 @@ public static partial class TestData return stringReader.ReadToEnd(); } + private static string ConvertPathToAssemblyResourcePath(string path) => + path.Replace("/", ".").Replace("\\", ".").Replace(" ", "_"); + public static IEnumerable MapTests => [ - ["Serialization.TestData.Map.default_map.default-map", TestData.DefaultMap(), Array.Empty()], - ["Serialization.TestData.Map.map_with_common_props.map-with-common-props", TestData.MapWithCommonProps(), Array.Empty()], - ["Serialization.TestData.Map.map_with_custom_type_props.map-with-custom-type-props", TestData.MapWithCustomTypeProps(), TestData.MapWithCustomTypePropsCustomTypeDefinitions()], - ["Serialization.TestData.Map.map_with_embedded_tileset.map-with-embedded-tileset", TestData.MapWithEmbeddedTileset(), Array.Empty()], + ["Serialization/TestData/Map/default_map/default-map", (string f) => TestData.DefaultMap(), Array.Empty()], + ["Serialization/TestData/Map/map_with_common_props/map-with-common-props", (string f) => TestData.MapWithCommonProps(), Array.Empty()], + ["Serialization/TestData/Map/map_with_custom_type_props/map-with-custom-type-props", (string f) => TestData.MapWithCustomTypeProps(), TestData.MapWithCustomTypePropsCustomTypeDefinitions()], + ["Serialization/TestData/Map/map_with_embedded_tileset/map-with-embedded-tileset", (string f) => TestData.MapWithEmbeddedTileset(), Array.Empty()], + ["Serialization/TestData/Map/map_with_external_tileset/map-with-external-tileset", (string f) => TestData.MapWithExternalTileset(f), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/CustomTypes/large-propertytypes.json b/DotTiled.Tests/Serialization/TestData/CustomTypes/large-propertytypes.json deleted file mode 100644 index e21cf83..0000000 --- a/DotTiled.Tests/Serialization/TestData/CustomTypes/large-propertytypes.json +++ /dev/null @@ -1,103 +0,0 @@ -[ - { - "id": 4, - "name": "Enum0String", - "storageType": "string", - "type": "enum", - "values": [ - "Enum0_1", - "Enum0_2", - "Enum0_3" - ], - "valuesAsFlags": false - }, - { - "id": 5, - "name": "Enum1Num", - "storageType": "int", - "type": "enum", - "values": [ - "Enum1Num_1", - "Enum1Num_2", - "Enum1Num_3", - "Enum1Num_4" - ], - "valuesAsFlags": false - }, - { - "id": 6, - "name": "Enum2StringFlags", - "storageType": "string", - "type": "enum", - "values": [ - "Enum2StringFlags_1", - "Enum2StringFlags_2", - "Enum2StringFlags_3", - "Enum2StringFlags_4" - ], - "valuesAsFlags": true - }, - { - "id": 7, - "name": "Enum3NumFlags", - "storageType": "int", - "type": "enum", - "values": [ - "Enum3NumFlags_1", - "Enum3NumFlags_2", - "Enum3NumFlags_3", - "Enum3NumFlags_4", - "Enum3NumFlags_5" - ], - "valuesAsFlags": true - }, - { - "color": "#ffa0a0a4", - "drawFill": true, - "id": 2, - "members": [ - { - "name": "Yep", - "propertyType": "TestClass", - "type": "class", - "value": { - } - } - ], - "name": "Test", - "type": "class", - "useAs": [ - "property", - "map", - "layer", - "object", - "tile", - "tileset", - "wangcolor", - "wangset", - "project" - ] - }, - { - "color": "#ffa0a0a4", - "drawFill": true, - "id": 1, - "members": [ - { - "name": "Amount", - "type": "float", - "value": 0 - }, - { - "name": "Name", - "type": "string", - "value": "" - } - ], - "name": "TestClass", - "type": "class", - "useAs": [ - "property" - ] - } -] diff --git a/DotTiled.Tests/Serialization/TestData/CustomTypes/map-with-object-template-propertytypes.json b/DotTiled.Tests/Serialization/TestData/CustomTypes/map-with-object-template-propertytypes.json deleted file mode 100644 index 3505dce..0000000 --- a/DotTiled.Tests/Serialization/TestData/CustomTypes/map-with-object-template-propertytypes.json +++ /dev/null @@ -1,24 +0,0 @@ -[ - { - "color": "#ffa0a0a4", - "drawFill": true, - "id": 1, - "members": [ - { - "name": "Amount", - "type": "float", - "value": 0 - }, - { - "name": "Name", - "type": "string", - "value": "" - } - ], - "name": "TestClass", - "type": "class", - "useAs": [ - "property" - ] - } -] diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs new file mode 100644 index 0000000..10c4d67 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs @@ -0,0 +1,79 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithExternalTileset(string fileExt) => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Tilesets = [ + new Tileset + { + Version = "1.10", + TiledVersion = "1.11.0", + FirstGID = 1, + Name = "tileset", + TileWidth = 32, + TileHeight = 32, + TileCount = 24, + Columns = 8, + Source = $"tileset.{(fileExt == "tmx" ? "tsx" : "tsj")}", + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96, + } + } + ], + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 1, 1, 0, 0, 7, + 1, 1, 0, 0, 7, + 0, 0, 1, 0, 7, + 0, 0, 0, 1, 7, + 21, 21, 21, 21, 1 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj new file mode 100644 index 0000000..89bef93 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj @@ -0,0 +1,36 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[1, 1, 0, 0, 7, + 1, 1, 0, 0, 7, + 0, 0, 1, 0, 7, + 0, 0, 0, 1, 7, + 21, 21, 21, 21, 1], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx new file mode 100644 index 0000000..06114fb --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx @@ -0,0 +1,13 @@ + + + + + +1,1,0,0,7, +1,1,0,0,7, +0,0,1,0,7, +0,0,0,1,7, +21,21,21,21,1 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1fb31b1fa4dcf1214b8fe9b2e2b8e287c72d0 GIT binary patch literal 11908 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 Pn-8F-q^(#jZyEZ3BaoJ| literal 0 HcmV?d00001 diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsj b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsj new file mode 100644 index 0000000..820e88f --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsj @@ -0,0 +1,14 @@ +{ "columns":8, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":24, + "tiledversion":"1.11.0", + "tileheight":32, + "tilewidth":32, + "type":"tileset", + "version":"1.10" +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsx b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsx new file mode 100644 index 0000000..d730182 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs index 71e5304..670fdf6 100644 --- a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs @@ -7,21 +7,22 @@ public partial class TmjMapReaderTests [MemberData(nameof(Maps))] public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( string testDataFile, - Map expectedMap, + Func expectedMap, IReadOnlyCollection customTypeDefinitions) { // Arrange testDataFile += ".tmj"; + var fileDir = Path.GetDirectoryName(testDataFile); var json = TestData.GetRawStringFor(testDataFile); Template ResolveTemplate(string source) { - var templateJson = TestData.GetRawStringFor($"Serialization.TestData.Template.{source}"); + var templateJson = TestData.GetRawStringFor($"{fileDir}/{source}"); using var templateReader = new TjTemplateReader(templateJson, ResolveTileset, ResolveTemplate, customTypeDefinitions); return templateReader.ReadTemplate(); } Tileset ResolveTileset(string source) { - var tilesetJson = TestData.GetRawStringFor($"Serialization.TestData.Tileset.{source}"); + var tilesetJson = TestData.GetRawStringFor($"{fileDir}/{source}"); using var tilesetReader = new TsjTilesetReader(tilesetJson, ResolveTemplate, customTypeDefinitions); return tilesetReader.ReadTileset(); } @@ -32,6 +33,6 @@ public partial class TmjMapReaderTests // Assert Assert.NotNull(map); - DotTiledAssert.AssertMap(expectedMap, map); + DotTiledAssert.AssertMap(expectedMap("tmj"), map); } } diff --git a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs index c0dc083..a99ee9a 100644 --- a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs @@ -9,21 +9,22 @@ public partial class TmxMapReaderTests [MemberData(nameof(Maps))] public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( string testDataFile, - Map expectedMap, + Func expectedMap, IReadOnlyCollection customTypeDefinitions) { // Arrange testDataFile += ".tmx"; + var fileDir = Path.GetDirectoryName(testDataFile); using var reader = TestData.GetXmlReaderFor(testDataFile); Template ResolveTemplate(string source) { - using var xmlTemplateReader = TestData.GetXmlReaderFor($"Serialization.TestData.Template.{source}"); + using var xmlTemplateReader = TestData.GetXmlReaderFor($"{fileDir}/{source}"); using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate, customTypeDefinitions); return templateReader.ReadTemplate(); } Tileset ResolveTileset(string source) { - using var xmlTilesetReader = TestData.GetXmlReaderFor($"Serialization.TestData.Tileset.{source}"); + using var xmlTilesetReader = TestData.GetXmlReaderFor($"{fileDir}/{source}"); using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate, customTypeDefinitions); return tilesetReader.ReadTileset(); } @@ -34,6 +35,6 @@ public partial class TmxMapReaderTests // Assert Assert.NotNull(map); - DotTiledAssert.AssertMap(expectedMap, map); + DotTiledAssert.AssertMap(expectedMap("tmx"), map); } } diff --git a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs index 3885dac..9f576bb 100644 --- a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs +++ b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs @@ -83,7 +83,7 @@ internal partial class Tmx var resolvedTileset = externalTilesetResolver(source); resolvedTileset.FirstGID = firstGID; - resolvedTileset.Source = null; + resolvedTileset.Source = source; return resolvedTileset; } From e68f7c178a0018837df72e1d04179e4a525c1d4c Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Mon, 12 Aug 2024 23:20:47 +0200 Subject: [PATCH 08/12] Add tests for map with rotated/flipped tiles --- DotTiled.Tests/Serialization/TestData.cs | 1 + .../map-with-flippingflags.cs | 79 ++++++++++++++++++ .../map-with-flippingflags.tmj | 36 ++++++++ .../map-with-flippingflags.tmx | 13 +++ .../Map/map-with-flippingflags/tileset.png | Bin 0 -> 11908 bytes .../Map/map-with-flippingflags/tileset.tsj | 14 ++++ .../Map/map-with-flippingflags/tileset.tsx | 4 + 7 files changed, 147 insertions(+) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.png create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsx diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 254cba7..98a59be 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -36,6 +36,7 @@ public static partial class TestData ["Serialization/TestData/Map/map_with_custom_type_props/map-with-custom-type-props", (string f) => TestData.MapWithCustomTypeProps(), TestData.MapWithCustomTypePropsCustomTypeDefinitions()], ["Serialization/TestData/Map/map_with_embedded_tileset/map-with-embedded-tileset", (string f) => TestData.MapWithEmbeddedTileset(), Array.Empty()], ["Serialization/TestData/Map/map_with_external_tileset/map-with-external-tileset", (string f) => TestData.MapWithExternalTileset(f), Array.Empty()], + ["Serialization/TestData/Map/map_with_flippingflags/map-with-flippingflags", (string f) => TestData.MapWithFlippingFlags(f), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.cs new file mode 100644 index 0000000..4e181c4 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.cs @@ -0,0 +1,79 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithFlippingFlags(string fileExt) => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Tilesets = [ + new Tileset + { + Version = "1.10", + TiledVersion = "1.11.0", + FirstGID = 1, + Name = "tileset", + TileWidth = 32, + TileHeight = 32, + TileCount = 24, + Columns = 8, + Source = $"tileset.{(fileExt == "tmx" ? "tsx" : "tsj")}", + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96, + } + } + ], + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 1, 1, 0, 0, 7, + 1, 1, 0, 0, 7, + 0, 0, 1, 0, 7, + 0, 0, 0, 1, 7, + 21, 21, 21, 21, 1 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.FlippedDiagonally | FlippingFlags.FlippedHorizontally, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically, + FlippingFlags.FlippedDiagonally | FlippingFlags.FlippedVertically, FlippingFlags.FlippedVertically | FlippingFlags.FlippedHorizontally, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically, + FlippingFlags.FlippedHorizontally, FlippingFlags.FlippedHorizontally, FlippingFlags.FlippedHorizontally, FlippingFlags.FlippedHorizontally, FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj new file mode 100644 index 0000000..3b74128 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj @@ -0,0 +1,36 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[1, 2684354561, 0, 0, 1073741831, + 1610612737, 3221225473, 0, 0, 1073741831, + 0, 0, 1, 0, 1073741831, + 0, 0, 0, 1, 1073741831, + 2147483669, 2147483669, 2147483669, 2147483669, 1], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx new file mode 100644 index 0000000..a72cd1a --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx @@ -0,0 +1,13 @@ + + + + + +1,2684354561,0,0,1073741831, +1610612737,3221225473,0,0,1073741831, +0,0,1,0,1073741831, +0,0,0,1,1073741831, +2147483669,2147483669,2147483669,2147483669,1 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1fb31b1fa4dcf1214b8fe9b2e2b8e287c72d0 GIT binary patch literal 11908 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 Pn-8F-q^(#jZyEZ3BaoJ| literal 0 HcmV?d00001 diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsj b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsj new file mode 100644 index 0000000..820e88f --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsj @@ -0,0 +1,14 @@ +{ "columns":8, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":24, + "tiledversion":"1.11.0", + "tileheight":32, + "tilewidth":32, + "type":"tileset", + "version":"1.10" +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsx b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsx new file mode 100644 index 0000000..d730182 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.tsx @@ -0,0 +1,4 @@ + + + + From 3645f8c2a29f21c77f4602cedc44564a1728b0d8 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Tue, 13 Aug 2024 21:39:08 +0200 Subject: [PATCH 09/12] Add some tileset tests --- DotTiled.Tests/Serialization/TestData.cs | 1 + .../map-external-tileset-multi.cs | 121 ++++++++++++++++++ .../map-external-tileset-multi.tmj | 36 ++++++ .../map-external-tileset-multi.tmx | 13 ++ .../multi-tileset.tsj | 71 ++++++++++ .../multi-tileset.tsx | 20 +++ .../map-external-tileset-multi/tileset.png | Bin 0 -> 11908 bytes DotTiled/Serialization/Tmj/Tmj.Tileset.cs | 8 +- 8 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/tileset.png diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 98a59be..005bc82 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -37,6 +37,7 @@ public static partial class TestData ["Serialization/TestData/Map/map_with_embedded_tileset/map-with-embedded-tileset", (string f) => TestData.MapWithEmbeddedTileset(), Array.Empty()], ["Serialization/TestData/Map/map_with_external_tileset/map-with-external-tileset", (string f) => TestData.MapWithExternalTileset(f), Array.Empty()], ["Serialization/TestData/Map/map_with_flippingflags/map-with-flippingflags", (string f) => TestData.MapWithFlippingFlags(f), Array.Empty()], + ["Serialization/TestData/Map/map_external_tileset_multi/map-external-tileset-multi", (string f) => TestData.MapExternalTilesetMulti(f), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.cs b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.cs new file mode 100644 index 0000000..24651b6 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.cs @@ -0,0 +1,121 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapExternalTilesetMulti(string fileExt) => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Tilesets = [ + new Tileset + { + TileOffset = new TileOffset + { + X = 1, + Y = 5 + }, + Version = "1.10", + TiledVersion = "1.11.0", + FirstGID = 1, + Name = "multi-tileset", + TileWidth = 256, + TileHeight = 96, + TileCount = 2, + Columns = 0, + Source = $"multi-tileset.{(fileExt == "tmx" ? "tsx" : "tsj")}", + Grid = new Grid + { + Orientation = GridOrientation.Orthogonal, + Width = 1, + Height = 1 + }, + Properties = new Dictionary + { + ["tilesetbool"] = new BoolProperty { Name = "tilesetbool", Value = true }, + ["tilesetcolor"] = new ColorProperty { Name = "tilesetcolor", Value = Color.Parse("#ffff0000", CultureInfo.InvariantCulture) }, + ["tilesetfile"] = new FileProperty { Name = "tilesetfile", Value = "" }, + ["tilesetfloat"] = new FloatProperty { Name = "tilesetfloat", Value = 5.2f }, + ["tilesetint"] = new IntProperty { Name = "tilesetint", Value = 9 }, + ["tilesetobject"] = new ObjectProperty { Name = "tilesetobject", Value = 0 }, + ["tilesetstring"] = new StringProperty { Name = "tilesetstring", Value = "hello world!" } + }, + Tiles = [ + new Tile + { + ID = 0, + Width = 256, + Height = 96, + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96 + } + }, + new Tile + { + ID = 1, + Width = 256, + Height = 96, + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96 + } + } + ] + } + ], + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj new file mode 100644 index 0000000..da37182 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj @@ -0,0 +1,36 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "source":"multi-tileset.tsj" + }], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx new file mode 100644 index 0000000..477c112 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx @@ -0,0 +1,13 @@ + + + + + +0,0,0,0,0, +0,0,0,0,0, +1,0,0,0,0, +0,0,0,0,0, +0,2,0,0,0 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsj new file mode 100644 index 0000000..d190934 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsj @@ -0,0 +1,71 @@ +{ "columns":0, + "grid": + { + "height":1, + "orientation":"orthogonal", + "width":1 + }, + "margin":0, + "name":"multi-tileset", + "properties":[ + { + "name":"tilesetbool", + "type":"bool", + "value":true + }, + { + "name":"tilesetcolor", + "type":"color", + "value":"#ffff0000" + }, + { + "name":"tilesetfile", + "type":"file", + "value":"" + }, + { + "name":"tilesetfloat", + "type":"float", + "value":5.2 + }, + { + "name":"tilesetint", + "type":"int", + "value":9 + }, + { + "name":"tilesetobject", + "type":"object", + "value":0 + }, + { + "name":"tilesetstring", + "type":"string", + "value":"hello world!" + }], + "spacing":0, + "tilecount":2, + "tiledversion":"1.11.0", + "tileheight":96, + "tileoffset": + { + "x":1, + "y":5 + }, + "tiles":[ + { + "id":0, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256 + }, + { + "id":1, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256 + }], + "tilewidth":256, + "type":"tileset", + "version":"1.10" +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsx new file mode 100644 index 0000000..a28bfac --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/multi-tileset.tsx @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1fb31b1fa4dcf1214b8fe9b2e2b8e287c72d0 GIT binary patch literal 11908 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 Pn-8F-q^(#jZyEZ3BaoJ| literal 0 HcmV?d00001 diff --git a/DotTiled/Serialization/Tmj/Tmj.Tileset.cs b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs index fd5088b..6eefdb7 100644 --- a/DotTiled/Serialization/Tmj/Tmj.Tileset.cs +++ b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs @@ -77,14 +77,14 @@ internal partial class Tmj return resolvedTileset; } - var imageModel = new Image + var imageModel = image is not null ? new Image { - Format = Helpers.ParseImageFormatFromSource(image!), + Format = Helpers.ParseImageFormatFromSource(image), Source = image, Height = imageHeight, Width = imageWidth, TransparentColor = transparentColor - }; + } : null; return new Tileset { @@ -159,7 +159,7 @@ internal partial class Tmj var width = e.GetOptionalProperty("width", imageWidth ?? 0); var height = e.GetOptionalProperty("height", imageHeight ?? 0); var objectGroup = e.GetOptionalPropertyCustom("objectgroup", e => ReadObjectLayer(e, externalTemplateResolver, customTypeDefinitions), null); - var probability = e.GetOptionalProperty("probability", 1.0f); + var probability = e.GetOptionalProperty("probability", 0.0f); var properties = e.GetOptionalPropertyCustom?>("properties", el => ReadProperties(el, customTypeDefinitions), null); // var terrain, replaced by wangsets var type = e.GetOptionalProperty("type", ""); From 292dc9b1b9e101b5bc59fd7d73c783a4b3aa3a40 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Tue, 13 Aug 2024 22:34:51 +0200 Subject: [PATCH 10/12] Add wangset test --- DotTiled.Tests/Serialization/TestData.cs | 1 + .../map-external-tileset-wangset.cs | 92 ++++++++++++++++++ .../map-external-tileset-wangset.tmj | 36 +++++++ .../map-external-tileset-wangset.tmx | 13 +++ .../map-external-tileset-wangset/tileset.png | Bin 0 -> 11908 bytes .../wangset-tileset.tsj | 69 +++++++++++++ .../wangset-tileset.tsx | 17 ++++ DotTiled/Model/Tileset/WangColor.cs | 2 +- DotTiled/Model/Tileset/Wangset.cs | 2 +- DotTiled/Serialization/Tmj/Tmj.Tileset.cs | 26 ++++- DotTiled/Serialization/Tmx/Tmx.Tileset.cs | 14 +-- 11 files changed, 260 insertions(+), 12 deletions(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index 005bc82..d2d3316 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -38,6 +38,7 @@ public static partial class TestData ["Serialization/TestData/Map/map_with_external_tileset/map-with-external-tileset", (string f) => TestData.MapWithExternalTileset(f), Array.Empty()], ["Serialization/TestData/Map/map_with_flippingflags/map-with-flippingflags", (string f) => TestData.MapWithFlippingFlags(f), Array.Empty()], ["Serialization/TestData/Map/map_external_tileset_multi/map-external-tileset-multi", (string f) => TestData.MapExternalTilesetMulti(f), Array.Empty()], + ["Serialization/TestData/Map/map_external_tileset_wangset/map-external-tileset-wangset", (string f) => TestData.MapExternalTilesetWangset(f), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs new file mode 100644 index 0000000..9aaa7d7 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.cs @@ -0,0 +1,92 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapExternalTilesetWangset(string fileExt) => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 24, + TileHeight = 24, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Tilesets = [ + new Tileset + { + Version = "1.10", + TiledVersion = "1.11.0", + FirstGID = 1, + Name = "tileset", + TileWidth = 24, + TileHeight = 24, + TileCount = 48, + Columns = 10, + Source = $"wangset-tileset.{(fileExt == "tmx" ? "tsx" : "tsj")}", + Transformations = new Transformations + { + HFlip = true, + VFlip = true, + Rotate = false, + PreferUntransformed = false + }, + Grid = new Grid + { + Orientation = GridOrientation.Orthogonal, + Width = 32, + Height = 32 + }, + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96, + } + } + ], + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 2, 2, 12, 11, 0, + 1, 12, 1, 11, 0, + 2, 1, 0, 1, 0, + 12, 11, 12, 2, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.FlippedHorizontally, FlippingFlags.None, FlippingFlags.FlippedHorizontally, FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.FlippedVertically, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically | FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedVertically | FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.FlippedHorizontally, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj new file mode 100644 index 0000000..cea9ad6 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmj @@ -0,0 +1,36 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[2147483650, 2, 2147483660, 2147483659, 0, + 1073741825, 12, 1, 3221225483, 0, + 2, 1, 0, 3221225473, 0, + 12, 11, 12, 2147483650, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":24, + "tilesets":[ + { + "firstgid":1, + "source":"wangset-tileset.tsj" + }], + "tilewidth":24, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx new file mode 100644 index 0000000..656fddb --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/map-external-tileset-wangset.tmx @@ -0,0 +1,13 @@ + + + + + +2147483650,2,2147483660,2147483659,0, +1073741825,12,1,3221225483,0, +2,1,0,3221225473,0, +12,11,12,2147483650,0, +0,0,0,0,0 + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1fb31b1fa4dcf1214b8fe9b2e2b8e287c72d0 GIT binary patch literal 11908 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 Pn-8F-q^(#jZyEZ3BaoJ| literal 0 HcmV?d00001 diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj new file mode 100644 index 0000000..511641a --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsj @@ -0,0 +1,69 @@ +{ "columns":10, + "grid": + { + "height":32, + "orientation":"orthogonal", + "width":32 + }, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":48, + "tiledversion":"1.11.0", + "tileheight":24, + "tilewidth":24, + "transformations": + { + "hflip":true, + "preferuntransformed":false, + "rotate":false, + "vflip":true + }, + "type":"tileset", + "version":"1.10", + "wangsets":[ + { + "colors":[ + { + "color":"#ff0000", + "name":"Water", + "probability":1, + "tile":0 + }, + { + "color":"#00ff00", + "name":"Grass", + "probability":1, + "tile":-1 + }, + { + "color":"#0000ff", + "name":"Stone", + "probability":1, + "tile":29 + }], + "name":"test-terrain", + "tile":-1, + "type":"mixed", + "wangtiles":[ + { + "tileid":0, + "wangid":[1, 1, 0, 0, 0, 1, 1, 1] + }, + { + "tileid":1, + "wangid":[1, 1, 1, 1, 0, 0, 0, 1] + }, + { + "tileid":10, + "wangid":[0, 0, 0, 1, 1, 1, 1, 1] + }, + { + "tileid":11, + "wangid":[0, 1, 1, 1, 1, 1, 0, 0] + }] + }] +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx new file mode 100644 index 0000000..d2b8666 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/wangset-tileset.tsx @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/DotTiled/Model/Tileset/WangColor.cs b/DotTiled/Model/Tileset/WangColor.cs index e278bb9..9ac751c 100644 --- a/DotTiled/Model/Tileset/WangColor.cs +++ b/DotTiled/Model/Tileset/WangColor.cs @@ -8,7 +8,7 @@ public class WangColor public required string Name { get; set; } public string Class { get; set; } = ""; public required Color Color { get; set; } - public required uint Tile { get; set; } + public required int Tile { get; set; } public float Probability { get; set; } = 0f; // Elements diff --git a/DotTiled/Model/Tileset/Wangset.cs b/DotTiled/Model/Tileset/Wangset.cs index 8d4d1a5..61f8496 100644 --- a/DotTiled/Model/Tileset/Wangset.cs +++ b/DotTiled/Model/Tileset/Wangset.cs @@ -7,7 +7,7 @@ public class Wangset // Attributes public required string Name { get; set; } public string Class { get; set; } = ""; - public required uint Tile { get; set; } + public required int Tile { get; set; } // Elements // At most one of diff --git a/DotTiled/Serialization/Tmj/Tmj.Tileset.cs b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs index 6eefdb7..d455b42 100644 --- a/DotTiled/Serialization/Tmj/Tmj.Tileset.cs +++ b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs @@ -64,7 +64,8 @@ internal partial class Tmj var transparentColor = element.GetOptionalPropertyParseable("transparentcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null); var type = element.GetOptionalProperty("type", null); var version = element.GetOptionalProperty("version", null); - //var wangsets = element.GetOptionalPropertyCustom?>("wangsets", ReadWangSets, null); + var transformations = element.GetOptionalPropertyCustom("transformations", ReadTransformations, null); + var wangsets = element.GetOptionalPropertyCustom?>("wangsets", el => el.GetValueAsList(e => ReadWangset(e, customTypeDefinitions)), null); if (source is not null) { @@ -108,7 +109,24 @@ internal partial class Tmj Tiles = tiles, TileWidth = tileWidth, Version = version, - //Wangsets = wangsets + Wangsets = wangsets, + Transformations = transformations + }; + } + + internal static Transformations ReadTransformations(JsonElement element) + { + var hFlip = element.GetOptionalProperty("hflip", false); + var vFlip = element.GetOptionalProperty("vflip", false); + var rotate = element.GetOptionalProperty("rotate", false); + var preferUntransformed = element.GetOptionalProperty("preferuntransformed", false); + + return new Transformations + { + HFlip = hFlip, + VFlip = vFlip, + Rotate = rotate, + PreferUntransformed = preferUntransformed }; } @@ -208,7 +226,7 @@ internal partial class Tmj var colors = element.GetOptionalPropertyCustom>("colors", e => e.GetValueAsList(el => ReadWangColor(el, customTypeDefinitions)), []); var name = element.GetRequiredProperty("name"); var properties = element.GetOptionalPropertyCustom?>("properties", e => ReadProperties(e, customTypeDefinitions), null); - var tile = element.GetOptionalProperty("tile", 0); + var tile = element.GetOptionalProperty("tile", 0); var type = element.GetOptionalProperty("type", ""); var wangTiles = element.GetOptionalPropertyCustom>("wangtiles", e => e.GetValueAsList(ReadWangTile), []); @@ -232,7 +250,7 @@ internal partial class Tmj var name = element.GetRequiredProperty("name"); var probability = element.GetOptionalProperty("probability", 1.0f); var properties = element.GetOptionalPropertyCustom?>("properties", e => ReadProperties(e, customTypeDefinitions), null); - var tile = element.GetOptionalProperty("tile", 0); + var tile = element.GetOptionalProperty("tile", 0); return new WangColor { diff --git a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs index 9f576bb..1912df2 100644 --- a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs +++ b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs @@ -193,10 +193,10 @@ internal partial class Tmx internal static Transformations ReadTransformations(XmlReader reader) { // Attributes - var hFlip = reader.GetOptionalAttributeParseable("hflip") ?? false; - var vFlip = reader.GetOptionalAttributeParseable("vflip") ?? false; - var rotate = reader.GetOptionalAttributeParseable("rotate") ?? false; - var preferUntransformed = reader.GetOptionalAttributeParseable("preferuntransformed") ?? false; + var hFlip = (reader.GetOptionalAttributeParseable("hflip") ?? 0) == 1; + var vFlip = (reader.GetOptionalAttributeParseable("vflip") ?? 0) == 1; + var rotate = (reader.GetOptionalAttributeParseable("rotate") ?? 0) == 1; + var preferUntransformed = (reader.GetOptionalAttributeParseable("preferuntransformed") ?? 0) == 1; reader.ReadStartElement("transformations"); return new Transformations { HFlip = hFlip, VFlip = vFlip, Rotate = rotate, PreferUntransformed = preferUntransformed }; @@ -266,7 +266,7 @@ internal partial class Tmx // Attributes var name = reader.GetRequiredAttribute("name"); var @class = reader.GetOptionalAttribute("class") ?? ""; - var tile = reader.GetRequiredAttributeParseable("tile"); + var tile = reader.GetRequiredAttributeParseable("tile"); // Elements Dictionary? properties = null; @@ -303,7 +303,7 @@ internal partial class Tmx var name = reader.GetRequiredAttribute("name"); var @class = reader.GetOptionalAttribute("class") ?? ""; var color = reader.GetRequiredAttributeParseable("color"); - var tile = reader.GetRequiredAttributeParseable("tile"); + var tile = reader.GetRequiredAttributeParseable("tile"); var probability = reader.GetOptionalAttributeParseable("probability") ?? 0f; // Elements @@ -339,6 +339,8 @@ internal partial class Tmx return indices; }); + reader.ReadStartElement("wangtile"); + return new WangTile { TileID = tileID, From 653e5b5326d5429252cac4b81120e619ec4f148c Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Tue, 13 Aug 2024 23:18:42 +0200 Subject: [PATCH 11/12] Add final tests --- DotTiled.Tests/Assert/AssertMap.cs | 40 ++++ DotTiled.Tests/Assert/AssertObject.cs | 7 +- DotTiled.Tests/Serialization/TestData.cs | 1 + .../map-with-many-layers.cs | 214 ++++++++++++++++++ .../map-with-many-layers.tmj | 181 +++++++++++++++ .../map-with-many-layers.tmx | 51 +++++ .../Map/map-with-many-layers/tileset.png | Bin 0 -> 11908 bytes .../Map/map-with-many-layers/tileset.tsj | 14 ++ .../Map/map-with-many-layers/tileset.tsx | 4 + DotTiled/Model/Layers/ImageLayer.cs | 4 +- DotTiled/Model/Layers/Objects/Object.cs | 1 - DotTiled/Model/Layers/Objects/TileObject.cs | 6 + DotTiled/Serialization/Tmj/Tmj.ImageLayer.cs | 4 +- DotTiled/Serialization/Tmj/Tmj.ObjectLayer.cs | 26 ++- DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs | 9 +- DotTiled/Serialization/Tmx/Tmx.TileLayer.cs | 4 +- 16 files changed, 549 insertions(+), 17 deletions(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.png create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsx create mode 100644 DotTiled/Model/Layers/Objects/TileObject.cs diff --git a/DotTiled.Tests/Assert/AssertMap.cs b/DotTiled.Tests/Assert/AssertMap.cs index 6596ee8..e9ad8be 100644 --- a/DotTiled.Tests/Assert/AssertMap.cs +++ b/DotTiled.Tests/Assert/AssertMap.cs @@ -1,3 +1,6 @@ +using System.Collections; +using System.Numerics; + namespace DotTiled.Tests; public static partial class DotTiledAssert @@ -10,6 +13,29 @@ public static partial class DotTiledAssert return; } + if (typeof(T) == typeof(float)) + { + var expectedFloat = (float)(object)expected; + var actualFloat = (float)(object)actual!; + + var expecRounded = MathF.Round(expectedFloat, 3); + var actRounded = MathF.Round(actualFloat, 3); + + Assert.True(expecRounded == actRounded, $"Expected {nameof} '{expecRounded}' but got '{actRounded}'"); + return; + } + + if (expected is Vector2) + { + var expectedVector = (Vector2)(object)expected; + var actualVector = (Vector2)(object)actual!; + + AssertEqual(expectedVector.X, actualVector.X, $"{nameof}.X"); + AssertEqual(expectedVector.Y, actualVector.Y, $"{nameof}.Y"); + + return; + } + if (typeof(T).IsArray) { var expectedArray = (Array)(object)expected; @@ -24,6 +50,20 @@ public static partial class DotTiledAssert return; } + if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(List<>)) + { + var expectedList = (IList)(object)expected; + var actualList = (IList)(object)actual!; + + Assert.NotNull(actualList); + AssertEqual(expectedList.Count, actualList.Count, $"{nameof}.Count"); + + for (var i = 0; i < expectedList.Count; i++) + AssertEqual(expectedList[i], actualList[i], $"{nameof}[{i}]"); + + return; + } + Assert.True(expected.Equals(actual), $"Expected {nameof} '{expected}' but got '{actual}'"); } diff --git a/DotTiled.Tests/Assert/AssertObject.cs b/DotTiled.Tests/Assert/AssertObject.cs index c49b6e7..bd303f9 100644 --- a/DotTiled.Tests/Assert/AssertObject.cs +++ b/DotTiled.Tests/Assert/AssertObject.cs @@ -13,7 +13,6 @@ public static partial class DotTiledAssert AssertEqual(expected.Width, actual.Width, nameof(Object.Width)); AssertEqual(expected.Height, actual.Height, nameof(Object.Height)); AssertEqual(expected.Rotation, actual.Rotation, nameof(Object.Rotation)); - AssertEqual(expected.GID, actual.GID, nameof(Object.GID)); AssertEqual(expected.Visible, actual.Visible, nameof(Object.Visible)); AssertEqual(expected.Template, actual.Template, nameof(Object.Template)); @@ -63,4 +62,10 @@ public static partial class DotTiledAssert AssertEqual(expected.Text, actual.Text, nameof(TextObject.Text)); } + + private static void AssertObject(TileObject expected, TileObject actual) + { + // Attributes + AssertEqual(expected.GID, actual.GID, nameof(TileObject.GID)); + } } diff --git a/DotTiled.Tests/Serialization/TestData.cs b/DotTiled.Tests/Serialization/TestData.cs index d2d3316..c3d52f8 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -39,6 +39,7 @@ public static partial class TestData ["Serialization/TestData/Map/map_with_flippingflags/map-with-flippingflags", (string f) => TestData.MapWithFlippingFlags(f), Array.Empty()], ["Serialization/TestData/Map/map_external_tileset_multi/map-external-tileset-multi", (string f) => TestData.MapExternalTilesetMulti(f), Array.Empty()], ["Serialization/TestData/Map/map_external_tileset_wangset/map-external-tileset-wangset", (string f) => TestData.MapExternalTilesetWangset(f), Array.Empty()], + ["Serialization/TestData/Map/map_with_many_layers/map-with-many-layers", (string f) => TestData.MapWithManyLayers(f), Array.Empty()], ]; private static CustomTypeDefinition[] typedefs = [ diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs new file mode 100644 index 0000000..8ef6ce5 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs @@ -0,0 +1,214 @@ +using System.Numerics; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithManyLayers(string fileExt) => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + HexSideLength = null, + StaggerAxis = null, + StaggerIndex = null, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = new Color { R = 0, G = 0, B = 0, A = 0 }, + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 8, + NextObjectID = 7, + Tilesets = [ + new Tileset + { + Version = "1.10", + TiledVersion = "1.11.0", + FirstGID = 1, + Name = "tileset", + TileWidth = 32, + TileHeight = 32, + TileCount = 24, + Columns = 8, + Source = $"tileset.{(fileExt == "tmx" ? "tsx" : "tsj")}", + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = 256, + Height = 96, + } + } + ], + Layers = [ + new Group + { + ID = 2, + Name = "Root", + Layers = [ + new ObjectLayer + { + ID = 3, + Name = "Objects", + Objects = [ + new RectangleObject + { + ID = 1, + Name = "Object 1", + X = 25.6667f, + Y = 28.6667f, + Width = 31.3333f, + Height = 31.3333f + }, + new PointObject + { + ID = 3, + Name = "P1", + X = 117.667f, + Y = 48.6667f + }, + new EllipseObject + { + ID = 4, + Name = "Circle1", + X = 77f, + Y = 72.3333f, + Width = 34.6667f, + Height = 34.6667f + }, + new PolygonObject + { + ID = 5, + Name = "Poly", + X = 20.6667f, + Y = 114.667f, + Points = [ + new Vector2(0, 0), + new Vector2(104,20), + new Vector2(35.6667f, 32.3333f) + ] + }, + new TileObject + { + ID = 6, + Name = "TileObj", + GID = 7, + X = -35, + Y = 110.333f, + Width = 64, + Height = 146 + } + ] + }, + new Group + { + ID = 5, + Name = "Sub", + Layers = [ + new TileLayer + { + ID = 7, + Name = "Tile 3", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + }, + new TileLayer + { + ID = 6, + Name = "Tile 2", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 0, 15, 15, 0, 0, + 0, 15, 15, 0, 0, + 0, 15, 15, 15, 0, + 15, 15, 15, 0, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + }, + new ImageLayer + { + ID = 4, + Name = "ImageLayer", + Image = new Image + { + Format = ImageFormat.Png, + Source = "tileset.png", + Width = fileExt == "tmx" ? 256u : 0, // Currently, json format does not + Height = fileExt == "tmx" ? 96u : 0 // include image dimensions in image layer https://github.com/mapeditor/tiled/issues/4028 + }, + RepeatX = true + }, + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + Chunks = null, + Compression = null, + GlobalTileIDs = [ + 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], + FlippingFlags = [ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ] + } + } + ] + } + ] + }; +} diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj new file mode 100644 index 0000000..16561f4 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj @@ -0,0 +1,181 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "id":2, + "layers":[ + { + "draworder":"topdown", + "id":3, + "name":"Objects", + "objects":[ + { + "height":31.3333333333333, + "id":1, + "name":"Object 1", + "rotation":0, + "type":"", + "visible":true, + "width":31.3333333333333, + "x":25.6666666666667, + "y":28.6666666666667 + }, + { + "height":0, + "id":3, + "name":"P1", + "point":true, + "rotation":0, + "type":"", + "visible":true, + "width":0, + "x":117.666666666667, + "y":48.6666666666667 + }, + { + "ellipse":true, + "height":34.6666666666667, + "id":4, + "name":"Circle1", + "rotation":0, + "type":"", + "visible":true, + "width":34.6666666666667, + "x":77, + "y":72.3333333333333 + }, + { + "height":0, + "id":5, + "name":"Poly", + "polygon":[ + { + "x":0, + "y":0 + }, + { + "x":104, + "y":20 + }, + { + "x":35.6666666666667, + "y":32.3333333333333 + }], + "rotation":0, + "type":"", + "visible":true, + "width":0, + "x":20.6666666666667, + "y":114.666666666667 + }, + { + "gid":7, + "height":146, + "id":6, + "name":"TileObj", + "rotation":0, + "type":"", + "visible":true, + "width":64, + "x":-35, + "y":110.333333333333 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "id":5, + "layers":[ + { + "data":[0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":7, + "name":"Tile 3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }, + { + "data":[0, 15, 15, 0, 0, + 0, 15, 15, 0, 0, + 0, 15, 15, 15, 0, + 15, 15, 15, 0, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":6, + "name":"Tile 2", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "name":"Sub", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }, + { + "id":4, + "image":"tileset.png", + "name":"ImageLayer", + "opacity":1, + "repeatx":true, + "type":"imagelayer", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "name":"Root", + "opacity":1, + "type":"group", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":8, + "nextobjectid":7, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx new file mode 100644 index 0000000..34cd91c --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0 + + + + +0,15,15,0,0, +0,15,15,0,0, +0,15,15,15,0, +15,15,15,0,0, +0,0,0,0,0 + + + + + + + + +1,1,1,1,1, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0 + + + + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.png b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..97c1fb31b1fa4dcf1214b8fe9b2e2b8e287c72d0 GIT binary patch literal 11908 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 Pn-8F-q^(#jZyEZ3BaoJ| literal 0 HcmV?d00001 diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsj b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsj new file mode 100644 index 0000000..820e88f --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsj @@ -0,0 +1,14 @@ +{ "columns":8, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, + "margin":0, + "name":"tileset", + "spacing":0, + "tilecount":24, + "tiledversion":"1.11.0", + "tileheight":32, + "tilewidth":32, + "type":"tileset", + "version":"1.10" +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsx b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsx new file mode 100644 index 0000000..d730182 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.tsx @@ -0,0 +1,4 @@ + + + + diff --git a/DotTiled/Model/Layers/ImageLayer.cs b/DotTiled/Model/Layers/ImageLayer.cs index 6489c22..a140b0d 100644 --- a/DotTiled/Model/Layers/ImageLayer.cs +++ b/DotTiled/Model/Layers/ImageLayer.cs @@ -5,8 +5,8 @@ public class ImageLayer : BaseLayer // Attributes public uint X { get; set; } = 0; public uint Y { get; set; } = 0; - public required bool RepeatX { get; set; } - public required bool RepeatY { get; set; } + public bool RepeatX { get; set; } = false; + public bool RepeatY { get; set; } = false; // At most one of public Image? Image { get; set; } diff --git a/DotTiled/Model/Layers/Objects/Object.cs b/DotTiled/Model/Layers/Objects/Object.cs index b3313d7..765de69 100644 --- a/DotTiled/Model/Layers/Objects/Object.cs +++ b/DotTiled/Model/Layers/Objects/Object.cs @@ -13,7 +13,6 @@ public abstract class Object public float Width { get; set; } = 0f; public float Height { get; set; } = 0f; public float Rotation { get; set; } = 0f; - public uint? GID { get; set; } public bool Visible { get; set; } = true; public string? Template { get; set; } diff --git a/DotTiled/Model/Layers/Objects/TileObject.cs b/DotTiled/Model/Layers/Objects/TileObject.cs new file mode 100644 index 0000000..c066780 --- /dev/null +++ b/DotTiled/Model/Layers/Objects/TileObject.cs @@ -0,0 +1,6 @@ +namespace DotTiled; + +public class TileObject : Object +{ + public uint GID { get; set; } +} diff --git a/DotTiled/Serialization/Tmj/Tmj.ImageLayer.cs b/DotTiled/Serialization/Tmj/Tmj.ImageLayer.cs index d315891..dbd75a1 100644 --- a/DotTiled/Serialization/Tmj/Tmj.ImageLayer.cs +++ b/DotTiled/Serialization/Tmj/Tmj.ImageLayer.cs @@ -25,8 +25,8 @@ internal partial class Tmj var properties = element.GetOptionalPropertyCustom?>("properties", e => ReadProperties(e, customTypeDefinitions), null); var image = element.GetRequiredProperty("image"); - var repeatX = element.GetRequiredProperty("repeatx"); - var repeatY = element.GetRequiredProperty("repeaty"); + var repeatX = element.GetOptionalProperty("repeatx", false); + var repeatY = element.GetOptionalProperty("repeaty", false); var transparentColor = element.GetOptionalPropertyParseable("transparentcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null); var x = element.GetOptionalProperty("x", 0); var y = element.GetOptionalProperty("y", 0); diff --git a/DotTiled/Serialization/Tmj/Tmj.ObjectLayer.cs b/DotTiled/Serialization/Tmj/Tmj.ObjectLayer.cs index 2fdf3c9..564f2db 100644 --- a/DotTiled/Serialization/Tmj/Tmj.ObjectLayer.cs +++ b/DotTiled/Serialization/Tmj/Tmj.ObjectLayer.cs @@ -97,7 +97,6 @@ internal partial class Tmj widthDefault = templObj.Width; heightDefault = templObj.Height; rotationDefault = templObj.Rotation; - gidDefault = templObj.GID; visibleDefault = templObj.Visible; propertiesDefault = templObj.Properties; ellipseDefault = templObj is EllipseObject; @@ -123,6 +122,25 @@ internal partial class Tmj var x = element.GetOptionalProperty("x", xDefault); var y = element.GetOptionalProperty("y", yDefault); + if (gid is not null) + { + return new TileObject + { + ID = id, + Name = name, + Type = type, + X = x, + Y = y, + Width = width, + Height = height, + Rotation = rotation, + Visible = visible, + Template = template, + Properties = properties, + GID = gid.Value + }; + } + if (ellipse) { return new EllipseObject @@ -135,7 +153,6 @@ internal partial class Tmj Width = width, Height = height, Rotation = rotation, - GID = gid, Visible = visible, Template = template, Properties = properties @@ -154,7 +171,6 @@ internal partial class Tmj Width = width, Height = height, Rotation = rotation, - GID = gid, Visible = visible, Template = template, Properties = properties @@ -173,7 +189,6 @@ internal partial class Tmj Width = width, Height = height, Rotation = rotation, - GID = gid, Visible = visible, Template = template, Properties = properties, @@ -193,7 +208,6 @@ internal partial class Tmj Width = width, Height = height, Rotation = rotation, - GID = gid, Visible = visible, Template = template, Properties = properties, @@ -211,7 +225,6 @@ internal partial class Tmj text.Width = width; text.Height = height; text.Rotation = rotation; - text.GID = gid; text.Visible = visible; text.Template = template; text.Properties = properties; @@ -228,7 +241,6 @@ internal partial class Tmj Width = width, Height = height, Rotation = rotation, - GID = gid, Visible = visible, Template = template, Properties = properties diff --git a/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs b/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs index 2367974..fa80805 100644 --- a/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs +++ b/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs @@ -105,7 +105,6 @@ internal partial class Tmx widthDefault = templObj.Width; heightDefault = templObj.Height; rotationDefault = templObj.Rotation; - gidDefault = templObj.GID; visibleDefault = templObj.Visible; propertiesDefault = templObj.Properties; } @@ -137,12 +136,19 @@ internal partial class Tmx _ => throw new Exception($"Unknown object marker '{elementName}'") }); + if (gid is not null) + { + obj = new TileObject { ID = id, GID = gid.Value }; + reader.Skip(); + } + if (obj is null) { obj = new RectangleObject { ID = id }; reader.Skip(); } + obj.ID = id; obj.Name = name; obj.Type = type; obj.X = x; @@ -150,7 +156,6 @@ internal partial class Tmx obj.Width = width; obj.Height = height; obj.Rotation = rotation; - obj.GID = gid; obj.Visible = visible; obj.Template = template; obj.Properties = properties; diff --git a/DotTiled/Serialization/Tmx/Tmx.TileLayer.cs b/DotTiled/Serialization/Tmx/Tmx.TileLayer.cs index 78096e3..6fc64fb 100644 --- a/DotTiled/Serialization/Tmx/Tmx.TileLayer.cs +++ b/DotTiled/Serialization/Tmx/Tmx.TileLayer.cs @@ -74,8 +74,8 @@ internal partial class Tmx var offsetY = reader.GetOptionalAttributeParseable("offsety") ?? 0.0f; var parallaxX = reader.GetOptionalAttributeParseable("parallaxx") ?? 1.0f; var parallaxY = reader.GetOptionalAttributeParseable("parallaxy") ?? 1.0f; - var repeatX = reader.GetRequiredAttributeParseable("repeatx"); - var repeatY = reader.GetRequiredAttributeParseable("repeaty"); + var repeatX = (reader.GetOptionalAttributeParseable("repeatx") ?? 0) == 1; + var repeatY = (reader.GetOptionalAttributeParseable("repeaty") ?? 0) == 1; Dictionary? properties = null; Image? image = null; From aecd97bd7d1f72c4a81454e6739ed35095208614 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Wed, 14 Aug 2024 20:29:55 +0200 Subject: [PATCH 12/12] More tests --- DotTiled.Tests/Assert/AssertObject.cs | 2 + .../map-with-many-layers.cs | 7 +- .../map-with-many-layers.tmj | 44 ++---- .../map-with-many-layers.tmx | 4 +- .../TestData/Map/map-with-many-layers/poly.tj | 31 ++++ .../TestData/Map/map-with-many-layers/poly.tx | 9 ++ DotTiled/Serialization/Helpers.cs | 2 +- DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs | 148 ++++++++++++------ 8 files changed, 159 insertions(+), 88 deletions(-) create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tj create mode 100644 DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tx diff --git a/DotTiled.Tests/Assert/AssertObject.cs b/DotTiled.Tests/Assert/AssertObject.cs index bd303f9..6c586bb 100644 --- a/DotTiled.Tests/Assert/AssertObject.cs +++ b/DotTiled.Tests/Assert/AssertObject.cs @@ -17,6 +17,8 @@ public static partial class DotTiledAssert AssertEqual(expected.Template, actual.Template, nameof(Object.Template)); AssertProperties(expected.Properties, actual.Properties); + + Assert.True(expected.GetType() == actual.GetType(), $"Expected object type {expected.GetType()} but got {actual.GetType()}"); AssertObject((dynamic)expected, (dynamic)actual); } diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs index 8ef6ce5..2ef98d0 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs @@ -92,7 +92,12 @@ public partial class TestData new Vector2(0, 0), new Vector2(104,20), new Vector2(35.6667f, 32.3333f) - ] + ], + Template = fileExt == "tmx" ? "poly.tx" : "poly.tj", + Properties = new Dictionary + { + ["templateprop"] = new StringProperty { Name = "templateprop", Value = "helo there" } + } }, new TileObject { diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj index 16561f4..9e9f669 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj @@ -11,15 +11,15 @@ "name":"Objects", "objects":[ { - "height":31.3333333333333, + "height":31.3333, "id":1, "name":"Object 1", "rotation":0, "type":"", "visible":true, - "width":31.3333333333333, - "x":25.6666666666667, - "y":28.6666666666667 + "width":31.3333, + "x":25.6667, + "y":28.6667 }, { "height":0, @@ -30,44 +30,26 @@ "type":"", "visible":true, "width":0, - "x":117.666666666667, - "y":48.6666666666667 + "x":117.667, + "y":48.6667 }, { "ellipse":true, - "height":34.6666666666667, + "height":34.6667, "id":4, "name":"Circle1", "rotation":0, "type":"", "visible":true, - "width":34.6666666666667, + "width":34.6667, "x":77, - "y":72.3333333333333 + "y":72.3333 }, { - "height":0, "id":5, - "name":"Poly", - "polygon":[ - { - "x":0, - "y":0 - }, - { - "x":104, - "y":20 - }, - { - "x":35.6666666666667, - "y":32.3333333333333 - }], - "rotation":0, - "type":"", - "visible":true, - "width":0, - "x":20.6666666666667, - "y":114.666666666667 + "template":"poly.tj", + "x":20.6667, + "y":114.667 }, { "gid":7, @@ -79,7 +61,7 @@ "visible":true, "width":64, "x":-35, - "y":110.333333333333 + "y":110.333 }], "opacity":1, "type":"objectgroup", diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx index 34cd91c..5888069 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx @@ -10,9 +10,7 @@ - - - + diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tj b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tj new file mode 100644 index 0000000..f23c7d9 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tj @@ -0,0 +1,31 @@ +{ "object": + { + "height":0, + "id":5, + "name":"Poly", + "polygon":[ + { + "x":0, + "y":0 + }, + { + "x":104, + "y":20 + }, + { + "x":35.6667, + "y":32.3333 + }], + "properties":[ + { + "name":"templateprop", + "type":"string", + "value":"helo there" + }], + "rotation":0, + "type":"", + "visible":true, + "width":0 + }, + "type":"template" +} \ No newline at end of file diff --git a/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tx b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tx new file mode 100644 index 0000000..a0a2457 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/poly.tx @@ -0,0 +1,9 @@ + + diff --git a/DotTiled/Serialization/Helpers.cs b/DotTiled/Serialization/Helpers.cs index 905cb9f..2e36124 100644 --- a/DotTiled/Serialization/Helpers.cs +++ b/DotTiled/Serialization/Helpers.cs @@ -72,7 +72,7 @@ internal static partial class Helpers }; } - internal static Dictionary MergeProperties(Dictionary? baseProperties, Dictionary overrideProperties) + internal static Dictionary MergeProperties(Dictionary? baseProperties, Dictionary? overrideProperties) { if (baseProperties is null) return overrideProperties ?? new Dictionary(); diff --git a/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs b/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs index fa80805..4d70b91 100644 --- a/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs +++ b/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs @@ -78,36 +78,21 @@ internal partial class Tmx { // Attributes var template = reader.GetOptionalAttribute("template"); - - uint? idDefault = null; - string nameDefault = ""; - string typeDefault = ""; - float xDefault = 0f; - float yDefault = 0f; - float widthDefault = 0f; - float heightDefault = 0f; - float rotationDefault = 0f; - uint? gidDefault = null; - bool visibleDefault = true; - Dictionary? propertiesDefault = null; - - // Perform template copy first + Object? obj = null; if (template is not null) - { - var resolvedTemplate = externalTemplateResolver(template); - var templObj = resolvedTemplate.Object; + obj = externalTemplateResolver(template).Object; - idDefault = templObj.ID; - nameDefault = templObj.Name; - typeDefault = templObj.Type; - xDefault = templObj.X; - yDefault = templObj.Y; - widthDefault = templObj.Width; - heightDefault = templObj.Height; - rotationDefault = templObj.Rotation; - visibleDefault = templObj.Visible; - propertiesDefault = templObj.Properties; - } + uint? idDefault = obj?.ID ?? null; + string nameDefault = obj?.Name ?? ""; + string typeDefault = obj?.Type ?? ""; + float xDefault = obj?.X ?? 0f; + float yDefault = obj?.Y ?? 0f; + float widthDefault = obj?.Width ?? 0f; + float heightDefault = obj?.Height ?? 0f; + float rotationDefault = obj?.Rotation ?? 0f; + uint? gidDefault = obj is TileObject tileObj ? tileObj.GID : null; + bool visibleDefault = obj?.Visible ?? true; + Dictionary? propertiesDefault = obj?.Properties ?? null; var id = reader.GetOptionalAttributeParseable("id") ?? idDefault; var name = reader.GetOptionalAttribute("name") ?? nameDefault; @@ -121,46 +106,66 @@ internal partial class Tmx var visible = reader.GetOptionalAttributeParseable("visible") ?? visibleDefault; // Elements - Object? obj = null; + Object? foundObject = null; int propertiesCounter = 0; Dictionary? properties = propertiesDefault; reader.ProcessChildren("object", (r, elementName) => elementName switch { "properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, Helpers.MergeProperties(properties, ReadProperties(r, customTypeDefinitions)), "Properties", ref propertiesCounter), - "ellipse" => () => Helpers.SetAtMostOnce(ref obj, ReadEllipseObject(r), "Object marker"), - "point" => () => Helpers.SetAtMostOnce(ref obj, ReadPointObject(r), "Object marker"), - "polygon" => () => Helpers.SetAtMostOnce(ref obj, ReadPolygonObject(r), "Object marker"), - "polyline" => () => Helpers.SetAtMostOnce(ref obj, ReadPolylineObject(r), "Object marker"), - "text" => () => Helpers.SetAtMostOnce(ref obj, ReadTextObject(r), "Object marker"), + "ellipse" => () => Helpers.SetAtMostOnce(ref foundObject, ReadEllipseObject(r), "Object marker"), + "point" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPointObject(r), "Object marker"), + "polygon" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPolygonObject(r), "Object marker"), + "polyline" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPolylineObject(r), "Object marker"), + "text" => () => Helpers.SetAtMostOnce(ref foundObject, ReadTextObject(r), "Object marker"), _ => throw new Exception($"Unknown object marker '{elementName}'") }); - if (gid is not null) + if (foundObject is null) { - obj = new TileObject { ID = id, GID = gid.Value }; - reader.Skip(); + if (gid is not null) + foundObject = new TileObject { ID = id, GID = gid.Value }; + else + foundObject = new RectangleObject { ID = id }; } + foundObject.ID = id; + foundObject.Name = name; + foundObject.Type = type; + foundObject.X = x; + foundObject.Y = y; + foundObject.Width = width; + foundObject.Height = height; + foundObject.Rotation = rotation; + foundObject.Visible = visible; + foundObject.Properties = properties; + foundObject.Template = template; + + return OverrideObject(obj, foundObject); + } + + internal static Object OverrideObject(Object? obj, Object foundObject) + { if (obj is null) + return foundObject; + + if (obj.GetType() != foundObject.GetType()) { - obj = new RectangleObject { ID = id }; - reader.Skip(); + obj.ID = foundObject.ID; + obj.Name = foundObject.Name; + obj.Type = foundObject.Type; + obj.X = foundObject.X; + obj.Y = foundObject.Y; + obj.Width = foundObject.Width; + obj.Height = foundObject.Height; + obj.Rotation = foundObject.Rotation; + obj.Visible = foundObject.Visible; + obj.Properties = Helpers.MergeProperties(obj.Properties, foundObject.Properties); + obj.Template = foundObject.Template; + return obj; } - obj.ID = id; - obj.Name = name; - obj.Type = type; - obj.X = x; - obj.Y = y; - obj.Width = width; - obj.Height = height; - obj.Rotation = rotation; - obj.Visible = visible; - obj.Template = template; - obj.Properties = properties; - - return obj; + return OverrideObject((dynamic)obj, (dynamic)foundObject); } internal static EllipseObject ReadEllipseObject(XmlReader reader) @@ -169,12 +174,16 @@ internal partial class Tmx return new EllipseObject { }; } + internal static EllipseObject OverrideObject(EllipseObject obj, EllipseObject foundObject) => obj; + internal static PointObject ReadPointObject(XmlReader reader) { reader.Skip(); return new PointObject { }; } + internal static PointObject OverrideObject(PointObject obj, PointObject foundObject) => obj; + internal static PolygonObject ReadPolygonObject(XmlReader reader) { // Attributes @@ -193,6 +202,12 @@ internal partial class Tmx return new PolygonObject { Points = points }; } + internal static PolygonObject OverrideObject(PolygonObject obj, PolygonObject foundObject) + { + obj.Points = foundObject.Points; + return obj; + } + internal static PolylineObject ReadPolylineObject(XmlReader reader) { // Attributes @@ -211,6 +226,12 @@ internal partial class Tmx return new PolylineObject { Points = points }; } + internal static PolylineObject OverrideObject(PolylineObject obj, PolylineObject foundObject) + { + obj.Points = foundObject.Points; + return obj; + } + internal static TextObject ReadTextObject(XmlReader reader) { // Attributes @@ -259,6 +280,29 @@ internal partial class Tmx }; } + internal static TextObject OverrideObject(TextObject obj, TextObject foundObject) + { + obj.FontFamily = foundObject.FontFamily; + obj.PixelSize = foundObject.PixelSize; + obj.Wrap = foundObject.Wrap; + obj.Color = foundObject.Color; + obj.Bold = foundObject.Bold; + obj.Italic = foundObject.Italic; + obj.Underline = foundObject.Underline; + obj.Strikeout = foundObject.Strikeout; + obj.Kerning = foundObject.Kerning; + obj.HorizontalAlignment = foundObject.HorizontalAlignment; + obj.VerticalAlignment = foundObject.VerticalAlignment; + obj.Text = foundObject.Text; + return obj; + } + + internal static TileObject OverrideObject(TileObject obj, TileObject foundObject) + { + obj.GID = foundObject.GID; + return obj; + } + internal static Template ReadTemplate( XmlReader reader, Func externalTilesetResolver,