mirror of
https://github.com/dcronqvist/DotTiled.git
synced 2025-02-05 08:52:50 +02:00
commit
0cf564ce46
131 changed files with 5158 additions and 1032 deletions
20
DotTiled.Benchmark/DotTiled.Benchmark.csproj
Normal file
20
DotTiled.Benchmark/DotTiled.Benchmark.csproj
Normal file
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
|
||||
<PackageReference Include="TiledCSPlus" Version="4.2.0" />
|
||||
<PackageReference Include="TiledLib" Version="4.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DotTiled\DotTiled.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
94
DotTiled.Benchmark/Program.cs
Normal file
94
DotTiled.Benchmark/Program.cs
Normal file
|
@ -0,0 +1,94 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Columns;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Order;
|
||||
using BenchmarkDotNet.Reports;
|
||||
using BenchmarkDotNet.Running;
|
||||
|
||||
namespace MyBenchmarks
|
||||
{
|
||||
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
|
||||
[CategoriesColumn]
|
||||
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
|
||||
[HideColumns(["StdDev", "Error", "RatioSD"])]
|
||||
public class MapLoading
|
||||
{
|
||||
private string _tmxPath = @"DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.tmx";
|
||||
private string _tmxContents = "";
|
||||
|
||||
private string _tmjPath = @"DotTiled.Tests/Serialization/TestData/Map/default-map/default-map.tmj";
|
||||
private string _tmjContents = "";
|
||||
|
||||
public MapLoading()
|
||||
{
|
||||
var basePath = Path.GetDirectoryName(WhereAmI())!;
|
||||
var tmxPath = Path.Combine(basePath, $"../{_tmxPath}");
|
||||
var tmjPath = Path.Combine(basePath, $"../{_tmjPath}");
|
||||
|
||||
_tmxContents = System.IO.File.ReadAllText(tmxPath);
|
||||
_tmjContents = System.IO.File.ReadAllText(tmjPath);
|
||||
}
|
||||
|
||||
static string WhereAmI([CallerFilePath] string callerFilePath = "") => callerFilePath;
|
||||
|
||||
[BenchmarkCategory("MapFromInMemoryTmxString")]
|
||||
[Benchmark(Baseline = true, Description = "DotTiled")]
|
||||
public DotTiled.Map LoadWithDotTiledFromInMemoryTmxString()
|
||||
{
|
||||
using var stringReader = new StringReader(_tmxContents);
|
||||
using var xmlReader = XmlReader.Create(stringReader);
|
||||
using var mapReader = new DotTiled.TmxMapReader(xmlReader, _ => throw new Exception(), _ => throw new Exception(), []);
|
||||
return mapReader.ReadMap();
|
||||
}
|
||||
|
||||
[BenchmarkCategory("MapFromInMemoryTmjString")]
|
||||
[Benchmark(Baseline = true, Description = "DotTiled")]
|
||||
public DotTiled.Map LoadWithDotTiledFromInMemoryTmjString()
|
||||
{
|
||||
using var mapReader = new DotTiled.TmjMapReader(_tmjContents, _ => throw new Exception(), _ => throw new Exception(), []);
|
||||
return mapReader.ReadMap();
|
||||
}
|
||||
|
||||
[BenchmarkCategory("MapFromInMemoryTmxString")]
|
||||
[Benchmark(Description = "TiledLib")]
|
||||
public TiledLib.Map LoadWithTiledLibFromInMemoryTmxString()
|
||||
{
|
||||
using var memStream = new MemoryStream(Encoding.UTF8.GetBytes(_tmxContents));
|
||||
return TiledLib.Map.FromStream(memStream);
|
||||
}
|
||||
|
||||
[BenchmarkCategory("MapFromInMemoryTmjString")]
|
||||
[Benchmark(Description = "TiledLib")]
|
||||
public TiledLib.Map LoadWithTiledLibFromInMemoryTmjString()
|
||||
{
|
||||
using var memStream = new MemoryStream(Encoding.UTF8.GetBytes(_tmjContents));
|
||||
return TiledLib.Map.FromStream(memStream);
|
||||
}
|
||||
|
||||
[BenchmarkCategory("MapFromInMemoryTmxString")]
|
||||
[Benchmark(Description = "TiledCSPlus")]
|
||||
public TiledCSPlus.TiledMap LoadWithTiledCSPlusFromInMemoryTmxString()
|
||||
{
|
||||
using var memStream = new MemoryStream(Encoding.UTF8.GetBytes(_tmxContents));
|
||||
return new TiledCSPlus.TiledMap(memStream);
|
||||
}
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var config = BenchmarkDotNet.Configs.DefaultConfig.Instance
|
||||
.WithArtifactsPath(args[0])
|
||||
.WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
.AddDiagnoser(BenchmarkDotNet.Diagnosers.MemoryDiagnoser.Default);
|
||||
var summary = BenchmarkRunner.Run<MapLoading>(config);
|
||||
}
|
||||
}
|
||||
}
|
43
DotTiled.Tests/Assert/AssertData.cs
Normal file
43
DotTiled.Tests/Assert/AssertData.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertData(Data? expected, Data? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
AssertEqual(expected.Encoding, actual.Encoding, nameof(Data.Encoding));
|
||||
AssertEqual(expected.Compression, actual.Compression, nameof(Data.Compression));
|
||||
|
||||
// Data
|
||||
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);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertChunk(Chunk expected, Chunk actual)
|
||||
{
|
||||
// Attributes
|
||||
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
|
||||
AssertEqual(expected.GlobalTileIDs, actual.GlobalTileIDs, nameof(Chunk.GlobalTileIDs));
|
||||
AssertEqual(expected.FlippingFlags, actual.FlippingFlags, nameof(Chunk.FlippingFlags));
|
||||
}
|
||||
}
|
21
DotTiled.Tests/Assert/AssertImage.cs
Normal file
21
DotTiled.Tests/Assert/AssertImage.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertImage(Image? expected, Image? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
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));
|
||||
}
|
||||
}
|
75
DotTiled.Tests/Assert/AssertLayer.cs
Normal file
75
DotTiled.Tests/Assert/AssertLayer.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertLayer(BaseLayer? expected, BaseLayer? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
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);
|
||||
}
|
||||
|
||||
private static void AssertLayer(TileLayer expected, TileLayer actual)
|
||||
{
|
||||
// Attributes
|
||||
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);
|
||||
}
|
||||
|
||||
private static void AssertLayer(ObjectLayer expected, ObjectLayer actual)
|
||||
{
|
||||
// Attributes
|
||||
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);
|
||||
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]);
|
||||
}
|
||||
|
||||
private static void AssertLayer(ImageLayer expected, ImageLayer actual)
|
||||
{
|
||||
// Attributes
|
||||
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);
|
||||
}
|
||||
|
||||
private static void AssertLayer(Group expected, Group actual)
|
||||
{
|
||||
// Attributes
|
||||
Assert.NotNull(actual.Layers);
|
||||
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]);
|
||||
}
|
||||
}
|
105
DotTiled.Tests/Assert/AssertMap.cs
Normal file
105
DotTiled.Tests/Assert/AssertMap.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
using System.Collections;
|
||||
using System.Numerics;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
private static void AssertEqual<T>(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
|
||||
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);
|
||||
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);
|
||||
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]);
|
||||
}
|
||||
}
|
73
DotTiled.Tests/Assert/AssertObject.cs
Normal file
73
DotTiled.Tests/Assert/AssertObject.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertObject(Object expected, Object actual)
|
||||
{
|
||||
// Attributes
|
||||
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);
|
||||
}
|
||||
|
||||
private static void AssertObject(RectangleObject expected, RectangleObject actual)
|
||||
{
|
||||
Assert.True(true); // A rectangle object is the same as the abstract Object
|
||||
}
|
||||
|
||||
private static void AssertObject(EllipseObject expected, EllipseObject actual)
|
||||
{
|
||||
Assert.True(true); // An ellipse object is the same as the abstract Object
|
||||
}
|
||||
|
||||
private static void AssertObject(PointObject expected, PointObject actual)
|
||||
{
|
||||
Assert.True(true); // A point object is the same as the abstract Object
|
||||
}
|
||||
|
||||
private static void AssertObject(PolygonObject expected, PolygonObject actual)
|
||||
{
|
||||
AssertEqual(expected.Points, actual.Points, nameof(PolygonObject.Points));
|
||||
}
|
||||
|
||||
private static void AssertObject(PolylineObject expected, PolylineObject actual)
|
||||
{
|
||||
AssertEqual(expected.Points, actual.Points, nameof(PolylineObject.Points));
|
||||
}
|
||||
|
||||
private static void AssertObject(TextObject expected, TextObject actual)
|
||||
{
|
||||
// Attributes
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
69
DotTiled.Tests/Assert/AssertProperties.cs
Normal file
69
DotTiled.Tests/Assert/AssertProperties.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertProperties(Dictionary<string, IProperty>? expected, Dictionary<string, IProperty>? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.NotNull(actual);
|
||||
AssertEqual(expected.Count, actual.Count, "Properties.Count");
|
||||
foreach (var kvp in expected)
|
||||
{
|
||||
Assert.Contains(kvp.Key, actual.Keys);
|
||||
AssertProperty((dynamic)kvp.Value, (dynamic)actual[kvp.Key]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertProperty(IProperty expected, IProperty actual)
|
||||
{
|
||||
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)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "StringProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(IntProperty expected, IntProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "IntProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(FloatProperty expected, FloatProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "FloatProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(BoolProperty expected, BoolProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "BoolProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(ColorProperty expected, ColorProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "ColorProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(FileProperty expected, FileProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "FileProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(ObjectProperty expected, ObjectProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Value, actual.Value, "ObjectProperty.Value");
|
||||
}
|
||||
|
||||
private static void AssertProperty(ClassProperty expected, ClassProperty actual)
|
||||
{
|
||||
AssertEqual(expected.PropertyType, actual.PropertyType, "ClassProperty.PropertyType");
|
||||
AssertProperties(expected.Properties, actual.Properties);
|
||||
}
|
||||
}
|
160
DotTiled.Tests/Assert/AssertTileset.cs
Normal file
160
DotTiled.Tests/Assert/AssertTileset.cs
Normal file
|
@ -0,0 +1,160 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertTileset(Tileset expected, Tileset actual)
|
||||
{
|
||||
// Attributes
|
||||
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);
|
||||
AssertTileOffset(expected.TileOffset, actual.TileOffset);
|
||||
AssertGrid(expected.Grid, actual.Grid);
|
||||
AssertProperties(expected.Properties, actual.Properties);
|
||||
// TODO: AssertTerrainTypes(actual.TerrainTypes, expected.TerrainTypes);
|
||||
if (expected.Wangsets is not null)
|
||||
{
|
||||
Assert.NotNull(actual.Wangsets);
|
||||
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]);
|
||||
}
|
||||
AssertTransformations(expected.Transformations, actual.Transformations);
|
||||
|
||||
// Any number of
|
||||
Assert.NotNull(actual.Tiles);
|
||||
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]);
|
||||
}
|
||||
|
||||
private static void AssertTileOffset(TileOffset? expected, TileOffset? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
AssertEqual(expected.X, actual.X, nameof(TileOffset.X));
|
||||
AssertEqual(expected.Y, actual.Y, nameof(TileOffset.Y));
|
||||
}
|
||||
|
||||
private static void AssertGrid(Grid? expected, Grid? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
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
|
||||
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);
|
||||
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]);
|
||||
}
|
||||
for (var i = 0; i < expected.WangTiles.Count; i++)
|
||||
AssertWangTile(expected.WangTiles[i], actual.WangTiles[i]);
|
||||
}
|
||||
|
||||
private static void AssertWangColor(WangColor expected, WangColor actual)
|
||||
{
|
||||
// Attributes
|
||||
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);
|
||||
}
|
||||
|
||||
private static void AssertWangTile(WangTile expected, WangTile actual)
|
||||
{
|
||||
// Attributes
|
||||
AssertEqual(expected.TileID, actual.TileID, nameof(WangTile.TileID));
|
||||
AssertEqual(expected.WangID, actual.WangID, nameof(WangTile.WangID));
|
||||
}
|
||||
|
||||
private static void AssertTransformations(Transformations? expected, Transformations? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
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
|
||||
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);
|
||||
AssertImage(actual.Image, expected.Image);
|
||||
AssertLayer((BaseLayer?)actual.ObjectLayer, (BaseLayer?)expected.ObjectLayer);
|
||||
if (expected.Animation is not null)
|
||||
{
|
||||
Assert.NotNull(actual.Animation);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertFrame(Frame expected, Frame actual)
|
||||
{
|
||||
// Attributes
|
||||
AssertEqual(expected.TileID, actual.TileID, nameof(Frame.TileID));
|
||||
AssertEqual(expected.Duration, actual.Duration, nameof(Frame.Duration));
|
||||
}
|
||||
}
|
|
@ -25,8 +25,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- TmxSerializer test data -->
|
||||
<EmbeddedResource Include="TmxSerializer/TestData/**/*.tmx" />
|
||||
<!-- Test data -->
|
||||
<EmbeddedResource Include="Serialization/TestData/**/*" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
79
DotTiled.Tests/Serialization/TestData.cs
Normal file
79
DotTiled.Tests/Serialization/TestData.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
using System.Xml;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class TestData
|
||||
{
|
||||
public static XmlReader GetXmlReaderFor(string 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);
|
||||
var xml = stringReader.ReadToEnd();
|
||||
var xmlStringReader = new StringReader(xml);
|
||||
return XmlReader.Create(xmlStringReader);
|
||||
}
|
||||
|
||||
public static string GetRawStringFor(string 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<object[]> MapTests =>
|
||||
[
|
||||
["Serialization/TestData/Map/default_map/default-map", (string f) => TestData.DefaultMap(), Array.Empty<CustomTypeDefinition>()],
|
||||
["Serialization/TestData/Map/map_with_common_props/map-with-common-props", (string f) => TestData.MapWithCommonProps(), Array.Empty<CustomTypeDefinition>()],
|
||||
["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<CustomTypeDefinition>()],
|
||||
["Serialization/TestData/Map/map_with_external_tileset/map-with-external-tileset", (string f) => TestData.MapWithExternalTileset(f), Array.Empty<CustomTypeDefinition>()],
|
||||
["Serialization/TestData/Map/map_with_flippingflags/map-with-flippingflags", (string f) => TestData.MapWithFlippingFlags(f), Array.Empty<CustomTypeDefinition>()],
|
||||
["Serialization/TestData/Map/map_external_tileset_multi/map-external-tileset-multi", (string f) => TestData.MapExternalTilesetMulti(f), Array.Empty<CustomTypeDefinition>()],
|
||||
["Serialization/TestData/Map/map_external_tileset_wangset/map-external-tileset-wangset", (string f) => TestData.MapExternalTilesetWangset(f), Array.Empty<CustomTypeDefinition>()],
|
||||
["Serialization/TestData/Map/map_with_many_layers/map-with-many-layers", (string f) => TestData.MapWithManyLayers(f), Array.Empty<CustomTypeDefinition>()],
|
||||
];
|
||||
|
||||
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 = []
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
|
@ -1,37 +1,28 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerMapTests
|
||||
public partial class TestData
|
||||
{
|
||||
private static Map SimpleMapWithEmbeddedTileset() => 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,
|
||||
Tilesets = [
|
||||
new Tileset
|
||||
{
|
||||
FirstGID = 1,
|
||||
Name = "Tileset 1",
|
||||
TileWidth = 32,
|
||||
TileHeight = 32,
|
||||
TileCount = 8,
|
||||
Columns = 4,
|
||||
Image = new Image
|
||||
{
|
||||
Source = "tiles.png",
|
||||
Width = 128,
|
||||
Height = 64
|
||||
}
|
||||
}
|
||||
],
|
||||
Layers = [
|
||||
new TileLayer
|
||||
{
|
||||
|
@ -42,13 +33,14 @@ public partial class TmxSerializerMapTests
|
|||
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
|
||||
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,
|
||||
|
@ -57,7 +49,7 @@ public partial class TmxSerializerMapTests
|
|||
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
|
||||
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None
|
||||
]
|
||||
},
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
{ "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",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.0",
|
||||
"tileheight":32,
|
||||
"tilesets":[],
|
||||
"tilewidth":32,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":5
|
||||
}
|
|
@ -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<string, IProperty>
|
||||
{
|
||||
["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
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{ "compressionlevel":-1,
|
||||
"height":5,
|
||||
"infinite":false,
|
||||
"layers":[
|
||||
{
|
||||
"data":[0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 2, 0, 0, 0],
|
||||
"height":5,
|
||||
"id":1,
|
||||
"name":"Tile Layer 1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":5,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":2,
|
||||
"nextobjectid":1,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.0",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"multi-tileset.tsj"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":5
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="multi-tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="base64" compression="zlib">
|
||||
eJxjYKA9AAAAZAAB
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.11.0" name="multi-tileset" tilewidth="256" tileheight="96" tilecount="2" columns="0">
|
||||
<tileoffset x="1" y="5"/>
|
||||
<grid orientation="orthogonal" width="1" height="1"/>
|
||||
<properties>
|
||||
<property name="tilesetbool" type="bool" value="true"/>
|
||||
<property name="tilesetcolor" type="color" value="#ffff0000"/>
|
||||
<property name="tilesetfile" type="file" value=""/>
|
||||
<property name="tilesetfloat" type="float" value="5.2"/>
|
||||
<property name="tilesetint" type="int" value="9"/>
|
||||
<property name="tilesetobject" type="object" value="0"/>
|
||||
<property name="tilesetstring" value="hello world!"/>
|
||||
</properties>
|
||||
<tile id="0">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</tile>
|
||||
<tile id="1">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</tile>
|
||||
</tileset>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="24" tileheight="24" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="wangset-tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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]
|
||||
}]
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.11.0" name="tileset" tilewidth="24" tileheight="24" tilecount="48" columns="10">
|
||||
<grid orientation="orthogonal" width="32" height="32"/>
|
||||
<transformations hflip="1" vflip="1" rotate="0" preferuntransformed="0"/>
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
<wangsets>
|
||||
<wangset name="test-terrain" type="mixed" tile="-1">
|
||||
<wangcolor name="Water" color="#ff0000" tile="0" probability="1"/>
|
||||
<wangcolor name="Grass" color="#00ff00" tile="-1" probability="1"/>
|
||||
<wangcolor name="Stone" color="#0000ff" tile="29" probability="1"/>
|
||||
<wangtile tileid="0" wangid="1,1,0,0,0,1,1,1"/>
|
||||
<wangtile tileid="1" wangid="1,1,1,1,0,0,0,1"/>
|
||||
<wangtile tileid="10" wangid="0,0,0,1,1,1,1,1"/>
|
||||
<wangtile tileid="11" wangid="0,1,1,1,1,1,0,0"/>
|
||||
</wangset>
|
||||
</wangsets>
|
||||
</tileset>
|
|
@ -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<string, IProperty>
|
||||
{
|
||||
["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!" }
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
{ "backgroundcolor":"#00ff00",
|
||||
"compressionlevel":-1,
|
||||
"height":5,
|
||||
"infinite":false,
|
||||
"layers":[
|
||||
{
|
||||
"data":[0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0],
|
||||
"height":5,
|
||||
"id":1,
|
||||
"name":"Tile Layer 1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":5,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":2,
|
||||
"nextobjectid":1,
|
||||
"orientation":"isometric",
|
||||
"properties":[
|
||||
{
|
||||
"name":"boolprop",
|
||||
"type":"bool",
|
||||
"value":true
|
||||
},
|
||||
{
|
||||
"name":"colorprop",
|
||||
"type":"color",
|
||||
"value":"#ff55ffff"
|
||||
},
|
||||
{
|
||||
"name":"fileprop",
|
||||
"type":"file",
|
||||
"value":"file.txt"
|
||||
},
|
||||
{
|
||||
"name":"floatprop",
|
||||
"type":"float",
|
||||
"value":4.2
|
||||
},
|
||||
{
|
||||
"name":"intprop",
|
||||
"type":"int",
|
||||
"value":8
|
||||
},
|
||||
|
||||
{
|
||||
"name":"objectprop",
|
||||
"type":"object",
|
||||
"value":5
|
||||
},
|
||||
{
|
||||
"name":"stringprop",
|
||||
"type":"string",
|
||||
"value":"This is a string, hello world!"
|
||||
}],
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.0",
|
||||
"tileheight":16,
|
||||
"tilesets":[],
|
||||
"tilewidth":32,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":5
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="isometric" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="16" infinite="0" backgroundcolor="#00ff00" nextlayerid="2" nextobjectid="1">
|
||||
<properties>
|
||||
<property name="boolprop" type="bool" value="true"/>
|
||||
<property name="colorprop" type="color" value="#ff55ffff"/>
|
||||
<property name="fileprop" type="file" value="file.txt"/>
|
||||
<property name="floatprop" type="float" value="4.2"/>
|
||||
<property name="intprop" type="int" value="8"/>
|
||||
<property name="objectprop" type="object" value="5"/>
|
||||
<property name="stringprop" value="This is a string, hello world!"/>
|
||||
</properties>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
|
@ -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<string, IProperty>
|
||||
{
|
||||
["customclassprop"] = new ClassProperty
|
||||
{
|
||||
Name = "customclassprop",
|
||||
PropertyType = "CustomClass",
|
||||
Properties = new Dictionary<string, IProperty>
|
||||
{
|
||||
["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<CustomTypeDefinition> 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 = ""
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<properties>
|
||||
<property name="MapBool" type="bool" value="true"/>
|
||||
<property name="MapColor" type="color" value="#ffff0000"/>
|
||||
<property name="MapFile" type="file" value="file.png"/>
|
||||
<property name="MapFloat" type="float" value="5.2"/>
|
||||
<property name="MapInt" type="int" value="42"/>
|
||||
<property name="MapObject" type="object" value="5"/>
|
||||
<property name="MapString" value="string in map"/>
|
||||
<property name="customclassprop" type="class" propertytype="CustomClass">
|
||||
<properties>
|
||||
<property name="boolinclass" type="bool" value="true"/>
|
||||
<property name="floatinclass" type="float" value="13.37"/>
|
||||
<property name="stringinclass" value="This is a set string"/>
|
||||
</properties>
|
||||
</property>
|
||||
</properties>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,20 +1,48 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerMapTests
|
||||
public partial class TestData
|
||||
{
|
||||
private static Map EmptyMapWithProperties() => 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",
|
||||
TileWidth = 32,
|
||||
TileHeight = 32,
|
||||
TileCount = 24,
|
||||
Columns = 8,
|
||||
Image = new Image
|
||||
{
|
||||
Format = ImageFormat.Png,
|
||||
Source = "tileset.png",
|
||||
Width = 256,
|
||||
Height = 96,
|
||||
}
|
||||
}
|
||||
],
|
||||
Layers = [
|
||||
new TileLayer
|
||||
{
|
||||
|
@ -25,12 +53,14 @@ public partial class TmxSerializerMapTests
|
|||
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, 0, 0, 7,
|
||||
9, 10, 0, 0, 7,
|
||||
17, 18, 0, 0, 0
|
||||
],
|
||||
FlippingFlags = [
|
||||
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
|
||||
|
@ -41,16 +71,6 @@ public partial class TmxSerializerMapTests
|
|||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
Properties = new Dictionary<string, IProperty>
|
||||
{
|
||||
["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" }
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{ "compressionlevel":-1,
|
||||
"height":5,
|
||||
"infinite":false,
|
||||
"layers":[
|
||||
{
|
||||
"data":[1, 1, 0, 0, 7,
|
||||
1, 1, 0, 0, 7,
|
||||
0, 0, 0, 0, 7,
|
||||
9, 10, 0, 0, 7,
|
||||
17, 18, 0, 0, 0],
|
||||
"height":5,
|
||||
"id":1,
|
||||
"name":"Tile Layer 1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":5,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":2,
|
||||
"nextobjectid":1,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.0",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"columns":8,
|
||||
"firstgid":1,
|
||||
"image":"tileset.png",
|
||||
"imageheight":96,
|
||||
"imagewidth":256,
|
||||
"margin":0,
|
||||
"name":"tileset",
|
||||
"spacing":0,
|
||||
"tilecount":24,
|
||||
"tileheight":32,
|
||||
"tilewidth":32
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":5
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" name="Tileset 1" tilewidth="32" tileheight="32" tilecount="8" columns="4">
|
||||
<image source="tiles.png" width="128" height="64"/>
|
||||
<tileset firstgid="1" name="tileset" tilewidth="32" tileheight="32" tilecount="24" columns="8">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</tileset>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -1,20 +1,51 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerMapTests
|
||||
public partial class TestData
|
||||
{
|
||||
private static Map EmptyMapWithEncodingAndCompression(DataEncoding dataEncoding, DataCompression? compression) => 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
|
||||
{
|
||||
|
@ -24,14 +55,15 @@ public partial class TmxSerializerMapTests
|
|||
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
|
||||
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,
|
|
@ -0,0 +1,36 @@
|
|||
{ "compressionlevel":-1,
|
||||
"height":5,
|
||||
"infinite":false,
|
||||
"layers":[
|
||||
{
|
||||
"data":[1, 1, 0, 0, 7,
|
||||
1, 1, 0, 0, 7,
|
||||
0, 0, 1, 0, 7,
|
||||
0, 0, 0, 1, 7,
|
||||
21, 21, 21, 21, 1],
|
||||
"height":5,
|
||||
"id":1,
|
||||
"name":"Tile Layer 1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":5,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":2,
|
||||
"nextobjectid":1,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.0",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"tileset.tsj"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":5
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="base64" compression="gzip">
|
||||
H4sIAAAAAAAACmNgoD0AAMrGiJlkAAAA
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.11.0" name="tileset" tilewidth="32" tileheight="32" tilecount="24" columns="8">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</tileset>
|
|
@ -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
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{ "compressionlevel":-1,
|
||||
"height":5,
|
||||
"infinite":false,
|
||||
"layers":[
|
||||
{
|
||||
"data":[1, 2684354561, 0, 0, 1073741831,
|
||||
1610612737, 3221225473, 0, 0, 1073741831,
|
||||
0, 0, 1, 0, 1073741831,
|
||||
0, 0, 0, 1, 1073741831,
|
||||
2147483669, 2147483669, 2147483669, 2147483669, 1],
|
||||
"height":5,
|
||||
"id":1,
|
||||
"name":"Tile Layer 1",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":5,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":2,
|
||||
"nextobjectid":1,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.0",
|
||||
"tileheight":32,
|
||||
"tilesets":[
|
||||
{
|
||||
"firstgid":1,
|
||||
"source":"tileset.tsj"
|
||||
}],
|
||||
"tilewidth":32,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":5
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="base64">
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.11.0" name="tileset" tilewidth="32" tileheight="32" tilecount="24" columns="8">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</tileset>
|
|
@ -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<string, IProperty>
|
||||
{
|
||||
["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
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="8" nextobjectid="7">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<group id="2" name="Root">
|
||||
<objectgroup id="3" name="Objects">
|
||||
<object id="1" name="Object 1" x="25.6667" y="28.6667" width="31.3333" height="31.3333"/>
|
||||
<object id="3" name="P1" x="117.667" y="48.6667">
|
||||
<point/>
|
||||
</object>
|
||||
<object id="4" name="Circle1" x="77" y="72.3333" width="34.6667" height="34.6667">
|
||||
<ellipse/>
|
||||
</object>
|
||||
<object id="5" template="poly.tx" x="20.6667" y="114.667"/>
|
||||
<object id="6" name="TileObj" gid="7" x="-35" y="110.333" width="64" height="146"/>
|
||||
</objectgroup>
|
||||
<group id="5" name="Sub">
|
||||
<layer id="7" name="Tile 3" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
<layer id="6" name="Tile 2" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</group>
|
||||
<imagelayer id="4" name="ImageLayer" repeatx="1">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</imagelayer>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
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
|
||||
</data>
|
||||
</layer>
|
||||
</group>
|
||||
</map>
|
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<template>
|
||||
<object name="Poly">
|
||||
<properties>
|
||||
<property name="templateprop" value="helo there"/>
|
||||
</properties>
|
||||
<polygon points="0,0 104,20 35.6667,32.3333"/>
|
||||
</object>
|
||||
</template>
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -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"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.11.0" name="tileset" tilewidth="32" tileheight="32" tilecount="24" columns="8">
|
||||
<image source="tileset.png" width="256" height="96"/>
|
||||
</tileset>
|
38
DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs
Normal file
38
DotTiled.Tests/Serialization/Tmj/TmjMapReaderTests.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmjMapReaderTests
|
||||
{
|
||||
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
||||
[Theory]
|
||||
[MemberData(nameof(Maps))]
|
||||
public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
||||
string testDataFile,
|
||||
Func<string, Map> expectedMap,
|
||||
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
// Arrange
|
||||
testDataFile += ".tmj";
|
||||
var fileDir = Path.GetDirectoryName(testDataFile);
|
||||
var json = TestData.GetRawStringFor(testDataFile);
|
||||
Template ResolveTemplate(string 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($"{fileDir}/{source}");
|
||||
using var tilesetReader = new TsjTilesetReader(tilesetJson, ResolveTemplate, customTypeDefinitions);
|
||||
return tilesetReader.ReadTileset();
|
||||
}
|
||||
using var mapReader = new TmjMapReader(json, ResolveTileset, ResolveTemplate, customTypeDefinitions);
|
||||
|
||||
// Act
|
||||
var map = mapReader.ReadMap();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(map);
|
||||
DotTiledAssert.AssertMap(expectedMap("tmj"), map);
|
||||
}
|
||||
}
|
40
DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs
Normal file
40
DotTiled.Tests/Serialization/Tmx/TmxMapReaderTests.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System.Xml;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxMapReaderTests
|
||||
{
|
||||
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
||||
[Theory]
|
||||
[MemberData(nameof(Maps))]
|
||||
public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
||||
string testDataFile,
|
||||
Func<string, Map> expectedMap,
|
||||
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
// Arrange
|
||||
testDataFile += ".tmx";
|
||||
var fileDir = Path.GetDirectoryName(testDataFile);
|
||||
using var reader = TestData.GetXmlReaderFor(testDataFile);
|
||||
Template ResolveTemplate(string 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($"{fileDir}/{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("tmx"), map);
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System.Xml;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public static class TmxSerializerTestData
|
||||
{
|
||||
public static XmlReader GetReaderFor(string testDataFile)
|
||||
{
|
||||
var fullyQualifiedTestDataFile = $"DotTiled.Tests.{testDataFile}";
|
||||
using var stream = typeof(TmxSerializerTestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile)
|
||||
?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found");
|
||||
|
||||
using var stringReader = new StreamReader(stream);
|
||||
var xml = stringReader.ReadToEnd();
|
||||
var xmlStringReader = new StringReader(xml);
|
||||
return XmlReader.Create(xmlStringReader);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerDataTests
|
||||
{
|
||||
public static void AssertData(Data? actual, Data? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Encoding, actual.Encoding);
|
||||
Assert.Equal(expected.Compression, actual.Compression);
|
||||
|
||||
// Data
|
||||
Assert.Equal(expected.GlobalTileIDs, actual.GlobalTileIDs);
|
||||
Assert.Equal(expected.FlippingFlags, actual.FlippingFlags);
|
||||
|
||||
if (expected.Chunks is not null)
|
||||
{
|
||||
Assert.NotNull(actual.Chunks);
|
||||
Assert.Equal(expected.Chunks.Length, actual.Chunks.Length);
|
||||
for (var i = 0; i < expected.Chunks.Length; i++)
|
||||
AssertChunk(actual.Chunks[i], expected.Chunks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertChunk(Chunk actual, Chunk expected)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Data
|
||||
Assert.Equal(expected.GlobalTileIDs, actual.GlobalTileIDs);
|
||||
Assert.Equal(expected.FlippingFlags, actual.FlippingFlags);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerImageTests
|
||||
{
|
||||
public static void AssertImage(Image? actual, Image? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerLayerTests
|
||||
{
|
||||
public static void AssertLayer(BaseLayer? actual, BaseLayer? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.X, actual.X);
|
||||
Assert.Equal(expected.Y, actual.Y);
|
||||
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);
|
||||
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
AssertLayer((dynamic)actual, (dynamic)expected);
|
||||
}
|
||||
|
||||
private static void AssertLayer(TileLayer actual, TileLayer expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.Width, actual.Width);
|
||||
Assert.Equal(expected.Height, actual.Height);
|
||||
|
||||
Assert.NotNull(actual.Data);
|
||||
TmxSerializerDataTests.AssertData(actual.Data, expected.Data);
|
||||
}
|
||||
|
||||
private static void AssertLayer(ObjectLayer actual, ObjectLayer expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.DrawOrder, actual.DrawOrder);
|
||||
|
||||
Assert.NotNull(actual.Objects);
|
||||
Assert.Equal(expected.Objects.Count, actual.Objects.Count);
|
||||
for (var i = 0; i < expected.Objects.Count; i++)
|
||||
TmxSerializerObjectTests.AssertObject(actual.Objects[i], expected.Objects[i]);
|
||||
}
|
||||
|
||||
private static void AssertLayer(ImageLayer actual, ImageLayer expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.RepeatX, actual.RepeatX);
|
||||
Assert.Equal(expected.RepeatY, actual.RepeatY);
|
||||
|
||||
Assert.NotNull(actual.Image);
|
||||
TmxSerializerImageTests.AssertImage(actual.Image, expected.Image);
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerMapTests
|
||||
{
|
||||
private static void AssertMap(Map actual, Map expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.Version, actual.Version);
|
||||
Assert.Equal(expected.TiledVersion, actual.TiledVersion);
|
||||
Assert.Equal(expected.Class, actual.Class);
|
||||
Assert.Equal(expected.Orientation, actual.Orientation);
|
||||
Assert.Equal(expected.RenderOrder, actual.RenderOrder);
|
||||
Assert.Equal(expected.CompressionLevel, actual.CompressionLevel);
|
||||
Assert.Equal(expected.Width, actual.Width);
|
||||
Assert.Equal(expected.Height, actual.Height);
|
||||
Assert.Equal(expected.TileWidth, actual.TileWidth);
|
||||
Assert.Equal(expected.TileHeight, actual.TileHeight);
|
||||
Assert.Equal(expected.HexSideLength, actual.HexSideLength);
|
||||
Assert.Equal(expected.StaggerAxis, actual.StaggerAxis);
|
||||
Assert.Equal(expected.StaggerIndex, actual.StaggerIndex);
|
||||
Assert.Equal(expected.ParallaxOriginX, actual.ParallaxOriginX);
|
||||
Assert.Equal(expected.ParallaxOriginY, actual.ParallaxOriginY);
|
||||
Assert.Equal(expected.BackgroundColor, actual.BackgroundColor);
|
||||
Assert.Equal(expected.NextLayerID, actual.NextLayerID);
|
||||
Assert.Equal(expected.NextObjectID, actual.NextObjectID);
|
||||
Assert.Equal(expected.Infinite, actual.Infinite);
|
||||
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
|
||||
Assert.NotNull(actual.Tilesets);
|
||||
Assert.Equal(expected.Tilesets.Count, actual.Tilesets.Count);
|
||||
for (var i = 0; i < expected.Tilesets.Count; i++)
|
||||
TmxSerializerTilesetTests.AssertTileset(actual.Tilesets[i], expected.Tilesets[i]);
|
||||
|
||||
Assert.NotNull(actual.Layers);
|
||||
Assert.Equal(expected.Layers.Count, actual.Layers.Count);
|
||||
for (var i = 0; i < expected.Layers.Count; i++)
|
||||
TmxSerializerLayerTests.AssertLayer(actual.Layers[i], expected.Layers[i]);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data =>
|
||||
[
|
||||
["TmxSerializer.TestData.Map.empty-map-csv.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Csv, null)],
|
||||
["TmxSerializer.TestData.Map.empty-map-base64.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, null)],
|
||||
["TmxSerializer.TestData.Map.empty-map-base64-gzip.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.GZip)],
|
||||
["TmxSerializer.TestData.Map.empty-map-base64-zlib.tmx", EmptyMapWithEncodingAndCompression(DataEncoding.Base64, DataCompression.ZLib)],
|
||||
["TmxSerializer.TestData.Map.simple-tileset-embed.tmx", SimpleMapWithEmbeddedTileset()],
|
||||
["TmxSerializer.TestData.Map.empty-map-properties.tmx", EmptyMapWithProperties()],
|
||||
];
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapWithoutThrowing_Data))]
|
||||
public void DeserializeMap_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap)
|
||||
{
|
||||
// Arrange
|
||||
using var reader = TmxSerializerTestData.GetReaderFor(testDataFile);
|
||||
Func<string, Tileset> externalTilesetResolver = (string s) => throw new NotSupportedException("External tilesets are not supported in this test");
|
||||
var tmxSerializer = new TmxSerializer(externalTilesetResolver);
|
||||
|
||||
// Act
|
||||
var map = tmxSerializer.DeserializeMap(reader);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(map);
|
||||
AssertMap(map, expectedMap);
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerObjectTests
|
||||
{
|
||||
public static void AssertObject(Object actual, Object expected)
|
||||
{
|
||||
// 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);
|
||||
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
AssertObject((dynamic)actual, (dynamic)expected);
|
||||
}
|
||||
|
||||
private static void AssertObject(RectangleObject actual, RectangleObject expected)
|
||||
{
|
||||
Assert.True(true); // A rectangle object is the same as the abstract Object
|
||||
}
|
||||
|
||||
private static void AssertObject(EllipseObject actual, EllipseObject expected)
|
||||
{
|
||||
Assert.True(true); // An ellipse object is the same as the abstract Object
|
||||
}
|
||||
|
||||
private static void AssertObject(PointObject actual, PointObject expected)
|
||||
{
|
||||
Assert.True(true); // A point object is the same as the abstract Object
|
||||
}
|
||||
|
||||
private static void AssertObject(PolygonObject actual, PolygonObject expected)
|
||||
{
|
||||
Assert.Equal(expected.Points, actual.Points);
|
||||
}
|
||||
|
||||
private static void AssertObject(PolylineObject actual, PolylineObject expected)
|
||||
{
|
||||
Assert.Equal(expected.Points, actual.Points);
|
||||
}
|
||||
|
||||
private static void AssertObject(TextObject actual, TextObject expected)
|
||||
{
|
||||
// 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);
|
||||
|
||||
Assert.Equal(expected.Text, actual.Text);
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerPropertiesTests
|
||||
{
|
||||
public static void AssertProperties(Dictionary<string, IProperty>? actual, Dictionary<string, IProperty>? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Count, actual.Count);
|
||||
foreach (var kvp in expected)
|
||||
{
|
||||
Assert.Contains(kvp.Key, actual.Keys);
|
||||
AssertProperty((dynamic)kvp.Value, (dynamic)actual[kvp.Key]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertProperty(IProperty actual, IProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Type, actual.Type);
|
||||
Assert.Equal(expected.Name, actual.Name);
|
||||
AssertProperties((dynamic)actual, (dynamic)expected);
|
||||
}
|
||||
|
||||
private static void AssertProperty(StringProperty actual, StringProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(IntProperty actual, IntProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(FloatProperty actual, FloatProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(BoolProperty actual, BoolProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(ColorProperty actual, ColorProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(FileProperty actual, FileProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(ObjectProperty actual, ObjectProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.Value, actual.Value);
|
||||
}
|
||||
|
||||
private static void AssertProperty(ClassProperty actual, ClassProperty expected)
|
||||
{
|
||||
Assert.Equal(expected.PropertyType, actual.PropertyType);
|
||||
AssertProperties(actual.Properties, expected.Properties);
|
||||
}
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxSerializerTilesetTests
|
||||
{
|
||||
public static void AssertTileset(Tileset actual, Tileset expected)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// At most one of
|
||||
TmxSerializerImageTests.AssertImage(actual.Image, expected.Image);
|
||||
AssertTileOffset(actual.TileOffset, expected.TileOffset);
|
||||
AssertGrid(actual.Grid, expected.Grid);
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
// TODO: AssertTerrainTypes(actual.TerrainTypes, expected.TerrainTypes);
|
||||
if (expected.Wangsets is not null)
|
||||
{
|
||||
Assert.NotNull(actual.Wangsets);
|
||||
Assert.Equal(expected.Wangsets.Count, actual.Wangsets.Count);
|
||||
for (var i = 0; i < expected.Wangsets.Count; i++)
|
||||
AssertWangset(actual.Wangsets[i], expected.Wangsets[i]);
|
||||
}
|
||||
AssertTransformations(actual.Transformations, expected.Transformations);
|
||||
|
||||
// Any number of
|
||||
Assert.NotNull(actual.Tiles);
|
||||
Assert.Equal(expected.Tiles.Count, actual.Tiles.Count);
|
||||
for (var i = 0; i < expected.Tiles.Count; i++)
|
||||
AssertTile(actual.Tiles[i], expected.Tiles[i]);
|
||||
}
|
||||
|
||||
private static void AssertTileOffset(TileOffset? actual, TileOffset? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.X, actual.X);
|
||||
Assert.Equal(expected.Y, actual.Y);
|
||||
}
|
||||
|
||||
private static void AssertGrid(Grid? actual, Grid? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Orientation, actual.Orientation);
|
||||
Assert.Equal(expected.Width, actual.Width);
|
||||
Assert.Equal(expected.Height, actual.Height);
|
||||
}
|
||||
|
||||
private static void AssertWangset(Wangset actual, Wangset expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.Name, actual.Name);
|
||||
Assert.Equal(expected.Class, actual.Class);
|
||||
Assert.Equal(expected.Tile, actual.Tile);
|
||||
|
||||
// At most one of
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
if (expected.WangColors is not null)
|
||||
{
|
||||
Assert.NotNull(actual.WangColors);
|
||||
Assert.Equal(expected.WangColors.Count, actual.WangColors.Count);
|
||||
for (var i = 0; i < expected.WangColors.Count; i++)
|
||||
AssertWangColor(actual.WangColors[i], expected.WangColors[i]);
|
||||
}
|
||||
for (var i = 0; i < expected.WangTiles.Count; i++)
|
||||
AssertWangTile(actual.WangTiles[i], expected.WangTiles[i]);
|
||||
}
|
||||
|
||||
private static void AssertWangColor(WangColor actual, WangColor expected)
|
||||
{
|
||||
// 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);
|
||||
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
}
|
||||
|
||||
private static void AssertWangTile(WangTile actual, WangTile expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.TileID, actual.TileID);
|
||||
Assert.Equal(expected.WangID, actual.WangID);
|
||||
}
|
||||
|
||||
private static void AssertTransformations(Transformations? actual, Transformations? expected)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
private static void AssertTile(Tile actual, Tile expected)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Elements
|
||||
TmxSerializerPropertiesTests.AssertProperties(actual.Properties, expected.Properties);
|
||||
TmxSerializerImageTests.AssertImage(actual.Image, expected.Image);
|
||||
TmxSerializerLayerTests.AssertLayer(actual.ObjectLayer, expected.ObjectLayer);
|
||||
if (expected.Animation is not null)
|
||||
{
|
||||
Assert.NotNull(actual.Animation);
|
||||
Assert.Equal(expected.Animation.Count, actual.Animation.Count);
|
||||
for (var i = 0; i < expected.Animation.Count; i++)
|
||||
AssertFrame(actual.Animation[i], expected.Animation[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertFrame(Frame actual, Frame expected)
|
||||
{
|
||||
// Attributes
|
||||
Assert.Equal(expected.TileID, actual.TileID);
|
||||
Assert.Equal(expected.Duration, actual.Duration);
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public class TmxSerializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void TmxSerializerConstructor_ExternalTilesetResolverIsNull_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
Func<string, Tileset> externalTilesetResolver = null!;
|
||||
|
||||
// Act
|
||||
Action act = () => _ = new TmxSerializer(externalTilesetResolver);
|
||||
|
||||
// Assert
|
||||
Assert.Throws<ArgumentNullException>(act);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TmxSerializerConstructor_ExternalTilesetResolverIsNotNull_DoesNotThrow()
|
||||
{
|
||||
// Arrange
|
||||
Func<string, Tileset> externalTilesetResolver = _ => new Tileset();
|
||||
|
||||
// Act
|
||||
var tmxSerializer = new TmxSerializer(externalTilesetResolver);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(tmxSerializer);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotTiled", "DotTiled\DotTil
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotTiled.Tests", "DotTiled.Tests\DotTiled.Tests.csproj", "{C1311A5A-5206-467C-B323-B131CA11FDB8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotTiled.Benchmark", "DotTiled.Benchmark\DotTiled.Benchmark.csproj", "{510F3077-8EA4-47D1-8D01-E2D538F1B899}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -24,5 +26,9 @@ Global
|
|||
{C1311A5A-5206-467C-B323-B131CA11FDB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C1311A5A-5206-467C-B323-B131CA11FDB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C1311A5A-5206-467C-B323-B131CA11FDB8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{510F3077-8EA4-47D1-8D01-E2D538F1B899}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -66,4 +66,6 @@ public class Color : IParsable<Color>, IEquatable<Color>
|
|||
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}";
|
||||
}
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
public class StringProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.String;
|
||||
public required string Value { get; set; }
|
||||
}
|
||||
|
||||
public class IntProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.Int;
|
||||
public required int Value { get; set; }
|
||||
}
|
||||
|
||||
public class FloatProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.Float;
|
||||
public required float Value { get; set; }
|
||||
}
|
||||
|
||||
public class BoolProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.Bool;
|
||||
public required bool Value { get; set; }
|
||||
}
|
||||
|
||||
public class ColorProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.Color;
|
||||
public required Color Value { get; set; }
|
||||
}
|
||||
|
||||
public class FileProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.File;
|
||||
public required string Value { get; set; }
|
||||
}
|
||||
|
||||
public class ObjectProperty : IProperty
|
||||
{
|
||||
public required string Name { get; set; }
|
||||
public PropertyType Type => PropertyType.Object;
|
||||
public required uint Value { get; set; }
|
||||
}
|
||||
|
||||
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<string, IProperty> Properties { get; set; }
|
||||
}
|
|
@ -8,8 +8,6 @@ public abstract class BaseLayer
|
|||
public required uint ID { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string Class { get; set; } = "";
|
||||
public uint X { get; set; } = 0;
|
||||
public uint Y { get; set; } = 0;
|
||||
public float Opacity { get; set; } = 1.0f;
|
||||
public bool Visible { get; set; } = true;
|
||||
public Color? TintColor { get; set; }
|
||||
|
|
11
DotTiled/Model/Layers/Group.cs
Normal file
11
DotTiled/Model/Layers/Group.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace DotTiled;
|
||||
|
||||
public class Group : BaseLayer
|
||||
{
|
||||
// Uses same attributes as BaseLayer
|
||||
|
||||
// Any number of
|
||||
public List<BaseLayer> Layers { get; set; } = [];
|
||||
}
|
|
@ -3,8 +3,10 @@ namespace DotTiled;
|
|||
public class ImageLayer : BaseLayer
|
||||
{
|
||||
// Attributes
|
||||
public required bool RepeatX { get; set; }
|
||||
public required bool RepeatY { get; set; }
|
||||
public uint X { get; set; } = 0;
|
||||
public uint Y { get; set; } = 0;
|
||||
public bool RepeatX { get; set; } = false;
|
||||
public bool RepeatY { get; set; } = false;
|
||||
|
||||
// At most one of
|
||||
public Image? Image { get; set; }
|
||||
|
|
|
@ -11,10 +11,12 @@ public enum DrawOrder
|
|||
public class ObjectLayer : BaseLayer
|
||||
{
|
||||
// Attributes
|
||||
public uint X { get; set; } = 0;
|
||||
public uint Y { get; set; } = 0;
|
||||
public uint? Width { get; set; }
|
||||
public uint? Height { get; set; }
|
||||
public required Color? Color { get; set; }
|
||||
public required DrawOrder DrawOrder { get; set; } = DrawOrder.TopDown;
|
||||
public Color? Color { get; set; }
|
||||
public DrawOrder DrawOrder { get; set; } = DrawOrder.TopDown;
|
||||
|
||||
// Elements
|
||||
public required List<Object> Objects { get; set; }
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace DotTiled;
|
|||
public abstract class Object
|
||||
{
|
||||
// Attributes
|
||||
public required uint ID { get; set; }
|
||||
public uint? ID { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string Type { get; set; } = "";
|
||||
public float X { get; set; } = 0f;
|
||||
|
@ -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; }
|
||||
|
||||
|
|
6
DotTiled/Model/Layers/Objects/TileObject.cs
Normal file
6
DotTiled/Model/Layers/Objects/TileObject.cs
Normal file
|
@ -0,0 +1,6 @@
|
|||
namespace DotTiled;
|
||||
|
||||
public class TileObject : Object
|
||||
{
|
||||
public uint GID { get; set; }
|
||||
}
|
|
@ -3,6 +3,8 @@ namespace DotTiled;
|
|||
public class TileLayer : BaseLayer
|
||||
{
|
||||
// Attributes
|
||||
public uint X { get; set; } = 0;
|
||||
public uint Y { get; set; } = 0;
|
||||
public required uint Width { get; set; }
|
||||
public required uint Height { get; set; }
|
||||
|
||||
|
|
|
@ -60,5 +60,4 @@ public class Map
|
|||
// Any number of
|
||||
public List<Tileset> Tilesets { get; set; } = [];
|
||||
public List<BaseLayer> Layers { get; set; } = [];
|
||||
// public List<Group> Groups { get; set; } = [];
|
||||
}
|
||||
|
|
14
DotTiled/Model/Properties/BoolProperty.cs
Normal file
14
DotTiled/Model/Properties/BoolProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
19
DotTiled/Model/Properties/ClassProperty.cs
Normal file
19
DotTiled/Model/Properties/ClassProperty.cs
Normal file
|
@ -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<string, IProperty> Properties { get; set; }
|
||||
|
||||
public IProperty Clone() => new ClassProperty
|
||||
{
|
||||
Name = Name,
|
||||
PropertyType = PropertyType,
|
||||
Properties = Properties.ToDictionary(p => p.Key, p => p.Value.Clone())
|
||||
};
|
||||
}
|
14
DotTiled/Model/Properties/ColorProperty.cs
Normal file
14
DotTiled/Model/Properties/ColorProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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<IProperty> Members { get; set; } = [];
|
||||
}
|
|
@ -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<string> Values { get; set; } = [];
|
||||
public bool ValueAsFlags { get; set; }
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace DotTiled;
|
||||
|
||||
public abstract class CustomTypeDefinition
|
||||
{
|
||||
public uint ID { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
}
|
14
DotTiled/Model/Properties/FileProperty.cs
Normal file
14
DotTiled/Model/Properties/FileProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
14
DotTiled/Model/Properties/FloatProperty.cs
Normal file
14
DotTiled/Model/Properties/FloatProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
9
DotTiled/Model/Properties/IProperty.cs
Normal file
9
DotTiled/Model/Properties/IProperty.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace DotTiled;
|
||||
|
||||
public interface IProperty
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public PropertyType Type { get; }
|
||||
|
||||
IProperty Clone();
|
||||
}
|
14
DotTiled/Model/Properties/IntProperty.cs
Normal file
14
DotTiled/Model/Properties/IntProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
14
DotTiled/Model/Properties/ObjectProperty.cs
Normal file
14
DotTiled/Model/Properties/ObjectProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
13
DotTiled/Model/Properties/PropertyType.cs
Normal file
13
DotTiled/Model/Properties/PropertyType.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace DotTiled;
|
||||
|
||||
public enum PropertyType
|
||||
{
|
||||
String,
|
||||
Int,
|
||||
Float,
|
||||
Bool,
|
||||
Color,
|
||||
File,
|
||||
Object,
|
||||
Class
|
||||
}
|
14
DotTiled/Model/Properties/StringProperty.cs
Normal file
14
DotTiled/Model/Properties/StringProperty.cs
Normal file
|
@ -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
|
||||
};
|
||||
}
|
8
DotTiled/Model/Template.cs
Normal file
8
DotTiled/Model/Template.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace DotTiled;
|
||||
|
||||
public class Template
|
||||
{
|
||||
// At most one of (if the template is a tile object)
|
||||
public Tileset? Tileset { get; set; }
|
||||
public required Object Object { get; set; }
|
||||
}
|
|
@ -39,8 +39,8 @@ public class Tileset
|
|||
public string Class { get; set; } = "";
|
||||
public uint? TileWidth { get; set; }
|
||||
public uint? TileHeight { get; set; }
|
||||
public float? Spacing { get; set; }
|
||||
public float? Margin { get; set; }
|
||||
public float? Spacing { get; set; } = 0f;
|
||||
public float? Margin { get; set; } = 0f;
|
||||
public uint? TileCount { get; set; }
|
||||
public uint? Columns { get; set; }
|
||||
public ObjectAlignment ObjectAlignment { get; set; } = ObjectAlignment.Unspecified;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
123
DotTiled/Serialization/Helpers.cs
Normal file
123
DotTiled/Serialization/Helpers.cs
Normal file
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
|
||||
namespace DotTiled;
|
||||
|
||||
internal static partial class Helpers
|
||||
{
|
||||
internal static uint[] ReadMemoryStreamAsInt32Array(Stream stream)
|
||||
{
|
||||
var finalValues = new List<uint>();
|
||||
var int32Bytes = new byte[4];
|
||||
while (stream.Read(int32Bytes, 0, 4) == 4)
|
||||
{
|
||||
var value = BitConverter.ToUInt32(int32Bytes, 0);
|
||||
finalValues.Add(value);
|
||||
}
|
||||
return [.. finalValues];
|
||||
}
|
||||
|
||||
internal static uint[] DecompressGZip(MemoryStream stream)
|
||||
{
|
||||
using var decompressedStream = new GZipStream(stream, CompressionMode.Decompress);
|
||||
return ReadMemoryStreamAsInt32Array(decompressedStream);
|
||||
}
|
||||
|
||||
internal static uint[] DecompressZLib(MemoryStream stream)
|
||||
{
|
||||
using var decompressedStream = new ZLibStream(stream, CompressionMode.Decompress);
|
||||
return ReadMemoryStreamAsInt32Array(decompressedStream);
|
||||
}
|
||||
|
||||
internal static uint[] ReadBytesAsInt32Array(byte[] bytes)
|
||||
{
|
||||
var intArray = new uint[bytes.Length / 4];
|
||||
for (var i = 0; i < intArray.Length; i++)
|
||||
{
|
||||
intArray[i] = BitConverter.ToUInt32(bytes, i * 4);
|
||||
}
|
||||
|
||||
return intArray;
|
||||
}
|
||||
|
||||
internal static (uint[] GlobalTileIDs, FlippingFlags[] FlippingFlags) ReadAndClearFlippingFlagsFromGIDs(uint[] globalTileIDs)
|
||||
{
|
||||
var clearedGlobalTileIDs = new uint[globalTileIDs.Length];
|
||||
var flippingFlags = new FlippingFlags[globalTileIDs.Length];
|
||||
for (var i = 0; i < globalTileIDs.Length; i++)
|
||||
{
|
||||
var gid = globalTileIDs[i];
|
||||
var flags = gid & 0xF0000000u;
|
||||
flippingFlags[i] = (FlippingFlags)flags;
|
||||
clearedGlobalTileIDs[i] = gid & 0x0FFFFFFFu;
|
||||
}
|
||||
|
||||
return (clearedGlobalTileIDs, flippingFlags);
|
||||
}
|
||||
|
||||
internal static ImageFormat ParseImageFormatFromSource(string source)
|
||||
{
|
||||
var extension = Path.GetExtension(source).ToLowerInvariant();
|
||||
return extension switch
|
||||
{
|
||||
".png" => ImageFormat.Png,
|
||||
".gif" => ImageFormat.Gif,
|
||||
".jpg" => ImageFormat.Jpg,
|
||||
".jpeg" => ImageFormat.Jpg,
|
||||
".bmp" => ImageFormat.Bmp,
|
||||
_ => throw new NotSupportedException($"Unsupported image format '{extension}'")
|
||||
};
|
||||
}
|
||||
|
||||
internal static Dictionary<string, IProperty> MergeProperties(Dictionary<string, IProperty>? baseProperties, Dictionary<string, IProperty>? overrideProperties)
|
||||
{
|
||||
if (baseProperties is null)
|
||||
return overrideProperties ?? new Dictionary<string, IProperty>();
|
||||
|
||||
if (overrideProperties is null)
|
||||
return baseProperties;
|
||||
|
||||
var result = baseProperties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Clone());
|
||||
foreach (var (key, value) in overrideProperties)
|
||||
{
|
||||
if (!result.TryGetValue(key, out var baseProp))
|
||||
{
|
||||
result[key] = value;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is ClassProperty classProp)
|
||||
{
|
||||
((ClassProperty)baseProp).Properties = MergeProperties(((ClassProperty)baseProp).Properties, classProp.Properties);
|
||||
}
|
||||
else
|
||||
{
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void SetAtMostOnce<T>(ref T? field, T value, string fieldName)
|
||||
{
|
||||
if (field is not null)
|
||||
throw new InvalidOperationException($"{fieldName} already set");
|
||||
|
||||
field = value;
|
||||
}
|
||||
|
||||
internal static void SetAtMostOnceUsingCounter<T>(ref T? field, T value, string fieldName, ref int counter)
|
||||
{
|
||||
if (counter > 0)
|
||||
throw new InvalidOperationException($"{fieldName} already set");
|
||||
|
||||
field = value;
|
||||
counter++;
|
||||
}
|
||||
}
|
8
DotTiled/Serialization/IMapReader.cs
Normal file
8
DotTiled/Serialization/IMapReader.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace DotTiled;
|
||||
|
||||
public interface IMapReader : IDisposable
|
||||
{
|
||||
Map ReadMap();
|
||||
}
|
8
DotTiled/Serialization/ITemplateReader.cs
Normal file
8
DotTiled/Serialization/ITemplateReader.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace DotTiled;
|
||||
|
||||
public interface ITemplateReader : IDisposable
|
||||
{
|
||||
Template ReadTemplate();
|
||||
}
|
8
DotTiled/Serialization/ITilesetReader.cs
Normal file
8
DotTiled/Serialization/ITilesetReader.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace DotTiled;
|
||||
|
||||
public interface ITilesetReader : IDisposable
|
||||
{
|
||||
Tileset ReadTileset();
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue