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/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..e9ad8be 100644 --- a/DotTiled.Tests/Assert/AssertMap.cs +++ b/DotTiled.Tests/Assert/AssertMap.cs @@ -1,39 +1,104 @@ +using System.Collections; +using System.Numerics; + 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) == 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; + 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; + } + + 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}'"); + } + 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..6c586bb 100644 --- a/DotTiled.Tests/Assert/AssertObject.cs +++ b/DotTiled.Tests/Assert/AssertObject.cs @@ -5,19 +5,20 @@ 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.Visible, actual.Visible, nameof(Object.Visible)); + 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); } @@ -38,29 +39,35 @@ 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)); + } + + private static void AssertObject(TileObject expected, TileObject actual) + { + // Attributes + AssertEqual(expected.GID, actual.GID, nameof(TileObject.GID)); } } 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.cs b/DotTiled.Tests/Serialization/TestData.cs index d31956f..c3d52f8 100644 --- a/DotTiled.Tests/Serialization/TestData.cs +++ b/DotTiled.Tests/Serialization/TestData.cs @@ -6,7 +6,7 @@ public static partial class TestData { public static XmlReader GetXmlReaderFor(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"); @@ -18,11 +18,62 @@ 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"); using var stringReader = new StreamReader(stream); return stringReader.ReadToEnd(); } + + private static string ConvertPathToAssemblyResourcePath(string path) => + path.Replace("/", ".").Replace("\\", ".").Replace(" ", "_"); + + public static IEnumerable MapTests => + [ + ["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()], + ["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 = [ + 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/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/empty-map.cs b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs similarity index 69% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map.cs rename to DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs index b51aeba..eff73d9 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map.cs +++ b/DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.cs @@ -2,17 +2,25 @@ namespace DotTiled.Tests; public partial class TestData { - public static Map EmptyMapWithEncodingAndCompression(DataEncoding dataEncoding, DataCompression? compression) => new Map + public static Map DefaultMap() => new Map { - Version = "1.10", - TiledVersion = "1.11.0", + Class = "", Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, 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 = [ @@ -24,14 +32,15 @@ public partial class TestData Height = 5, Data = new Data { - Encoding = dataEncoding, - Compression = compression, + 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 + 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, 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/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/empty-map-base64.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj similarity index 64% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmj rename to DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj index b13707c..da37182 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmj +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmj @@ -3,9 +3,11 @@ "infinite":false, "layers":[ { - "compression":"", - "data":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "encoding":"base64", + "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", @@ -22,7 +24,11 @@ "renderorder":"right-down", "tiledversion":"1.11.0", "tileheight":32, - "tilesets":[], + "tilesets":[ + { + "firstgid":1, + "source":"multi-tileset.tsj" + }], "tilewidth":32, "type":"map", "version":"1.10", diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx similarity index 66% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx rename to DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx index d3e0f29..477c112 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmx +++ b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/map-external-tileset-multi.tmx @@ -1,8 +1,13 @@ + - - H4sIAAAAAAAACmNgoD0AAMrGiJlkAAAA - + +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 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-multi/tileset.png differ 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 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-external-tileset-wangset/tileset.png differ 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.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/empty-map-properties.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj similarity index 65% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmj rename to DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj index 237546d..c7182ef 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmj +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-common-props/map-with-common-props.tmj @@ -1,4 +1,5 @@ -{ "compressionlevel":-1, +{ "backgroundcolor":"#00ff00", + "compressionlevel":-1, "height":5, "infinite":false, "layers":[ @@ -20,47 +21,47 @@ }], "nextlayerid":2, "nextobjectid":1, - "orientation":"orthogonal", + "orientation":"isometric", "properties":[ { - "name":"MapBool", + "name":"boolprop", "type":"bool", "value":true }, { - "name":"MapColor", + "name":"colorprop", "type":"color", - "value":"#ffff0000" + "value":"#ff55ffff" }, { - "name":"MapFile", + "name":"fileprop", "type":"file", - "value":"file.png" + "value":"file.txt" }, { - "name":"MapFloat", + "name":"floatprop", "type":"float", - "value":5.2 + "value":4.2 }, { - "name":"MapInt", + "name":"intprop", "type":"int", - "value":42 + "value":8 }, { - "name":"MapObject", + "name":"objectprop", "type":"object", "value":5 }, { - "name":"MapString", + "name":"stringprop", "type":"string", - "value":"string in map" + "value":"This is a string, hello world!" }], "renderorder":"right-down", "tiledversion":"1.11.0", - "tileheight":32, + "tileheight":16, "tilesets":[], "tilewidth":32, "type":"map", 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 + + + 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/empty-map-properties.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx similarity index 50% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmx rename to DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx index 5a14d94..c364577 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.tmx +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-custom-type-props/map-with-custom-type-props.tmx @@ -1,13 +1,13 @@ - - - - - - - + + + + + + + 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/TestData/Map/simple-tileset-embed.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs similarity index 68% rename from DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.cs rename to DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs index d6a5f10..fb3c95f 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.cs +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.cs @@ -1,35 +1,45 @@ +using System.Globalization; + namespace DotTiled.Tests; public partial class TestData { - public static Map SimpleMapWithEmbeddedTileset() => new Map + public static Map MapWithEmbeddedTileset() => new Map { - Version = "1.10", - TiledVersion = "1.11.0", + Class = "", Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, 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 1", + Name = "tileset", TileWidth = 32, TileHeight = 32, - TileCount = 8, - Columns = 4, + TileCount = 24, + Columns = 8, Image = new Image { Format = ImageFormat.Png, - Source = "tiles.png", - Width = 128, - Height = 64 + Source = "tileset.png", + Width = 256, + Height = 96, } } ], @@ -43,13 +53,14 @@ public partial class TestData Data = new Data { Encoding = DataEncoding.Csv, + Chunks = null, 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 + 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, @@ -58,7 +69,7 @@ public partial class TestData 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/map-with-embedded-tileset/map-with-embedded-tileset.tmj similarity index 64% rename from DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmj rename to DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmj index fa5a4ef..41d5e7b 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmj +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmj @@ -3,11 +3,11 @@ "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], + "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", @@ -26,15 +26,15 @@ "tileheight":32, "tilesets":[ { - "columns":4, + "columns":8, "firstgid":1, - "image":"tiles.png", - "imageheight":64, - "imagewidth":128, + "image":"tileset.png", + "imageheight":96, + "imagewidth":256, "margin":0, - "name":"Tileset 1", + "name":"tileset", "spacing":0, - "tilecount":8, + "tilecount":24, "tileheight":32, "tilewidth":32 }], diff --git a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx similarity index 60% rename from DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx rename to DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx index 3d91b9d..43ca51c 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/simple-tileset-embed.tmx +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/map-with-embedded-tileset.tmx @@ -1,15 +1,15 @@ - - + + -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 +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 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-with-embedded-tileset/tileset.png differ diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs similarity index 54% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs rename to DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs index 79df5a5..10c4d67 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-properties.cs +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.cs @@ -1,20 +1,51 @@ +using System.Globalization; + namespace DotTiled.Tests; public partial class TestData { - public static Map EmptyMapWithProperties() => new Map + public static Map MapWithExternalTileset(string fileExt) => new Map { - Version = "1.10", - TiledVersion = "1.11.0", + Class = "", Orientation = MapOrientation.Orthogonal, - RenderOrder = RenderOrder.RightDown, 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 { @@ -25,12 +56,14 @@ public partial class TestData 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 + 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, @@ -41,16 +74,6 @@ public partial class TestData ] } } - ], - 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-base64-zlib.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj similarity index 64% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmj rename to DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj index 4cf9e84..89bef93 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmj +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmj @@ -3,9 +3,11 @@ "infinite":false, "layers":[ { - "compression":"zlib", - "data":"eJxjYKA9AAAAZAAB", - "encoding":"base64", + "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", @@ -22,7 +24,11 @@ "renderorder":"right-down", "tiledversion":"1.11.0", "tileheight":32, - "tilesets":[], + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }], "tilewidth":32, "type":"map", "version":"1.10", diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx similarity index 67% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx rename to DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx index d35b438..06114fb 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-zlib.tmx +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/map-with-external-tileset.tmx @@ -1,8 +1,13 @@ + - - eJxjYKA9AAAAZAAB - + +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 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-with-external-tileset/tileset.png differ 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/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/empty-map-base64-gzip.tmj b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj similarity index 57% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmj rename to DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj index de94421..3b74128 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64-gzip.tmj +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmj @@ -3,9 +3,11 @@ "infinite":false, "layers":[ { - "compression":"gzip", - "data":"H4sIAAAAAAAACmNgoD0AAMrGiJlkAAAA", - "encoding":"base64", + "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", @@ -22,7 +24,11 @@ "renderorder":"right-down", "tiledversion":"1.11.0", "tileheight":32, - "tilesets":[], + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }], "tilewidth":32, "type":"map", "version":"1.10", diff --git a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx similarity index 55% rename from DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx rename to DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx index 0e98f67..a72cd1a 100644 --- a/DotTiled.Tests/Serialization/TestData/Map/empty-map-base64.tmx +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/map-with-flippingflags.tmx @@ -1,8 +1,13 @@ + - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== - + +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 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-with-flippingflags/tileset.png differ 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 @@ + + + + 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-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..2ef98d0 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.cs @@ -0,0 +1,219 @@ +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) + ], + Template = fileExt == "tmx" ? "poly.tx" : "poly.tj", + Properties = new Dictionary + { + ["templateprop"] = new StringProperty { Name = "templateprop", Value = "helo there" } + } + }, + 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..9e9f669 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmj @@ -0,0 +1,163 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "id":2, + "layers":[ + { + "draworder":"topdown", + "id":3, + "name":"Objects", + "objects":[ + { + "height":31.3333, + "id":1, + "name":"Object 1", + "rotation":0, + "type":"", + "visible":true, + "width":31.3333, + "x":25.6667, + "y":28.6667 + }, + { + "height":0, + "id":3, + "name":"P1", + "point":true, + "rotation":0, + "type":"", + "visible":true, + "width":0, + "x":117.667, + "y":48.6667 + }, + { + "ellipse":true, + "height":34.6667, + "id":4, + "name":"Circle1", + "rotation":0, + "type":"", + "visible":true, + "width":34.6667, + "x":77, + "y":72.3333 + }, + { + "id":5, + "template":"poly.tj", + "x":20.6667, + "y":114.667 + }, + { + "gid":7, + "height":146, + "id":6, + "name":"TileObj", + "rotation":0, + "type":"", + "visible":true, + "width":64, + "x":-35, + "y":110.333 + }], + "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..5888069 --- /dev/null +++ b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/map-with-many-layers.tmx @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + +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/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.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 0000000..97c1fb3 Binary files /dev/null and b/DotTiled.Tests/Serialization/TestData/Map/map-with-many-layers/tileset.png differ 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.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/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..670fdf6 100644 --- a/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs @@ -2,96 +2,27 @@ 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()], - ]; - + public static IEnumerable Maps => TestData.MapTests; [Theory] - [MemberData(nameof(DeserializeMap_ValidTmjNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void TmxMapReaderReadMap_ValidTmjNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) + [MemberData(nameof(Maps))] + public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( + string testDataFile, + Func expectedMap, + IReadOnlyCollection customTypeDefinitions) { // 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()], - ]; - - [Theory] - [MemberData(nameof(DeserializeMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_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 = [] - } - ] - } - ]; - + 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(); } @@ -102,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 3556893..a99ee9a 100644 --- a/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs +++ b/DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs @@ -4,138 +4,27 @@ 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()], - ]; - + public static IEnumerable Maps => TestData.MapTests; [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))] - public void TmxMapReaderReadMap_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) + [MemberData(nameof(Maps))] + public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected( + string testDataFile, + Func 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"; + 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(); } @@ -146,74 +35,6 @@ public partial class TmxMapReaderTests // 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()], - ]; - - [Theory] - [MemberData(nameof(DeserializeMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected_Data))] - public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_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); + DotTiledAssert.AssertMap(expectedMap("tmx"), map); } } 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}"; } 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/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/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 + }; +} 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/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/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/Tmj/Tmj.Tileset.cs b/DotTiled/Serialization/Tmj/Tmj.Tileset.cs index fd5088b..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) { @@ -77,14 +78,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 { @@ -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 }; } @@ -159,7 +177,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", ""); @@ -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.ObjectLayer.cs b/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs index 2367974..4d70b91 100644 --- a/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs +++ b/DotTiled/Serialization/Tmx/Tmx.ObjectLayer.cs @@ -78,37 +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; - gidDefault = templObj.GID; - 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; @@ -122,40 +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 (obj is null) + if (foundObject is null) { - obj = new RectangleObject { ID = id }; - reader.Skip(); + if (gid is not null) + foundObject = new TileObject { ID = id, GID = gid.Value }; + else + foundObject = new RectangleObject { ID = id }; } - 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; + 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 obj; + return OverrideObject(obj, foundObject); + } + + internal static Object OverrideObject(Object? obj, Object foundObject) + { + if (obj is null) + return foundObject; + + if (obj.GetType() != foundObject.GetType()) + { + 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; + } + + return OverrideObject((dynamic)obj, (dynamic)foundObject); } internal static EllipseObject ReadEllipseObject(XmlReader reader) @@ -164,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 @@ -188,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 @@ -206,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 @@ -254,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, 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; diff --git a/DotTiled/Serialization/Tmx/Tmx.Tileset.cs b/DotTiled/Serialization/Tmx/Tmx.Tileset.cs index 3885dac..1912df2 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; } @@ -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,