diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.DataTests.cs b/DotTiled.Tests/Assert/AssertData.cs similarity index 80% rename from DotTiled.Tests/TmxSerializer/TmxSerializer.DataTests.cs rename to DotTiled.Tests/Assert/AssertData.cs index e08d402..d4b54f0 100644 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.DataTests.cs +++ b/DotTiled.Tests/Assert/AssertData.cs @@ -1,8 +1,8 @@ namespace DotTiled.Tests; -public partial class TmxSerializerDataTests +public static partial class DotTiledAssert { - public static void AssertData(Data? actual, Data? expected) + internal static void AssertData(Data? expected, Data? actual) { if (expected is null) { @@ -24,11 +24,11 @@ public partial class TmxSerializerDataTests Assert.NotNull(actual.Chunks); Assert.Equal(expected.Chunks.Length, actual.Chunks.Length); for (var i = 0; i < expected.Chunks.Length; i++) - AssertChunk(actual.Chunks[i], expected.Chunks[i]); + AssertChunk(expected.Chunks[i], actual.Chunks[i]); } } - private static void AssertChunk(Chunk actual, Chunk expected) + private static void AssertChunk(Chunk expected, Chunk actual) { // Attributes Assert.Equal(expected.X, actual.X); diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.ImageTests.cs b/DotTiled.Tests/Assert/AssertImage.cs similarity index 79% rename from DotTiled.Tests/TmxSerializer/TmxSerializer.ImageTests.cs rename to DotTiled.Tests/Assert/AssertImage.cs index 7d00713..9943c46 100644 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.ImageTests.cs +++ b/DotTiled.Tests/Assert/AssertImage.cs @@ -1,8 +1,8 @@ namespace DotTiled.Tests; -public partial class TmxSerializerImageTests +public static partial class DotTiledAssert { - public static void AssertImage(Image? actual, Image? expected) + internal static void AssertImage(Image? expected, Image? actual) { if (expected is null) { diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.LayerTests.cs b/DotTiled.Tests/Assert/AssertLayer.cs similarity index 66% rename from DotTiled.Tests/TmxSerializer/TmxSerializer.LayerTests.cs rename to DotTiled.Tests/Assert/AssertLayer.cs index c3289a4..57df04d 100644 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.LayerTests.cs +++ b/DotTiled.Tests/Assert/AssertLayer.cs @@ -1,8 +1,8 @@ namespace DotTiled.Tests; -public partial class TmxSerializerLayerTests +public static partial class DotTiledAssert { - public static void AssertLayer(BaseLayer? actual, BaseLayer? expected) + internal static void AssertLayer(BaseLayer? expected, BaseLayer? actual) { if (expected is null) { @@ -23,11 +23,11 @@ public partial class TmxSerializerLayerTests Assert.Equal(expected.ParallaxX, actual.ParallaxX); Assert.Equal(expected.ParallaxY, actual.ParallaxY); - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); - AssertLayer((dynamic)actual, (dynamic)expected); + AssertProperties(expected.Properties, actual.Properties); + AssertLayer((dynamic)expected, (dynamic)actual); } - private static void AssertLayer(TileLayer actual, TileLayer expected) + private static void AssertLayer(TileLayer expected, TileLayer actual) { // Attributes Assert.Equal(expected.Width, actual.Width); @@ -36,10 +36,10 @@ public partial class TmxSerializerLayerTests Assert.Equal(expected.Y, actual.Y); Assert.NotNull(actual.Data); - TmxSerializerDataTests.AssertData(actual.Data, expected.Data); + AssertData(expected.Data, actual.Data); } - private static void AssertLayer(ObjectLayer actual, ObjectLayer expected) + private static void AssertLayer(ObjectLayer expected, ObjectLayer actual) { // Attributes Assert.Equal(expected.DrawOrder, actual.DrawOrder); @@ -49,10 +49,10 @@ public partial class TmxSerializerLayerTests Assert.NotNull(actual.Objects); Assert.Equal(expected.Objects.Count, actual.Objects.Count); for (var i = 0; i < expected.Objects.Count; i++) - TmxSerializerObjectTests.AssertObject(actual.Objects[i], expected.Objects[i]); + AssertObject(expected.Objects[i], actual.Objects[i]); } - private static void AssertLayer(ImageLayer actual, ImageLayer expected) + private static void AssertLayer(ImageLayer expected, ImageLayer actual) { // Attributes Assert.Equal(expected.RepeatX, actual.RepeatX); @@ -61,15 +61,15 @@ public partial class TmxSerializerLayerTests Assert.Equal(expected.Y, actual.Y); Assert.NotNull(actual.Image); - TmxSerializerImageTests.AssertImage(actual.Image, expected.Image); + AssertImage(expected.Image, actual.Image); } - private static void AssertLayer(Group actual, Group expected) + private static void AssertLayer(Group expected, Group actual) { // Attributes Assert.NotNull(actual.Layers); Assert.Equal(expected.Layers.Count, actual.Layers.Count); for (var i = 0; i < expected.Layers.Count; i++) - AssertLayer(actual.Layers[i], expected.Layers[i]); + AssertLayer(expected.Layers[i], actual.Layers[i]); } } diff --git a/DotTiled.Tests/Assert/AssertMap.cs b/DotTiled.Tests/Assert/AssertMap.cs new file mode 100644 index 0000000..167d0ad --- /dev/null +++ b/DotTiled.Tests/Assert/AssertMap.cs @@ -0,0 +1,40 @@ +namespace DotTiled.Tests; + +public static partial class DotTiledAssert +{ + 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); + + AssertProperties(actual.Properties, expected.Properties); + + Assert.NotNull(actual.Tilesets); + Assert.Equal(expected.Tilesets.Count, actual.Tilesets.Count); + for (var i = 0; i < expected.Tilesets.Count; i++) + AssertTileset(actual.Tilesets[i], expected.Tilesets[i]); + + Assert.NotNull(actual.Layers); + Assert.Equal(expected.Layers.Count, actual.Layers.Count); + for (var i = 0; i < expected.Layers.Count; i++) + AssertLayer(actual.Layers[i], expected.Layers[i]); + } +} diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.ObjectTests.cs b/DotTiled.Tests/Assert/AssertObject.cs similarity index 68% rename from DotTiled.Tests/TmxSerializer/TmxSerializer.ObjectTests.cs rename to DotTiled.Tests/Assert/AssertObject.cs index c593074..68d74eb 100644 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.ObjectTests.cs +++ b/DotTiled.Tests/Assert/AssertObject.cs @@ -1,8 +1,8 @@ namespace DotTiled.Tests; -public partial class TmxSerializerObjectTests +public static partial class DotTiledAssert { - public static void AssertObject(Object actual, Object expected) + internal static void AssertObject(Object expected, Object actual) { // Attributes Assert.Equal(expected.ID, actual.ID); @@ -17,36 +17,36 @@ public partial class TmxSerializerObjectTests Assert.Equal(expected.Visible, actual.Visible); Assert.Equal(expected.Template, actual.Template); - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); - AssertObject((dynamic)actual, (dynamic)expected); + AssertProperties(actual.Properties, expected.Properties); + AssertObject((dynamic)expected, (dynamic)actual); } - private static void AssertObject(RectangleObject actual, RectangleObject expected) + private static void AssertObject(RectangleObject expected, RectangleObject actual) { Assert.True(true); // A rectangle object is the same as the abstract Object } - private static void AssertObject(EllipseObject actual, EllipseObject expected) + private static void AssertObject(EllipseObject expected, EllipseObject actual) { Assert.True(true); // An ellipse object is the same as the abstract Object } - private static void AssertObject(PointObject actual, PointObject expected) + private static void AssertObject(PointObject expected, PointObject actual) { Assert.True(true); // A point object is the same as the abstract Object } - private static void AssertObject(PolygonObject actual, PolygonObject expected) + private static void AssertObject(PolygonObject expected, PolygonObject actual) { Assert.Equal(expected.Points, actual.Points); } - private static void AssertObject(PolylineObject actual, PolylineObject expected) + private static void AssertObject(PolylineObject expected, PolylineObject actual) { Assert.Equal(expected.Points, actual.Points); } - private static void AssertObject(TextObject actual, TextObject expected) + private static void AssertObject(TextObject expected, TextObject actual) { // Attributes Assert.Equal(expected.FontFamily, actual.FontFamily); diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.PropertiesTests.cs b/DotTiled.Tests/Assert/AssertProperties.cs similarity index 91% rename from DotTiled.Tests/TmxSerializer/TmxSerializer.PropertiesTests.cs rename to DotTiled.Tests/Assert/AssertProperties.cs index e22e5b9..d0a8269 100644 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.PropertiesTests.cs +++ b/DotTiled.Tests/Assert/AssertProperties.cs @@ -1,8 +1,8 @@ namespace DotTiled.Tests; -public partial class TmxSerializerPropertiesTests +public static partial class DotTiledAssert { - public static void AssertProperties(Dictionary? actual, Dictionary? expected) + internal static void AssertProperties(Dictionary? expected, Dictionary? actual) { if (expected is null) { diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.TilesetTests.cs b/DotTiled.Tests/Assert/AssertTileset.cs similarity index 68% rename from DotTiled.Tests/TmxSerializer/TmxSerializer.TilesetTests.cs rename to DotTiled.Tests/Assert/AssertTileset.cs index 04bb54b..8421bd0 100644 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.TilesetTests.cs +++ b/DotTiled.Tests/Assert/AssertTileset.cs @@ -1,8 +1,8 @@ namespace DotTiled.Tests; -public partial class TmxSerializerTilesetTests +public static partial class DotTiledAssert { - public static void AssertTileset(Tileset actual, Tileset expected) + internal static void AssertTileset(Tileset expected, Tileset actual) { // Attributes Assert.Equal(expected.Version, actual.Version); @@ -22,28 +22,28 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.FillMode, actual.FillMode); // At most one of - TmxSerializerImageTests.AssertImage(actual.Image, expected.Image); - AssertTileOffset(actual.TileOffset, expected.TileOffset); - AssertGrid(actual.Grid, expected.Grid); - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); + AssertImage(expected.Image, actual.Image); + AssertTileOffset(expected.TileOffset, actual.TileOffset); + AssertGrid(expected.Grid, actual.Grid); + AssertProperties(expected.Properties, actual.Properties); // TODO: AssertTerrainTypes(actual.TerrainTypes, expected.TerrainTypes); if (expected.Wangsets is not null) { Assert.NotNull(actual.Wangsets); Assert.Equal(expected.Wangsets.Count, actual.Wangsets.Count); for (var i = 0; i < expected.Wangsets.Count; i++) - AssertWangset(actual.Wangsets[i], expected.Wangsets[i]); + AssertWangset(expected.Wangsets[i], actual.Wangsets[i]); } - AssertTransformations(actual.Transformations, expected.Transformations); + AssertTransformations(expected.Transformations, actual.Transformations); // Any number of Assert.NotNull(actual.Tiles); Assert.Equal(expected.Tiles.Count, actual.Tiles.Count); for (var i = 0; i < expected.Tiles.Count; i++) - AssertTile(actual.Tiles[i], expected.Tiles[i]); + AssertTile(expected.Tiles[i], actual.Tiles[i]); } - private static void AssertTileOffset(TileOffset? actual, TileOffset? expected) + private static void AssertTileOffset(TileOffset? expected, TileOffset? actual) { if (expected is null) { @@ -57,7 +57,7 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.Y, actual.Y); } - private static void AssertGrid(Grid? actual, Grid? expected) + private static void AssertGrid(Grid? expected, Grid? actual) { if (expected is null) { @@ -72,7 +72,7 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.Height, actual.Height); } - private static void AssertWangset(Wangset actual, Wangset expected) + private static void AssertWangset(Wangset expected, Wangset actual) { // Attributes Assert.Equal(expected.Name, actual.Name); @@ -80,19 +80,19 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.Tile, actual.Tile); // At most one of - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); + AssertProperties(expected.Properties, actual.Properties); if (expected.WangColors is not null) { Assert.NotNull(actual.WangColors); Assert.Equal(expected.WangColors.Count, actual.WangColors.Count); for (var i = 0; i < expected.WangColors.Count; i++) - AssertWangColor(actual.WangColors[i], expected.WangColors[i]); + AssertWangColor(expected.WangColors[i], actual.WangColors[i]); } for (var i = 0; i < expected.WangTiles.Count; i++) - AssertWangTile(actual.WangTiles[i], expected.WangTiles[i]); + AssertWangTile(expected.WangTiles[i], actual.WangTiles[i]); } - private static void AssertWangColor(WangColor actual, WangColor expected) + private static void AssertWangColor(WangColor expected, WangColor actual) { // Attributes Assert.Equal(expected.Name, actual.Name); @@ -101,17 +101,17 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.Tile, actual.Tile); Assert.Equal(expected.Probability, actual.Probability); - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); + AssertProperties(expected.Properties, actual.Properties); } - private static void AssertWangTile(WangTile actual, WangTile expected) + private static void AssertWangTile(WangTile expected, WangTile actual) { // Attributes Assert.Equal(expected.TileID, actual.TileID); Assert.Equal(expected.WangID, actual.WangID); } - private static void AssertTransformations(Transformations? actual, Transformations? expected) + private static void AssertTransformations(Transformations? expected, Transformations? actual) { if (expected is null) { @@ -127,7 +127,7 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.PreferUntransformed, actual.PreferUntransformed); } - private static void AssertTile(Tile actual, Tile expected) + private static void AssertTile(Tile expected, Tile actual) { // Attributes Assert.Equal(expected.ID, actual.ID); @@ -139,19 +139,19 @@ public partial class TmxSerializerTilesetTests Assert.Equal(expected.Height, actual.Height); // Elements - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); - TmxSerializerImageTests.AssertImage(actual.Image, expected.Image); - TmxSerializerLayerTests.AssertLayer(actual.ObjectLayer, expected.ObjectLayer); + AssertProperties(actual.Properties, expected.Properties); + AssertImage(actual.Image, expected.Image); + AssertLayer((BaseLayer?)actual.ObjectLayer, (BaseLayer?)expected.ObjectLayer); if (expected.Animation is not null) { Assert.NotNull(actual.Animation); Assert.Equal(expected.Animation.Count, actual.Animation.Count); for (var i = 0; i < expected.Animation.Count; i++) - AssertFrame(actual.Animation[i], expected.Animation[i]); + AssertFrame(expected.Animation[i], actual.Animation[i]); } } - private static void AssertFrame(Frame actual, Frame expected) + private static void AssertFrame(Frame expected, Frame actual) { // Attributes Assert.Equal(expected.TileID, actual.TileID); diff --git a/DotTiled.Tests/DotTiled.Tests.csproj b/DotTiled.Tests/DotTiled.Tests.csproj index 44236af..5e36559 100644 --- a/DotTiled.Tests/DotTiled.Tests.csproj +++ b/DotTiled.Tests/DotTiled.Tests.csproj @@ -26,7 +26,7 @@ - + diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-base64-gzip.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-base64-gzip.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-base64-gzip.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-base64-gzip.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-base64-zlib.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-base64-zlib.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-base64-zlib.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-base64-zlib.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-base64.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-base64.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-base64.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-base64.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-csv.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-csv.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-csv.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-csv.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-properties.cs b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-properties.cs similarity index 97% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-properties.cs rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-properties.cs index c87c183..795b920 100644 --- a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-properties.cs +++ b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-properties.cs @@ -1,6 +1,6 @@ namespace DotTiled.Tests; -public partial class TmxSerializerMapTests +public partial class TmxMapReaderTests { private static Map EmptyMapWithProperties() => new Map { diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-properties.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-properties.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map-properties.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map-properties.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map.cs b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map.cs similarity index 97% rename from DotTiled.Tests/TmxSerializer/TestData/Map/empty-map.cs rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map.cs index e01516b..12cfc00 100644 --- a/DotTiled.Tests/TmxSerializer/TestData/Map/empty-map.cs +++ b/DotTiled.Tests/Serialization/Tmx/TestData/Map/empty-map.cs @@ -1,6 +1,6 @@ namespace DotTiled.Tests; -public partial class TmxSerializerMapTests +public partial class TmxMapReaderTests { private static Map EmptyMapWithEncodingAndCompression(DataEncoding dataEncoding, DataCompression? compression) => new Map { diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/map-with-group.cs b/DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-group.cs similarity index 98% rename from DotTiled.Tests/TmxSerializer/TestData/Map/map-with-group.cs rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-group.cs index 0bac69e..515312e 100644 --- a/DotTiled.Tests/TmxSerializer/TestData/Map/map-with-group.cs +++ b/DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-group.cs @@ -1,6 +1,6 @@ namespace DotTiled.Tests; -public partial class TmxSerializerMapTests +public partial class TmxMapReaderTests { private static Map MapWithGroup() => new Map { diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/map-with-group.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-group.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/map-with-group.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-group.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/map-with-object-template.cs b/DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-object-template.cs similarity index 98% rename from DotTiled.Tests/TmxSerializer/TestData/Map/map-with-object-template.cs rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-object-template.cs index 31a658e..8f4459e 100644 --- a/DotTiled.Tests/TmxSerializer/TestData/Map/map-with-object-template.cs +++ b/DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-object-template.cs @@ -1,6 +1,6 @@ namespace DotTiled.Tests; -public partial class TmxSerializerMapTests +public partial class TmxMapReaderTests { private static Map MapWithObjectTemplate() => new Map { diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/map-with-object-template.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-object-template.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/map-with-object-template.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/map-with-object-template.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/simple-tileset-embed.cs b/DotTiled.Tests/Serialization/Tmx/TestData/Map/simple-tileset-embed.cs similarity index 97% rename from DotTiled.Tests/TmxSerializer/TestData/Map/simple-tileset-embed.cs rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/simple-tileset-embed.cs index ad27d8e..7dfb740 100644 --- a/DotTiled.Tests/TmxSerializer/TestData/Map/simple-tileset-embed.cs +++ b/DotTiled.Tests/Serialization/Tmx/TestData/Map/simple-tileset-embed.cs @@ -1,6 +1,6 @@ namespace DotTiled.Tests; -public partial class TmxSerializerMapTests +public partial class TmxMapReaderTests { private static Map SimpleMapWithEmbeddedTileset() => new Map { diff --git a/DotTiled.Tests/TmxSerializer/TestData/Map/simple-tileset-embed.tmx b/DotTiled.Tests/Serialization/Tmx/TestData/Map/simple-tileset-embed.tmx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Map/simple-tileset-embed.tmx rename to DotTiled.Tests/Serialization/Tmx/TestData/Map/simple-tileset-embed.tmx diff --git a/DotTiled.Tests/TmxSerializer/TestData/Template/map-with-object-template.tx b/DotTiled.Tests/Serialization/Tmx/TestData/Template/map-with-object-template.tx similarity index 100% rename from DotTiled.Tests/TmxSerializer/TestData/Template/map-with-object-template.tx rename to DotTiled.Tests/Serialization/Tmx/TestData/Template/map-with-object-template.tx diff --git a/DotTiled.Tests/TmxSerializer/TestData/TestData.cs b/DotTiled.Tests/Serialization/Tmx/TestData/TestData.cs similarity index 70% rename from DotTiled.Tests/TmxSerializer/TestData/TestData.cs rename to DotTiled.Tests/Serialization/Tmx/TestData/TestData.cs index 7dbc2ad..667fec0 100644 --- a/DotTiled.Tests/TmxSerializer/TestData/TestData.cs +++ b/DotTiled.Tests/Serialization/Tmx/TestData/TestData.cs @@ -2,12 +2,12 @@ using System.Xml; namespace DotTiled.Tests; -public static class TmxSerializerTestData +public static class TmxMapReaderTestData { - public static XmlReader GetReaderFor(string testDataFile) + public static XmlReader GetXmlReaderFor(string testDataFile) { var fullyQualifiedTestDataFile = $"DotTiled.Tests.{testDataFile}"; - using var stream = typeof(TmxSerializerTestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) + using var stream = typeof(TmxMapReaderTestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) ?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found"); using var stringReader = new StreamReader(stream); @@ -19,7 +19,7 @@ public static class TmxSerializerTestData public static string GetRawStringFor(string testDataFile) { var fullyQualifiedTestDataFile = $"DotTiled.Tests.{testDataFile}"; - using var stream = typeof(TmxSerializerTestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) + using var stream = typeof(TmxMapReaderTestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile) ?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found"); using var stringReader = new StreamReader(stream); diff --git a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs new file mode 100644 index 0000000..1924ac2 --- /dev/null +++ b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs @@ -0,0 +1,150 @@ +using System.Xml; + +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.Tmx.TestData.Map.empty-map-csv.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Csv, null)], + ["Serialization.Tmx.TestData.Map.empty-map-base64.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, null)], + ["Serialization.Tmx.TestData.Map.empty-map-base64-gzip.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.GZip)], + ["Serialization.Tmx.TestData.Map.empty-map-base64-zlib.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.ZLib)], + ["Serialization.Tmx.TestData.Map.simple-tileset-embed.tmx", SimpleMapWithEmbeddedTileset()], + ["Serialization.Tmx.TestData.Map.empty-map-properties.tmx", EmptyMapWithProperties()], + ]; + + [Theory] + [MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] + public void TmxMapReaderReadMap_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) + { + // Arrange + using var reader = TmxMapReaderTestData.GetXmlReaderFor(testDataFile); + static Template ResolveTemplate(string source) + { + using var xmlTemplateReader = TmxMapReaderTestData.GetXmlReaderFor($"Serialization.Tmx.TestData.Template.{source}"); + using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate); + return templateReader.ReadTemplate(); + } + static Tileset ResolveTileset(string source) + { + using var xmlTilesetReader = TmxMapReaderTestData.GetXmlReaderFor($"Serialization.Tmx.TestData.Tileset.{source}"); + using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate); + return tilesetReader.ReadTileset(); + } + using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate); + + // Act + var map = mapReader.ReadMap(); + + // Assert + Assert.NotNull(map); + DotTiledAssert.AssertMap(expectedMap, map); + } + + public static IEnumerable DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data => + [ + ["Serialization.Tmx.TestData.Map.map-with-object-template.tmx", MapWithObjectTemplate()], + ["Serialization.Tmx.TestData.Map.map-with-group.tmx", MapWithGroup()], + ]; + + [Theory] + [MemberData(nameof(DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] + public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) + { + // Arrange + using var reader = TmxMapReaderTestData.GetXmlReaderFor(testDataFile); + static Template ResolveTemplate(string source) + { + using var xmlTemplateReader = TmxMapReaderTestData.GetXmlReaderFor($"Serialization.Tmx.TestData.Template.{source}"); + using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate); + return templateReader.ReadTemplate(); + } + static Tileset ResolveTileset(string source) + { + using var xmlTilesetReader = TmxMapReaderTestData.GetXmlReaderFor($"Serialization.Tmx.TestData.Tileset.{source}"); + using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate); + return tilesetReader.ReadTileset(); + } + using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate); + + // Act + var map = mapReader.ReadMap(); + + // Assert + Assert.NotNull(map); + DotTiledAssert.AssertMap(expectedMap, map); + } +} diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializer.MapTests.cs b/DotTiled.Tests/TmxSerializer/TmxSerializer.MapTests.cs deleted file mode 100644 index 5a54e7c..0000000 --- a/DotTiled.Tests/TmxSerializer/TmxSerializer.MapTests.cs +++ /dev/null @@ -1,242 +0,0 @@ -namespace DotTiled.Tests; - -public partial class TmxSerializerMapTests -{ - private static void AssertMap(Map actual, Map expected) - { - // 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); - - TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties); - - Assert.NotNull(actual.Tilesets); - Assert.Equal(expected.Tilesets.Count, actual.Tilesets.Count); - for (var i = 0; i < expected.Tilesets.Count; i++) - TmxSerializerTilesetTests.AssertTileset(actual.Tilesets[i], expected.Tilesets[i]); - - Assert.NotNull(actual.Layers); - Assert.Equal(expected.Layers.Count, actual.Layers.Count); - for (var i = 0; i < expected.Layers.Count; i++) - TmxSerializerLayerTests.AssertLayer(actual.Layers[i], expected.Layers[i]); - } - - public static IEnumerable DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data => - [ - ["TmxSerializer.TestData.Map.empty-map-csv.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Csv, null)], - ["TmxSerializer.TestData.Map.empty-map-base64.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, null)], - ["TmxSerializer.TestData.Map.empty-map-base64-gzip.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.GZip)], - ["TmxSerializer.TestData.Map.empty-map-base64-zlib.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.ZLib)], - ["TmxSerializer.TestData.Map.simple-tileset-embed.tmx", SimpleMapWithEmbeddedTileset()], - ["TmxSerializer.TestData.Map.empty-map-properties.tmx", EmptyMapWithProperties()], - ]; - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void DeserializeMapFromXmlReader_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) - { - // Arrange - using var reader = TmxSerializerTestData.GetReaderFor(testDataFile); - var testDataFileText = TmxSerializerTestData.GetRawStringFor(testDataFile); - Func externalTilesetResolver = (TmxSerializer serializer, string s) => - throw new NotSupportedException("External tilesets are not supported in this test"); - Func externalTemplateResolver = (TmxSerializer serializer, string s) => - throw new NotSupportedException("External templates are not supported in this test"); - var tmxSerializer = new TmxSerializer( - externalTilesetResolver, - externalTemplateResolver); - - // Act - - static Template ResolveTemplate(string source) - { - using var xmlTemplateReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Template.{source}"); - using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate); - return templateReader.ReadTemplate(); - } - - static Tileset ResolveTileset(string source) - { - using var xmlTilesetReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Tileset.{source}"); - using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate); - return tilesetReader.ReadTileset(); - } - - var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate); - - var map = mapReader.ReadMap(); - var raw = tmxSerializer.DeserializeMap(testDataFileText); - - // Assert - Assert.NotNull(map); - AssertMap(map, expectedMap); - - Assert.NotNull(raw); - AssertMap(raw, expectedMap); - - AssertMap(map, raw); - } - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void DeserializeMapFromString_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) - { - // Arrange - var testDataFileText = TmxSerializerTestData.GetRawStringFor(testDataFile); - Func externalTilesetResolver = (TmxSerializer serializer, string s) => - throw new NotSupportedException("External tilesets are not supported in this test"); - Func externalTemplateResolver = (TmxSerializer serializer, string s) => - throw new NotSupportedException("External templates are not supported in this test"); - var tmxSerializer = new TmxSerializer( - externalTilesetResolver, - externalTemplateResolver); - - // Act - var raw = tmxSerializer.DeserializeMap(testDataFileText); - - // Assert - Assert.NotNull(raw); - AssertMap(raw, expectedMap); - } - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void DeserializeMapFromStringFromXmlReader_ValidXmlNoExternalTilesets_Equal(string testDataFile, Map expectedMap) - { - // Arrange - using var reader = TmxSerializerTestData.GetReaderFor(testDataFile); - var testDataFileText = TmxSerializerTestData.GetRawStringFor(testDataFile); - Func externalTilesetResolver = (TmxSerializer serializer, string s) => - throw new NotSupportedException("External tilesets are not supported in this test"); - Func externalTemplateResolver = (TmxSerializer serializer, string s) => - throw new NotSupportedException("External templates are not supported in this test"); - var tmxSerializer = new TmxSerializer( - externalTilesetResolver, - externalTemplateResolver); - - // Act - var map = tmxSerializer.DeserializeMap(reader); - var raw = tmxSerializer.DeserializeMap(testDataFileText); - - // Assert - Assert.NotNull(map); - Assert.NotNull(raw); - - AssertMap(map, raw); - AssertMap(map, expectedMap); - AssertMap(raw, expectedMap); - } - - public static IEnumerable DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data => - [ - ["TmxSerializer.TestData.Map.map-with-object-template.tmx", MapWithObjectTemplate()], - ["TmxSerializer.TestData.Map.map-with-group.tmx", MapWithGroup()], - ]; - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void DeserializeMapFromXmlReader_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) - { - // Arrange - using var reader = TmxSerializerTestData.GetReaderFor(testDataFile); - Func externalTilesetResolver = (TmxSerializer serializer, string s) => - { - using var tilesetReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Tileset.{s}"); - return serializer.DeserializeTileset(tilesetReader); - }; - Func externalTemplateResolver = (TmxSerializer serializer, string s) => - { - using var templateReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Template.{s}"); - return serializer.DeserializeTemplate(templateReader); - }; - var tmxSerializer = new TmxSerializer( - externalTilesetResolver, - externalTemplateResolver); - - // Act - var map = tmxSerializer.DeserializeMap(reader); - - // Assert - Assert.NotNull(map); - AssertMap(map, expectedMap); - } - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void DeserializeMapFromString_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) - { - // Arrange - var testDataFileText = TmxSerializerTestData.GetRawStringFor(testDataFile); - Func externalTilesetResolver = (TmxSerializer serializer, string s) => - { - using var tilesetReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Tileset.{s}"); - return serializer.DeserializeTileset(tilesetReader); - }; - Func externalTemplateResolver = (TmxSerializer serializer, string s) => - { - using var templateReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Template.{s}"); - return serializer.DeserializeTemplate(templateReader); - }; - var tmxSerializer = new TmxSerializer( - externalTilesetResolver, - externalTemplateResolver); - - // Act - var map = tmxSerializer.DeserializeMap(testDataFileText); - - // Assert - Assert.NotNull(map); - AssertMap(map, expectedMap); - } - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void DeserializeMapFromStringFromXmlReader_ValidXmlExternalTilesetsAndTemplates_Equal(string testDataFile, Map expectedMap) - { - // Arrange - using var reader = TmxSerializerTestData.GetReaderFor(testDataFile); - var testDataFileText = TmxSerializerTestData.GetRawStringFor(testDataFile); - Func externalTilesetResolver = (TmxSerializer serializer, string s) => - { - using var tilesetReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Tileset.{s}"); - return serializer.DeserializeTileset(tilesetReader); - }; - Func externalTemplateResolver = (TmxSerializer serializer, string s) => - { - using var templateReader = TmxSerializerTestData.GetReaderFor($"TmxSerializer.TestData.Template.{s}"); - return serializer.DeserializeTemplate(templateReader); - }; - var tmxSerializer = new TmxSerializer( - externalTilesetResolver, - externalTemplateResolver); - - // Act - var map = tmxSerializer.DeserializeMap(reader); - var raw = tmxSerializer.DeserializeMap(testDataFileText); - - // Assert - Assert.NotNull(map); - Assert.NotNull(raw); - - AssertMap(map, raw); - AssertMap(map, expectedMap); - AssertMap(raw, expectedMap); - } -} diff --git a/DotTiled.Tests/TmxSerializer/TmxSerializerTests.cs b/DotTiled.Tests/TmxSerializer/TmxSerializerTests.cs deleted file mode 100644 index 0c27cf1..0000000 --- a/DotTiled.Tests/TmxSerializer/TmxSerializerTests.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace DotTiled.Tests; - -public class TmxSerializerTests -{ - [Fact] - public void TmxSerializerConstructor_ExternalTilesetResolverIsNull_ThrowsArgumentNullException() - { - // Arrange - Func externalTilesetResolver = null!; - Func externalTemplateResolver = null!; - - // Act - Action act = () => _ = new TmxSerializer(externalTilesetResolver, externalTemplateResolver); - - // Assert - Assert.Throws(act); - } - - [Fact] - public void TmxSerializerConstructor_ExternalTilesetResolverIsNotNull_DoesNotThrow() - { - // Arrange - Func externalTilesetResolver = (_, _) => new Tileset(); - Func externalTemplateResolver = (_, _) => new Template { Object = new RectangleObject { } }; - - // Act - var tmxSerializer = new TmxSerializer(externalTilesetResolver, externalTemplateResolver); - - // Assert - Assert.NotNull(tmxSerializer); - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.Chunk.cs b/DotTiled/TmxSerializer/TmxSerializer.Chunk.cs deleted file mode 100644 index 47a2cb2..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.Chunk.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private Chunk ReadChunk(XmlReader reader, DataEncoding? encoding, DataCompression? compression) - { - var x = reader.GetRequiredAttributeParseable("x"); - var y = reader.GetRequiredAttributeParseable("y"); - var width = reader.GetRequiredAttributeParseable("width"); - var height = reader.GetRequiredAttributeParseable("height"); - - var usesTileChildrenInsteadOfRawData = encoding is null; - if (usesTileChildrenInsteadOfRawData) - { - var globalTileIDsWithFlippingFlags = ReadTileChildrenInWrapper("chunk", reader); - var (globalTileIDs, flippingFlags) = ReadAndClearFlippingFlagsFromGIDs(globalTileIDsWithFlippingFlags); - return new Chunk { X = x, Y = y, Width = width, Height = height, GlobalTileIDs = globalTileIDs, FlippingFlags = flippingFlags }; - } - else - { - var globalTileIDsWithFlippingFlags = ReadRawData(reader, encoding!.Value, compression); - var (globalTileIDs, flippingFlags) = ReadAndClearFlippingFlagsFromGIDs(globalTileIDsWithFlippingFlags); - return new Chunk { X = x, Y = y, Width = width, Height = height, GlobalTileIDs = globalTileIDs, FlippingFlags = flippingFlags }; - } - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.Data.cs b/DotTiled/TmxSerializer/TmxSerializer.Data.cs deleted file mode 100644 index 4725614..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.Data.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private Data ReadData(XmlReader reader, bool usesChunks) - { - var encoding = reader.GetOptionalAttributeEnum("encoding", e => e switch - { - "csv" => DataEncoding.Csv, - "base64" => DataEncoding.Base64, - _ => throw new XmlException("Invalid encoding") - }); - var compression = reader.GetOptionalAttributeEnum("compression", c => c switch - { - "gzip" => DataCompression.GZip, - "zlib" => DataCompression.ZLib, - "zstd" => DataCompression.ZStd, - _ => throw new XmlException("Invalid compression") - }); - - if (usesChunks) - { - var chunks = reader - .ReadList("data", "chunk", (r) => ReadChunk(r, encoding, compression)) - .ToArray(); - return new Data { Encoding = encoding, Compression = compression, GlobalTileIDs = null, Chunks = chunks }; - } - - var usesTileChildrenInsteadOfRawData = encoding is null && compression is null; - if (usesTileChildrenInsteadOfRawData) - { - var tileChildrenGlobalTileIDsWithFlippingFlags = ReadTileChildrenInWrapper("data", reader); - var (tileChildrenGlobalTileIDs, tileChildrenFlippingFlags) = ReadAndClearFlippingFlagsFromGIDs(tileChildrenGlobalTileIDsWithFlippingFlags); - return new Data { Encoding = encoding, Compression = compression, GlobalTileIDs = tileChildrenGlobalTileIDs, FlippingFlags = tileChildrenFlippingFlags, Chunks = null }; - } - - var rawDataGlobalTileIDsWithFlippingFlags = ReadRawData(reader, encoding!.Value, compression); - var (rawDataGlobalTileIDs, rawDataFlippingFlags) = ReadAndClearFlippingFlagsFromGIDs(rawDataGlobalTileIDsWithFlippingFlags); - return new Data { Encoding = encoding, Compression = compression, GlobalTileIDs = rawDataGlobalTileIDs, FlippingFlags = rawDataFlippingFlags, Chunks = null }; - } - - private (uint[] GlobalTileIDs, FlippingFlags[] FlippingFlags) ReadAndClearFlippingFlagsFromGIDs(uint[] globalTileIDs) - { - var clearedGlobalTileIDs = new uint[globalTileIDs.Length]; - var flippingFlags = new FlippingFlags[globalTileIDs.Length]; - for (var i = 0; i < globalTileIDs.Length; i++) - { - var gid = globalTileIDs[i]; - var flags = gid & 0xF0000000u; - flippingFlags[i] = (FlippingFlags)flags; - clearedGlobalTileIDs[i] = gid & 0x0FFFFFFFu; - } - - return (clearedGlobalTileIDs, flippingFlags); - } - - private uint[] ReadTileChildrenInWrapper(string wrapper, XmlReader reader) - { - return reader.ReadList(wrapper, "tile", (r) => r.GetOptionalAttributeParseable("gid") ?? 0).ToArray(); - } - - private uint[] ReadRawData(XmlReader reader, DataEncoding encoding, DataCompression? compression) - { - var data = reader.ReadElementContentAsString(); - if (encoding == DataEncoding.Csv) - return ParseCsvData(data); - - using var bytes = new MemoryStream(Convert.FromBase64String(data)); - if (compression is null) - return ReadMemoryStreamAsInt32Array(bytes); - - var decompressed = compression switch - { - DataCompression.GZip => DecompressGZip(bytes), - DataCompression.ZLib => DecompressZLib(bytes), - DataCompression.ZStd => throw new NotSupportedException("ZStd compression is not supported."), - _ => throw new XmlException("Invalid compression") - }; - - return decompressed; - } - - private uint[] ParseCsvData(string data) - { - var values = data - .Split((char[])['\n', '\r', ','], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) - .Select(uint.Parse) - .ToArray(); - return values; - } - - private uint[] ReadMemoryStreamAsInt32Array(Stream stream) - { - var finalValues = new List(); - var int32Bytes = new byte[4]; - while (stream.Read(int32Bytes, 0, 4) == 4) - { - var value = BitConverter.ToUInt32(int32Bytes, 0); - finalValues.Add(value); - } - return finalValues.ToArray(); - } - - private uint[] DecompressGZip(MemoryStream stream) - { - using var decompressedStream = new GZipStream(stream, CompressionMode.Decompress); - return ReadMemoryStreamAsInt32Array(decompressedStream); - } - - private uint[] DecompressZLib(MemoryStream stream) - { - using var decompressedStream = new ZLibStream(stream, CompressionMode.Decompress); - return ReadMemoryStreamAsInt32Array(decompressedStream); - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.Helpers.cs b/DotTiled/TmxSerializer/TmxSerializer.Helpers.cs deleted file mode 100644 index 14fcfaa..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.Helpers.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private static class Helpers - { - public static void SetAtMostOnce(ref T? field, T value, string fieldName) - { - if (field is not null) - throw new InvalidOperationException($"{fieldName} already set"); - - field = value; - } - - public static void SetAtMostOnceUsingCounter(ref T? field, T value, string fieldName, ref int counter) - { - if (counter > 0) - throw new InvalidOperationException($"{fieldName} already set"); - - field = value; - counter++; - } - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.Map.cs b/DotTiled/TmxSerializer/TmxSerializer.Map.cs deleted file mode 100644 index 799b217..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.Map.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private Map ReadMap(XmlReader reader) - { - // Attributes - var version = reader.GetRequiredAttribute("version"); - var tiledVersion = reader.GetRequiredAttribute("tiledversion"); - var @class = reader.GetOptionalAttribute("class") ?? ""; - var orientation = reader.GetRequiredAttributeEnum("orientation", s => s switch - { - "orthogonal" => MapOrientation.Orthogonal, - "isometric" => MapOrientation.Isometric, - "staggered" => MapOrientation.Staggered, - "hexagonal" => MapOrientation.Hexagonal, - _ => throw new Exception($"Unknown orientation '{s}'") - }); - var renderOrder = reader.GetOptionalAttributeEnum("renderorder", s => s switch - { - "right-down" => RenderOrder.RightDown, - "right-up" => RenderOrder.RightUp, - "left-down" => RenderOrder.LeftDown, - "left-up" => RenderOrder.LeftUp, - _ => throw new Exception($"Unknown render order '{s}'") - }) ?? RenderOrder.RightDown; - var compressionLevel = reader.GetOptionalAttributeParseable("compressionlevel") ?? -1; - var width = reader.GetRequiredAttributeParseable("width"); - var height = reader.GetRequiredAttributeParseable("height"); - var tileWidth = reader.GetRequiredAttributeParseable("tilewidth"); - var tileHeight = reader.GetRequiredAttributeParseable("tileheight"); - var hexSideLength = reader.GetOptionalAttributeParseable("hexsidelength"); - var staggerAxis = reader.GetOptionalAttributeEnum("staggeraxis", s => s switch - { - "x" => StaggerAxis.X, - "y" => StaggerAxis.Y, - _ => throw new Exception($"Unknown stagger axis '{s}'") - }); - var staggerIndex = reader.GetOptionalAttributeEnum("staggerindex", s => s switch - { - "odd" => StaggerIndex.Odd, - "even" => StaggerIndex.Even, - _ => throw new Exception($"Unknown stagger index '{s}'") - }); - var parallaxOriginX = reader.GetOptionalAttributeParseable("parallaxoriginx") ?? 0.0f; - var parallaxOriginY = reader.GetOptionalAttributeParseable("parallaxoriginy") ?? 0.0f; - var backgroundColor = reader.GetOptionalAttributeClass("backgroundcolor") ?? Color.Parse("#00000000", CultureInfo.InvariantCulture); - var nextLayerID = reader.GetRequiredAttributeParseable("nextlayerid"); - var nextObjectID = reader.GetRequiredAttributeParseable("nextobjectid"); - var infinite = (reader.GetOptionalAttributeParseable("infinite") ?? 0) == 1; - - // At most one of - Dictionary? properties = null; - - // Any number of - List layers = []; - List tilesets = []; - - reader.ProcessChildren("map", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - "tileset" => () => tilesets.Add(ReadTileset(r)), - "layer" => () => layers.Add(ReadTileLayer(r, dataUsesChunks: infinite)), - "objectgroup" => () => layers.Add(ReadObjectLayer(r)), - "imagelayer" => () => layers.Add(ReadImageLayer(r)), - "group" => () => layers.Add(ReadGroup(r)), - _ => r.Skip - }); - - return new Map - { - Version = version, - TiledVersion = tiledVersion, - Class = @class, - Orientation = orientation, - RenderOrder = renderOrder, - CompressionLevel = compressionLevel, - Width = width, - Height = height, - TileWidth = tileWidth, - TileHeight = tileHeight, - HexSideLength = hexSideLength, - StaggerAxis = staggerAxis, - StaggerIndex = staggerIndex, - ParallaxOriginX = parallaxOriginX, - ParallaxOriginY = parallaxOriginY, - BackgroundColor = backgroundColor, - NextLayerID = nextLayerID, - NextObjectID = nextObjectID, - Infinite = infinite, - Properties = properties, - Tilesets = tilesets, - Layers = layers - }; - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.ObjectLayer.cs b/DotTiled/TmxSerializer/TmxSerializer.ObjectLayer.cs deleted file mode 100644 index df97300..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.ObjectLayer.cs +++ /dev/null @@ -1,309 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Numerics; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private ObjectLayer ReadObjectLayer(XmlReader reader) - { - // Attributes - var id = reader.GetRequiredAttributeParseable("id"); - var name = reader.GetOptionalAttribute("name") ?? ""; - var @class = reader.GetOptionalAttribute("class") ?? ""; - var x = reader.GetOptionalAttributeParseable("x") ?? 0; - var y = reader.GetOptionalAttributeParseable("y") ?? 0; - var width = reader.GetOptionalAttributeParseable("width"); - var height = reader.GetOptionalAttributeParseable("height"); - var opacity = reader.GetOptionalAttributeParseable("opacity") ?? 1.0f; - var visible = reader.GetOptionalAttributeParseable("visible") ?? true; - var tintColor = reader.GetOptionalAttributeClass("tintcolor"); - var offsetX = reader.GetOptionalAttributeParseable("offsetx") ?? 0.0f; - var offsetY = reader.GetOptionalAttributeParseable("offsety") ?? 0.0f; - var parallaxX = reader.GetOptionalAttributeParseable("parallaxx") ?? 1.0f; - var parallaxY = reader.GetOptionalAttributeParseable("parallaxy") ?? 1.0f; - var color = reader.GetOptionalAttributeClass("color"); - var drawOrder = reader.GetOptionalAttributeEnum("draworder", s => s switch - { - "topdown" => DrawOrder.TopDown, - "index" => DrawOrder.Index, - _ => throw new Exception($"Unknown draw order '{s}'") - }) ?? DrawOrder.TopDown; - - // Elements - Dictionary? properties = null; - List objects = []; - - reader.ProcessChildren("objectgroup", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - "object" => () => objects.Add(ReadObject(r)), - _ => r.Skip - }); - - return new ObjectLayer - { - ID = id, - Name = name, - Class = @class, - X = x, - Y = y, - Width = width, - Height = height, - Opacity = opacity, - Visible = visible, - TintColor = tintColor, - OffsetX = offsetX, - OffsetY = offsetY, - ParallaxX = parallaxX, - ParallaxY = parallaxY, - Color = color, - Properties = properties, - DrawOrder = drawOrder, - Objects = objects - }; - } - - private Object ReadObject(XmlReader reader) - { - // 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 - if (template is not null) - { - var resolvedTemplate = _externalTemplateResolver(this, template); - var templObj = resolvedTemplate.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; - gidDefault = templObj.GID; - visibleDefault = templObj.Visible; - propertiesDefault = templObj.Properties; - } - - var id = reader.GetOptionalAttributeParseable("id") ?? idDefault; - var name = reader.GetOptionalAttribute("name") ?? nameDefault; - var type = reader.GetOptionalAttribute("type") ?? typeDefault; - var x = reader.GetOptionalAttributeParseable("x") ?? xDefault; - var y = reader.GetOptionalAttributeParseable("y") ?? yDefault; - var width = reader.GetOptionalAttributeParseable("width") ?? widthDefault; - var height = reader.GetOptionalAttributeParseable("height") ?? heightDefault; - var rotation = reader.GetOptionalAttributeParseable("rotation") ?? rotationDefault; - var gid = reader.GetOptionalAttributeParseable("gid") ?? gidDefault; - var visible = reader.GetOptionalAttributeParseable("visible") ?? visibleDefault; - - // Elements - Object? obj = null; - int propertiesCounter = 0; - Dictionary? properties = propertiesDefault; - - reader.ProcessChildren("object", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, MergeProperties(properties, ReadProperties(r)), "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"), - _ => throw new Exception($"Unknown object marker '{elementName}'") - }); - - if (obj is null) - { - obj = new RectangleObject { ID = id }; - reader.Skip(); - } - - obj.Name = name; - obj.Type = type; - obj.X = x; - obj.Y = y; - obj.Width = width; - obj.Height = height; - obj.Rotation = rotation; - obj.GID = gid; - obj.Visible = visible; - obj.Template = template; - obj.Properties = properties; - - return obj; - } - - private Dictionary MergeProperties(Dictionary? baseProperties, Dictionary overrideProperties) - { - if (baseProperties is null) - return overrideProperties ?? new Dictionary(); - - if (overrideProperties is null) - return baseProperties; - - var result = new Dictionary(baseProperties); - foreach (var (key, value) in overrideProperties) - { - if (!result.TryGetValue(key, out var baseProp)) - { - result[key] = value; - continue; - } - else - { - if (value is ClassProperty classProp) - { - ((ClassProperty)baseProp).Properties = MergeProperties(((ClassProperty)baseProp).Properties, classProp.Properties); - } - else - { - result[key] = value; - } - } - } - - return result; - } - - private EllipseObject ReadEllipseObject(XmlReader reader) - { - reader.Skip(); - return new EllipseObject { }; - } - - private PointObject ReadPointObject(XmlReader reader) - { - reader.Skip(); - return new PointObject { }; - } - - private PolygonObject ReadPolygonObject(XmlReader reader) - { - // Attributes - var points = reader.GetRequiredAttributeParseable>("points", s => - { - // Takes on format "x1,y1 x2,y2 x3,y3 ..." - var coords = s.Split(' '); - return coords.Select(c => - { - var xy = c.Split(','); - return new Vector2(float.Parse(xy[0], CultureInfo.InvariantCulture), float.Parse(xy[1], CultureInfo.InvariantCulture)); - }).ToList(); - }); - - reader.ReadStartElement("polygon"); - return new PolygonObject { Points = points }; - } - - private PolylineObject ReadPolylineObject(XmlReader reader) - { - // Attributes - var points = reader.GetRequiredAttributeParseable>("points", s => - { - // Takes on format "x1,y1 x2,y2 x3,y3 ..." - var coords = s.Split(' '); - return coords.Select(c => - { - var xy = c.Split(','); - return new Vector2(float.Parse(xy[0], CultureInfo.InvariantCulture), float.Parse(xy[1], CultureInfo.InvariantCulture)); - }).ToList(); - }); - - reader.ReadStartElement("polyline"); - return new PolylineObject { Points = points }; - } - - private TextObject ReadTextObject(XmlReader reader) - { - // Attributes - var fontFamily = reader.GetOptionalAttribute("fontfamily") ?? "sans-serif"; - var pixelSize = reader.GetOptionalAttributeParseable("pixelsize") ?? 16; - var wrap = reader.GetOptionalAttributeParseable("wrap") ?? false; - var color = reader.GetOptionalAttributeClass("color") ?? Color.Parse("#000000", CultureInfo.InvariantCulture); - var bold = reader.GetOptionalAttributeParseable("bold") ?? false; - var italic = reader.GetOptionalAttributeParseable("italic") ?? false; - var underline = reader.GetOptionalAttributeParseable("underline") ?? false; - var strikeout = reader.GetOptionalAttributeParseable("strikeout") ?? false; - var kerning = reader.GetOptionalAttributeParseable("kerning") ?? true; - var hAlign = reader.GetOptionalAttributeEnum("halign", s => s switch - { - "left" => TextHorizontalAlignment.Left, - "center" => TextHorizontalAlignment.Center, - "right" => TextHorizontalAlignment.Right, - "justify" => TextHorizontalAlignment.Justify, - _ => throw new Exception($"Unknown horizontal alignment '{s}'") - }) ?? TextHorizontalAlignment.Left; - var vAlign = reader.GetOptionalAttributeEnum("valign", s => s switch - { - "top" => TextVerticalAlignment.Top, - "center" => TextVerticalAlignment.Center, - "bottom" => TextVerticalAlignment.Bottom, - _ => throw new Exception($"Unknown vertical alignment '{s}'") - }) ?? TextVerticalAlignment.Top; - - // Elements - var text = reader.ReadElementContentAsString("text", ""); - - return new TextObject - { - FontFamily = fontFamily, - PixelSize = pixelSize, - Wrap = wrap, - Color = color, - Bold = bold, - Italic = italic, - Underline = underline, - Strikeout = strikeout, - Kerning = kerning, - HorizontalAlignment = hAlign, - VerticalAlignment = vAlign, - Text = text - }; - } - - private Template ReadTemplate(XmlReader reader) - { - // No attributes - - // At most one of - Tileset? tileset = null; - - // Should contain exactly one of - Object? obj = null; - - reader.ProcessChildren("template", (r, elementName) => elementName switch - { - "tileset" => () => Helpers.SetAtMostOnce(ref tileset, ReadTileset(r), "Tileset"), - "object" => () => Helpers.SetAtMostOnce(ref obj, ReadObject(r), "Object"), - _ => r.Skip - }); - - if (obj is null) - throw new NotSupportedException("Template must contain exactly one object"); - - return new Template - { - Tileset = tileset, - Object = obj - }; - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.Properties.cs b/DotTiled/TmxSerializer/TmxSerializer.Properties.cs deleted file mode 100644 index 1e7cd7e..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.Properties.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private Dictionary ReadProperties(XmlReader reader) - { - return reader.ReadList("properties", "property", (r) => - { - var name = r.GetRequiredAttribute("name"); - var type = r.GetOptionalAttributeEnum("type", (s) => s switch - { - "string" => PropertyType.String, - "int" => PropertyType.Int, - "float" => PropertyType.Float, - "bool" => PropertyType.Bool, - "color" => PropertyType.Color, - "file" => PropertyType.File, - "object" => PropertyType.Object, - "class" => PropertyType.Class, - _ => throw new XmlException("Invalid property type") - }) ?? PropertyType.String; - - IProperty property = type switch - { - PropertyType.String => new StringProperty { Name = name, Value = r.GetRequiredAttribute("value") }, - PropertyType.Int => new IntProperty { Name = name, Value = r.GetRequiredAttributeParseable("value") }, - PropertyType.Float => new FloatProperty { Name = name, Value = r.GetRequiredAttributeParseable("value") }, - PropertyType.Bool => new BoolProperty { Name = name, Value = r.GetRequiredAttributeParseable("value") }, - PropertyType.Color => new ColorProperty { Name = name, Value = r.GetRequiredAttributeParseable("value") }, - PropertyType.File => new FileProperty { Name = name, Value = r.GetRequiredAttribute("value") }, - PropertyType.Object => new ObjectProperty { Name = name, Value = r.GetRequiredAttributeParseable("value") }, - PropertyType.Class => ReadClassProperty(r), - _ => throw new XmlException("Invalid property type") - }; - return (name, property); - }).ToDictionary(x => x.name, x => x.property); - } - - private ClassProperty ReadClassProperty(XmlReader reader) - { - var name = reader.GetRequiredAttribute("name"); - var propertyType = reader.GetRequiredAttribute("propertytype"); - - reader.ReadStartElement("property"); - var properties = ReadProperties(reader); - reader.ReadEndElement(); - - return new ClassProperty { Name = name, PropertyType = propertyType, Properties = properties }; - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.TileLayer.cs b/DotTiled/TmxSerializer/TmxSerializer.TileLayer.cs deleted file mode 100644 index bd23d1f..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.TileLayer.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private TileLayer ReadTileLayer(XmlReader reader, bool dataUsesChunks) - { - var id = reader.GetRequiredAttributeParseable("id"); - var name = reader.GetOptionalAttribute("name") ?? ""; - var @class = reader.GetOptionalAttribute("class") ?? ""; - var x = reader.GetOptionalAttributeParseable("x") ?? 0; - var y = reader.GetOptionalAttributeParseable("y") ?? 0; - var width = reader.GetRequiredAttributeParseable("width"); - var height = reader.GetRequiredAttributeParseable("height"); - var opacity = reader.GetOptionalAttributeParseable("opacity") ?? 1.0f; - var visible = reader.GetOptionalAttributeParseable("visible") ?? true; - var tintColor = reader.GetOptionalAttributeClass("tintcolor"); - var offsetX = reader.GetOptionalAttributeParseable("offsetx") ?? 0.0f; - var offsetY = reader.GetOptionalAttributeParseable("offsety") ?? 0.0f; - var parallaxX = reader.GetOptionalAttributeParseable("parallaxx") ?? 1.0f; - var parallaxY = reader.GetOptionalAttributeParseable("parallaxy") ?? 1.0f; - - Dictionary? properties = null; - Data? data = null; - - reader.ProcessChildren("layer", (r, elementName) => elementName switch - { - "data" => () => Helpers.SetAtMostOnce(ref data, ReadData(r, dataUsesChunks), "Data"), - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - _ => r.Skip - }); - - return new TileLayer - { - ID = id, - Name = name, - Class = @class, - X = x, - Y = y, - Width = width, - Height = height, - Opacity = opacity, - Visible = visible, - TintColor = tintColor, - OffsetX = offsetX, - OffsetY = offsetY, - ParallaxX = parallaxX, - ParallaxY = parallaxY, - Data = data, - Properties = properties - }; - } - - private ImageLayer ReadImageLayer(XmlReader reader) - { - var id = reader.GetRequiredAttributeParseable("id"); - var name = reader.GetOptionalAttribute("name") ?? ""; - var @class = reader.GetOptionalAttribute("class") ?? ""; - var x = reader.GetOptionalAttributeParseable("x") ?? 0; - var y = reader.GetOptionalAttributeParseable("y") ?? 0; - var opacity = reader.GetOptionalAttributeParseable("opacity") ?? 1.0f; - var visible = reader.GetOptionalAttributeParseable("visible") ?? true; - var tintColor = reader.GetOptionalAttributeClass("tintcolor"); - var offsetX = reader.GetOptionalAttributeParseable("offsetx") ?? 0.0f; - 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"); - - Dictionary? properties = null; - Image? image = null; - - reader.ProcessChildren("imagelayer", (r, elementName) => elementName switch - { - "image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"), - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - _ => r.Skip - }); - - return new ImageLayer - { - ID = id, - Name = name, - Class = @class, - X = x, - Y = y, - Opacity = opacity, - Visible = visible, - TintColor = tintColor, - OffsetX = offsetX, - OffsetY = offsetY, - ParallaxX = parallaxX, - ParallaxY = parallaxY, - Properties = properties, - Image = image, - RepeatX = repeatX, - RepeatY = repeatY - }; - } - - private Group ReadGroup(XmlReader reader) - { - var id = reader.GetRequiredAttributeParseable("id"); - var name = reader.GetOptionalAttribute("name") ?? ""; - var @class = reader.GetOptionalAttribute("class") ?? ""; - var opacity = reader.GetOptionalAttributeParseable("opacity") ?? 1.0f; - var visible = reader.GetOptionalAttributeParseable("visible") ?? true; - var tintColor = reader.GetOptionalAttributeClass("tintcolor"); - var offsetX = reader.GetOptionalAttributeParseable("offsetx") ?? 0.0f; - var offsetY = reader.GetOptionalAttributeParseable("offsety") ?? 0.0f; - var parallaxX = reader.GetOptionalAttributeParseable("parallaxx") ?? 1.0f; - var parallaxY = reader.GetOptionalAttributeParseable("parallaxy") ?? 1.0f; - - Dictionary? properties = null; - List layers = []; - - reader.ProcessChildren("group", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - "layer" => () => layers.Add(ReadTileLayer(r, dataUsesChunks: false)), - "objectgroup" => () => layers.Add(ReadObjectLayer(r)), - "imagelayer" => () => layers.Add(ReadImageLayer(r)), - "group" => () => layers.Add(ReadGroup(r)), - _ => r.Skip - }); - - return new Group - { - ID = id, - Name = name, - Class = @class, - Opacity = opacity, - Visible = visible, - TintColor = tintColor, - OffsetX = offsetX, - OffsetY = offsetY, - ParallaxX = parallaxX, - ParallaxY = parallaxY, - Properties = properties, - Layers = layers - }; - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.Tileset.cs b/DotTiled/TmxSerializer/TmxSerializer.Tileset.cs deleted file mode 100644 index c16e037..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.Tileset.cs +++ /dev/null @@ -1,313 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private Tileset ReadTileset(XmlReader reader) - { - // Attributes - var version = reader.GetOptionalAttribute("version"); - var tiledVersion = reader.GetOptionalAttribute("tiledversion"); - var firstGID = reader.GetOptionalAttributeParseable("firstgid"); - var source = reader.GetOptionalAttribute("source"); - var name = reader.GetOptionalAttribute("name"); - var @class = reader.GetOptionalAttribute("class") ?? ""; - var tileWidth = reader.GetOptionalAttributeParseable("tilewidth"); - var tileHeight = reader.GetOptionalAttributeParseable("tileheight"); - var spacing = reader.GetOptionalAttributeParseable("spacing"); - var margin = reader.GetOptionalAttributeParseable("margin"); - var tileCount = reader.GetOptionalAttributeParseable("tilecount"); - var columns = reader.GetOptionalAttributeParseable("columns"); - var objectAlignment = reader.GetOptionalAttributeEnum("objectalignment", s => s switch - { - "unspecified" => ObjectAlignment.Unspecified, - "topleft" => ObjectAlignment.TopLeft, - "top" => ObjectAlignment.Top, - "topright" => ObjectAlignment.TopRight, - "left" => ObjectAlignment.Left, - "center" => ObjectAlignment.Center, - "right" => ObjectAlignment.Right, - "bottomleft" => ObjectAlignment.BottomLeft, - "bottom" => ObjectAlignment.Bottom, - "bottomright" => ObjectAlignment.BottomRight, - _ => throw new Exception($"Unknown object alignment '{s}'") - }) ?? ObjectAlignment.Unspecified; - var renderSize = reader.GetOptionalAttributeEnum("rendersize", s => s switch - { - "tile" => TileRenderSize.Tile, - "grid" => TileRenderSize.Grid, - _ => throw new Exception($"Unknown render size '{s}'") - }) ?? TileRenderSize.Tile; - var fillMode = reader.GetOptionalAttributeEnum("fillmode", s => s switch - { - "stretch" => FillMode.Stretch, - "preserve-aspect-fit" => FillMode.PreserveAspectFit, - _ => throw new Exception($"Unknown fill mode '{s}'") - }) ?? FillMode.Stretch; - - // Elements - Image? image = null; - TileOffset? tileOffset = null; - Grid? grid = null; - Dictionary? properties = null; - List? wangsets = null; - Transformations? transformations = null; - List tiles = []; - - reader.ProcessChildren("tileset", (r, elementName) => elementName switch - { - "image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"), - "tileoffset" => () => Helpers.SetAtMostOnce(ref tileOffset, ReadTileOffset(r), "TileOffset"), - "grid" => () => Helpers.SetAtMostOnce(ref grid, ReadGrid(r), "Grid"), - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - "wangsets" => () => Helpers.SetAtMostOnce(ref wangsets, ReadWangsets(r), "Wangsets"), - "transformations" => () => Helpers.SetAtMostOnce(ref transformations, ReadTransformations(r), "Transformations"), - "tile" => () => tiles.Add(ReadTile(r)), - _ => r.Skip - }); - - // Check if tileset is referring to external file - if (source is not null) - { - var resolvedTileset = _externalTilesetResolver(this, source); - resolvedTileset.FirstGID = firstGID; - resolvedTileset.Source = null; - return resolvedTileset; - } - - return new Tileset - { - Version = version, - TiledVersion = tiledVersion, - FirstGID = firstGID, - Source = source, - Name = name, - Class = @class, - TileWidth = tileWidth, - TileHeight = tileHeight, - Spacing = spacing, - Margin = margin, - TileCount = tileCount, - Columns = columns, - ObjectAlignment = objectAlignment, - RenderSize = renderSize, - FillMode = fillMode, - Image = image, - TileOffset = tileOffset, - Grid = grid, - Properties = properties, - Wangsets = wangsets, - Transformations = transformations, - Tiles = tiles - }; - } - - private Image ReadImage(XmlReader reader) - { - // Attributes - var format = reader.GetOptionalAttributeEnum("format", s => s switch - { - "png" => ImageFormat.Png, - "jpg" => ImageFormat.Jpg, - "bmp" => ImageFormat.Bmp, - "gif" => ImageFormat.Gif, - _ => throw new Exception($"Unknown image format '{s}'") - }); - var source = reader.GetOptionalAttribute("source"); - var transparentColor = reader.GetOptionalAttributeClass("trans"); - var width = reader.GetOptionalAttributeParseable("width"); - var height = reader.GetOptionalAttributeParseable("height"); - - reader.ProcessChildren("image", (r, elementName) => elementName switch - { - "data" => throw new NotSupportedException("Embedded image data is not supported."), - _ => r.Skip - }); - - return new Image - { - Format = format, - Source = source, - TransparentColor = transparentColor, - Width = width, - Height = height, - }; - } - - private TileOffset ReadTileOffset(XmlReader reader) - { - // Attributes - var x = reader.GetOptionalAttributeParseable("x") ?? 0f; - var y = reader.GetOptionalAttributeParseable("y") ?? 0f; - - reader.ReadStartElement("tileoffset"); - return new TileOffset { X = x, Y = y }; - } - - private Grid ReadGrid(XmlReader reader) - { - // Attributes - var orientation = reader.GetOptionalAttributeEnum("orientation", s => s switch - { - "orthogonal" => GridOrientation.Orthogonal, - "isometric" => GridOrientation.Isometric, - _ => throw new Exception($"Unknown orientation '{s}'") - }) ?? GridOrientation.Orthogonal; - var width = reader.GetRequiredAttributeParseable("width"); - var height = reader.GetRequiredAttributeParseable("height"); - - reader.ReadStartElement("grid"); - return new Grid { Orientation = orientation, Width = width, Height = height }; - } - - private 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; - - reader.ReadStartElement("transformations"); - return new Transformations { HFlip = hFlip, VFlip = vFlip, Rotate = rotate, PreferUntransformed = preferUntransformed }; - } - - private Tile ReadTile(XmlReader reader) - { - // Attributes - var id = reader.GetRequiredAttributeParseable("id"); - var type = reader.GetOptionalAttribute("type") ?? ""; - var probability = reader.GetOptionalAttributeParseable("probability") ?? 0f; - var x = reader.GetOptionalAttributeParseable("x") ?? 0; - var y = reader.GetOptionalAttributeParseable("y") ?? 0; - var width = reader.GetOptionalAttributeParseable("width"); - var height = reader.GetOptionalAttributeParseable("height"); - - // Elements - Dictionary? properties = null; - Image? image = null; - ObjectLayer? objectLayer = null; - List? animation = null; - - reader.ProcessChildren("tile", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - "image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"), - "objectgroup" => () => Helpers.SetAtMostOnce(ref objectLayer, ReadObjectLayer(r), "ObjectLayer"), - "animation" => () => Helpers.SetAtMostOnce(ref animation, r.ReadList("animation", "frame", (ar) => - { - var tileID = ar.GetRequiredAttributeParseable("tileid"); - var duration = ar.GetRequiredAttributeParseable("duration"); - return new Frame { TileID = tileID, Duration = duration }; - }), "Animation"), - _ => r.Skip - }); - - return new Tile - { - ID = id, - Type = type, - Probability = probability, - X = x, - Y = y, - Width = width ?? image?.Width ?? 0, - Height = height ?? image?.Height ?? 0, - Properties = properties, - Image = image, - ObjectLayer = objectLayer, - Animation = animation - }; - } - - private List ReadWangsets(XmlReader reader) - { - return reader.ReadList("wangsets", "wangset", ReadWangset); - } - - private Wangset ReadWangset(XmlReader reader) - { - // Attributes - var name = reader.GetRequiredAttribute("name"); - var @class = reader.GetOptionalAttribute("class") ?? ""; - var tile = reader.GetRequiredAttributeParseable("tile"); - - // Elements - Dictionary? properties = null; - List wangColors = []; - List wangTiles = []; - - reader.ProcessChildren("wangset", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - "wangcolor" => () => wangColors.Add(ReadWangColor(r)), - "wangtile" => () => wangTiles.Add(ReadWangTile(r)), - _ => r.Skip - }); - - if (wangColors.Count > 254) - throw new ArgumentException("Wangset can have at most 254 Wang colors."); - - return new Wangset - { - Name = name, - Class = @class, - Tile = tile, - Properties = properties, - WangColors = wangColors, - WangTiles = wangTiles - }; - } - - private WangColor ReadWangColor(XmlReader reader) - { - // Attributes - var name = reader.GetRequiredAttribute("name"); - var @class = reader.GetOptionalAttribute("class") ?? ""; - var color = reader.GetRequiredAttributeParseable("color"); - var tile = reader.GetRequiredAttributeParseable("tile"); - var probability = reader.GetOptionalAttributeParseable("probability") ?? 0f; - - // Elements - Dictionary? properties = null; - - reader.ProcessChildren("wangcolor", (r, elementName) => elementName switch - { - "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), - _ => r.Skip - }); - - return new WangColor - { - Name = name, - Class = @class, - Color = color, - Tile = tile, - Probability = probability, - Properties = properties - }; - } - - private WangTile ReadWangTile(XmlReader reader) - { - // Attributes - var tileID = reader.GetRequiredAttributeParseable("tileid"); - var wangID = reader.GetRequiredAttributeParseable("wangid", s => - { - // Comma-separated list of indices (0-254) - var indices = s.Split(',').Select(i => byte.Parse(i)).ToArray(); - if (indices.Length > 8) - throw new ArgumentException("Wang ID can have at most 8 indices."); - return indices; - }); - - return new WangTile - { - TileID = tileID, - WangID = wangID - }; - } -} diff --git a/DotTiled/TmxSerializer/TmxSerializer.cs b/DotTiled/TmxSerializer/TmxSerializer.cs deleted file mode 100644 index 5f5c604..0000000 --- a/DotTiled/TmxSerializer/TmxSerializer.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.IO; -using System.Xml; - -namespace DotTiled; - -public partial class TmxSerializer -{ - private readonly Func _externalTilesetResolver; - private readonly Func _externalTemplateResolver; - - public TmxSerializer( - Func externalTilesetResolver, - Func externalTemplateResolver - ) - { - _externalTilesetResolver = externalTilesetResolver ?? throw new ArgumentNullException(nameof(externalTilesetResolver)); - _externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver)); - } - - public Map DeserializeMap(XmlReader reader) - { - reader.ReadToFollowing("map"); - return ReadMap(reader); - } - - public Map DeserializeMap(string xml) - { - using var stringReader = new StringReader(xml); - using var reader = XmlReader.Create(stringReader); - return DeserializeMap(reader); - } - - public Tileset DeserializeTileset(XmlReader reader) - { - reader.ReadToFollowing("tileset"); - return ReadTileset(reader); - } - - public Template DeserializeTemplate(XmlReader reader) - { - reader.ReadToFollowing("template"); - return ReadTemplate(reader); - } -}