mirror of
https://github.com/dcronqvist/DotTiled.git
synced 2025-02-05 17:02:49 +02:00
Further optional improvements, Tmj now supports it too
This commit is contained in:
parent
88a5eadb74
commit
4fd887e7c8
18 changed files with 249 additions and 252 deletions
|
@ -2,7 +2,7 @@ namespace DotTiled.Tests;
|
||||||
|
|
||||||
public static partial class DotTiledAssert
|
public static partial class DotTiledAssert
|
||||||
{
|
{
|
||||||
internal static void AssertData(Data? expected, Data? actual)
|
internal static void AssertData(Data expected, Data actual)
|
||||||
{
|
{
|
||||||
if (expected is null)
|
if (expected is null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace DotTiled.Tests;
|
||||||
|
|
||||||
public static partial class DotTiledAssert
|
public static partial class DotTiledAssert
|
||||||
{
|
{
|
||||||
internal static void AssertImage(Image? expected, Image? actual)
|
internal static void AssertImage(Image expected, Image actual)
|
||||||
{
|
{
|
||||||
if (expected is null)
|
if (expected is null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace DotTiled.Tests;
|
||||||
|
|
||||||
public static partial class DotTiledAssert
|
public static partial class DotTiledAssert
|
||||||
{
|
{
|
||||||
internal static void AssertLayer(BaseLayer? expected, BaseLayer? actual)
|
internal static void AssertLayer(BaseLayer expected, BaseLayer actual)
|
||||||
{
|
{
|
||||||
if (expected is null)
|
if (expected is null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace DotTiled.Tests;
|
||||||
|
|
||||||
public static partial class DotTiledAssert
|
public static partial class DotTiledAssert
|
||||||
{
|
{
|
||||||
internal static void AssertProperties(IList<IProperty>? expected, IList<IProperty>? actual)
|
internal static void AssertProperties(IList<IProperty> expected, IList<IProperty> actual)
|
||||||
{
|
{
|
||||||
if (expected is null)
|
if (expected is null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,7 +43,7 @@ public static partial class DotTiledAssert
|
||||||
AssertEqual(expected.Y, actual.Y, nameof(TileOffset.Y));
|
AssertEqual(expected.Y, actual.Y, nameof(TileOffset.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AssertGrid(Grid? expected, Grid? actual)
|
private static void AssertGrid(Grid expected, Grid actual)
|
||||||
{
|
{
|
||||||
if (expected is null)
|
if (expected is null)
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,7 @@ public static partial class DotTiledAssert
|
||||||
AssertEqual(expected.WangID, actual.WangID, nameof(WangTile.WangID));
|
AssertEqual(expected.WangID, actual.WangID, nameof(WangTile.WangID));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AssertTransformations(Transformations? expected, Transformations? actual)
|
private static void AssertTransformations(Transformations expected, Transformations actual)
|
||||||
{
|
{
|
||||||
if (expected is null)
|
if (expected is null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace DotTiled.Tests;
|
||||||
public partial class MapReaderTests
|
public partial class MapReaderTests
|
||||||
{
|
{
|
||||||
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
||||||
[Theory(Skip = "Skipped for now")]
|
[Theory]
|
||||||
[MemberData(nameof(Maps))]
|
[MemberData(nameof(Maps))]
|
||||||
public void MapReaderReadMap_ValidFilesExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
public void MapReaderReadMap_ValidFilesExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
||||||
string testDataFile,
|
string testDataFile,
|
||||||
|
|
|
@ -15,13 +15,13 @@ internal static class ExtensionsJsonElement
|
||||||
return property.GetValueAs<T>();
|
return property.GetValueAs<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static T GetOptionalProperty<T>(this JsonElement element, string propertyName, T defaultValue)
|
internal static Optional<T> GetOptionalProperty<T>(this JsonElement element, string propertyName)
|
||||||
{
|
{
|
||||||
if (!element.TryGetProperty(propertyName, out var property))
|
if (!element.TryGetProperty(propertyName, out var property))
|
||||||
return defaultValue;
|
return Optional<T>.Empty;
|
||||||
|
|
||||||
if (property.ValueKind == JsonValueKind.Null)
|
if (property.ValueKind == JsonValueKind.Null)
|
||||||
return defaultValue;
|
return Optional<T>.Empty;
|
||||||
|
|
||||||
return property.GetValueAs<T>();
|
return property.GetValueAs<T>();
|
||||||
}
|
}
|
||||||
|
@ -64,18 +64,18 @@ internal static class ExtensionsJsonElement
|
||||||
return parser(property.GetString()!);
|
return parser(property.GetString()!);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static T GetOptionalPropertyParseable<T>(this JsonElement element, string propertyName, T defaultValue) where T : IParsable<T>
|
internal static Optional<T> GetOptionalPropertyParseable<T>(this JsonElement element, string propertyName) where T : IParsable<T>
|
||||||
{
|
{
|
||||||
if (!element.TryGetProperty(propertyName, out var property))
|
if (!element.TryGetProperty(propertyName, out var property))
|
||||||
return defaultValue;
|
return Optional<T>.Empty;
|
||||||
|
|
||||||
return T.Parse(property.GetString()!, CultureInfo.InvariantCulture);
|
return T.Parse(property.GetString()!, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static T GetOptionalPropertyParseable<T>(this JsonElement element, string propertyName, Func<string, T> parser, T defaultValue)
|
internal static Optional<T> GetOptionalPropertyParseable<T>(this JsonElement element, string propertyName, Func<string, T> parser)
|
||||||
{
|
{
|
||||||
if (!element.TryGetProperty(propertyName, out var property))
|
if (!element.TryGetProperty(propertyName, out var property))
|
||||||
return defaultValue;
|
return Optional<T>.Empty;
|
||||||
|
|
||||||
return parser(property.GetString()!);
|
return parser(property.GetString()!);
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,10 @@ internal static class ExtensionsJsonElement
|
||||||
return parser(property);
|
return parser(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static T GetOptionalPropertyCustom<T>(this JsonElement element, string propertyName, Func<JsonElement, T> parser, T defaultValue)
|
internal static Optional<T> GetOptionalPropertyCustom<T>(this JsonElement element, string propertyName, Func<JsonElement, T> parser)
|
||||||
{
|
{
|
||||||
if (!element.TryGetProperty(propertyName, out var property))
|
if (!element.TryGetProperty(propertyName, out var property))
|
||||||
return defaultValue;
|
return Optional<T>.Empty;
|
||||||
|
|
||||||
return parser(property);
|
return parser(property);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace DotTiled.Serialization.Tmj;
|
||||||
|
|
||||||
public abstract partial class TmjReaderBase
|
public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
internal static Data ReadDataAsChunks(JsonElement element, DataCompression? compression, DataEncoding encoding)
|
internal static Data ReadDataAsChunks(JsonElement element, Optional<DataCompression> compression, DataEncoding encoding)
|
||||||
{
|
{
|
||||||
var chunks = element.GetValueAsList<Chunk>(e => ReadChunk(e, compression, encoding)).ToArray();
|
var chunks = element.GetValueAsList<Chunk>(e => ReadChunk(e, compression, encoding)).ToArray();
|
||||||
return new Data
|
return new Data
|
||||||
|
@ -19,7 +19,7 @@ public abstract partial class TmjReaderBase
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Chunk ReadChunk(JsonElement element, DataCompression? compression, DataEncoding encoding)
|
internal static Chunk ReadChunk(JsonElement element, Optional<DataCompression> compression, DataEncoding encoding)
|
||||||
{
|
{
|
||||||
var data = ReadDataWithoutChunks(element, compression, encoding);
|
var data = ReadDataWithoutChunks(element, compression, encoding);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public abstract partial class TmjReaderBase
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Data ReadDataWithoutChunks(JsonElement element, DataCompression? compression, DataEncoding encoding)
|
internal static Data ReadDataWithoutChunks(JsonElement element, Optional<DataCompression> compression, DataEncoding encoding)
|
||||||
{
|
{
|
||||||
if (encoding == DataEncoding.Csv)
|
if (encoding == DataEncoding.Csv)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
var base64Data = element.GetBytesFromBase64();
|
var base64Data = element.GetBytesFromBase64();
|
||||||
|
|
||||||
if (compression == null)
|
if (!compression.HasValue)
|
||||||
{
|
{
|
||||||
var data = Helpers.ReadBytesAsInt32Array(base64Data);
|
var data = Helpers.ReadBytesAsInt32Array(base64Data);
|
||||||
var (globalTileIDs, flippingFlags) = Helpers.ReadAndClearFlippingFlagsFromGIDs(data);
|
var (globalTileIDs, flippingFlags) = Helpers.ReadAndClearFlippingFlagsFromGIDs(data);
|
||||||
|
@ -60,7 +60,7 @@ public abstract partial class TmjReaderBase
|
||||||
}
|
}
|
||||||
|
|
||||||
using var stream = new MemoryStream(base64Data);
|
using var stream = new MemoryStream(base64Data);
|
||||||
var decompressed = compression switch
|
var decompressed = compression.Value switch
|
||||||
{
|
{
|
||||||
DataCompression.GZip => Helpers.DecompressGZip(stream),
|
DataCompression.GZip => Helpers.DecompressGZip(stream),
|
||||||
DataCompression.ZLib => Helpers.DecompressZLib(stream),
|
DataCompression.ZLib => Helpers.DecompressZLib(stream),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace DotTiled.Serialization.Tmj;
|
namespace DotTiled.Serialization.Tmj;
|
||||||
|
@ -10,16 +9,16 @@ public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
var id = element.GetRequiredProperty<uint>("id");
|
var id = element.GetRequiredProperty<uint>("id");
|
||||||
var name = element.GetRequiredProperty<string>("name");
|
var name = element.GetRequiredProperty<string>("name");
|
||||||
var @class = element.GetOptionalProperty<string>("class", "");
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var opacity = element.GetOptionalProperty<float>("opacity", 1.0f);
|
var opacity = element.GetOptionalProperty<float>("opacity").GetValueOr(1.0f);
|
||||||
var visible = element.GetOptionalProperty<bool>("visible", true);
|
var visible = element.GetOptionalProperty<bool>("visible").GetValueOr(true);
|
||||||
var tintColor = element.GetOptionalPropertyParseable<Color?>("tintcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var tintColor = element.GetOptionalPropertyParseable<Color>("tintcolor");
|
||||||
var offsetX = element.GetOptionalProperty<float>("offsetx", 0.0f);
|
var offsetX = element.GetOptionalProperty<float>("offsetx").GetValueOr(0.0f);
|
||||||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
var offsetY = element.GetOptionalProperty<float>("offsety").GetValueOr(0.0f);
|
||||||
var parallaxX = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
var parallaxX = element.GetOptionalProperty<float>("parallaxx").GetValueOr(1.0f);
|
||||||
var parallaxY = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
var parallaxY = element.GetOptionalProperty<float>("parallaxy").GetValueOr(1.0f);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
var layers = element.GetOptionalPropertyCustom<List<BaseLayer>>("layers", e => e.GetValueAsList<BaseLayer>(ReadLayer), []);
|
var layers = element.GetOptionalPropertyCustom<List<BaseLayer>>("layers", e => e.GetValueAsList<BaseLayer>(ReadLayer)).GetValueOr([]);
|
||||||
|
|
||||||
return new Group
|
return new Group
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Globalization;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace DotTiled.Serialization.Tmj;
|
namespace DotTiled.Serialization.Tmj;
|
||||||
|
@ -9,22 +8,22 @@ public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
var id = element.GetRequiredProperty<uint>("id");
|
var id = element.GetRequiredProperty<uint>("id");
|
||||||
var name = element.GetRequiredProperty<string>("name");
|
var name = element.GetRequiredProperty<string>("name");
|
||||||
var @class = element.GetOptionalProperty<string>("class", "");
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var opacity = element.GetOptionalProperty<float>("opacity", 1.0f);
|
var opacity = element.GetOptionalProperty<float>("opacity").GetValueOr(1.0f);
|
||||||
var visible = element.GetOptionalProperty<bool>("visible", true);
|
var visible = element.GetOptionalProperty<bool>("visible").GetValueOr(true);
|
||||||
var tintColor = element.GetOptionalPropertyParseable<Color?>("tintcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var tintColor = element.GetOptionalPropertyParseable<Color>("tintcolor");
|
||||||
var offsetX = element.GetOptionalProperty<float>("offsetx", 0.0f);
|
var offsetX = element.GetOptionalProperty<float>("offsetx").GetValueOr(0.0f);
|
||||||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
var offsetY = element.GetOptionalProperty<float>("offsety").GetValueOr(0.0f);
|
||||||
var parallaxX = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
var parallaxX = element.GetOptionalProperty<float>("parallaxx").GetValueOr(1.0f);
|
||||||
var parallaxY = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
var parallaxY = element.GetOptionalProperty<float>("parallaxy").GetValueOr(1.0f);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
|
|
||||||
var image = element.GetRequiredProperty<string>("image");
|
var image = element.GetRequiredProperty<string>("image");
|
||||||
var repeatX = element.GetOptionalProperty<bool>("repeatx", false);
|
var repeatX = element.GetOptionalProperty<bool>("repeatx").GetValueOr(false);
|
||||||
var repeatY = element.GetOptionalProperty<bool>("repeaty", false);
|
var repeatY = element.GetOptionalProperty<bool>("repeaty").GetValueOr(false);
|
||||||
var transparentColor = element.GetOptionalPropertyParseable<Color?>("transparentcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var transparentColor = element.GetOptionalPropertyParseable<Color>("transparentcolor");
|
||||||
var x = element.GetOptionalProperty<uint>("x", 0);
|
var x = element.GetOptionalProperty<uint>("x").GetValueOr(0);
|
||||||
var y = element.GetOptionalProperty<uint>("y", 0);
|
var y = element.GetOptionalProperty<uint>("y").GetValueOr(0);
|
||||||
|
|
||||||
var imgModel = new Image
|
var imgModel = new Image
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
var version = element.GetRequiredProperty<string>("version");
|
var version = element.GetRequiredProperty<string>("version");
|
||||||
var tiledVersion = element.GetRequiredProperty<string>("tiledversion");
|
var tiledVersion = element.GetRequiredProperty<string>("tiledversion");
|
||||||
string @class = element.GetOptionalProperty<string>("class", "");
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var orientation = element.GetRequiredPropertyParseable<MapOrientation>("orientation", s => s switch
|
var orientation = element.GetRequiredPropertyParseable<MapOrientation>("orientation", s => s switch
|
||||||
{
|
{
|
||||||
"orthogonal" => MapOrientation.Orthogonal,
|
"orthogonal" => MapOrientation.Orthogonal,
|
||||||
|
@ -26,36 +26,36 @@ public abstract partial class TmjReaderBase
|
||||||
"left-down" => RenderOrder.LeftDown,
|
"left-down" => RenderOrder.LeftDown,
|
||||||
"left-up" => RenderOrder.LeftUp,
|
"left-up" => RenderOrder.LeftUp,
|
||||||
_ => throw new JsonException($"Unknown render order '{s}'")
|
_ => throw new JsonException($"Unknown render order '{s}'")
|
||||||
}, RenderOrder.RightDown);
|
}).GetValueOr(RenderOrder.RightDown);
|
||||||
var compressionLevel = element.GetOptionalProperty<int>("compressionlevel", -1);
|
var compressionLevel = element.GetOptionalProperty<int>("compressionlevel").GetValueOr(-1);
|
||||||
var width = element.GetRequiredProperty<uint>("width");
|
var width = element.GetRequiredProperty<uint>("width");
|
||||||
var height = element.GetRequiredProperty<uint>("height");
|
var height = element.GetRequiredProperty<uint>("height");
|
||||||
var tileWidth = element.GetRequiredProperty<uint>("tilewidth");
|
var tileWidth = element.GetRequiredProperty<uint>("tilewidth");
|
||||||
var tileHeight = element.GetRequiredProperty<uint>("tileheight");
|
var tileHeight = element.GetRequiredProperty<uint>("tileheight");
|
||||||
var hexSideLength = element.GetOptionalProperty<uint?>("hexsidelength", null);
|
var hexSideLength = element.GetOptionalProperty<uint>("hexsidelength");
|
||||||
var staggerAxis = element.GetOptionalPropertyParseable<StaggerAxis?>("staggeraxis", s => s switch
|
var staggerAxis = element.GetOptionalPropertyParseable<StaggerAxis>("staggeraxis", s => s switch
|
||||||
{
|
{
|
||||||
"x" => StaggerAxis.X,
|
"x" => StaggerAxis.X,
|
||||||
"y" => StaggerAxis.Y,
|
"y" => StaggerAxis.Y,
|
||||||
_ => throw new JsonException($"Unknown stagger axis '{s}'")
|
_ => throw new JsonException($"Unknown stagger axis '{s}'")
|
||||||
}, null);
|
});
|
||||||
var staggerIndex = element.GetOptionalPropertyParseable<StaggerIndex?>("staggerindex", s => s switch
|
var staggerIndex = element.GetOptionalPropertyParseable<StaggerIndex>("staggerindex", s => s switch
|
||||||
{
|
{
|
||||||
"odd" => StaggerIndex.Odd,
|
"odd" => StaggerIndex.Odd,
|
||||||
"even" => StaggerIndex.Even,
|
"even" => StaggerIndex.Even,
|
||||||
_ => throw new JsonException($"Unknown stagger index '{s}'")
|
_ => throw new JsonException($"Unknown stagger index '{s}'")
|
||||||
}, null);
|
});
|
||||||
var parallaxOriginX = element.GetOptionalProperty<float>("parallaxoriginx", 0.0f);
|
var parallaxOriginX = element.GetOptionalProperty<float>("parallaxoriginx").GetValueOr(0f);
|
||||||
var parallaxOriginY = element.GetOptionalProperty<float>("parallaxoriginy", 0.0f);
|
var parallaxOriginY = element.GetOptionalProperty<float>("parallaxoriginy").GetValueOr(0f);
|
||||||
var backgroundColor = element.GetOptionalPropertyParseable<Color>("backgroundcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), Color.Parse("#00000000", CultureInfo.InvariantCulture));
|
var backgroundColor = element.GetOptionalPropertyParseable<Color>("backgroundcolor").GetValueOr(Color.Parse("#00000000", CultureInfo.InvariantCulture));
|
||||||
var nextLayerID = element.GetRequiredProperty<uint>("nextlayerid");
|
var nextLayerID = element.GetRequiredProperty<uint>("nextlayerid");
|
||||||
var nextObjectID = element.GetRequiredProperty<uint>("nextobjectid");
|
var nextObjectID = element.GetRequiredProperty<uint>("nextobjectid");
|
||||||
var infinite = element.GetOptionalProperty<bool>("infinite", false);
|
var infinite = element.GetOptionalProperty<bool>("infinite").GetValueOr(false);
|
||||||
|
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
|
|
||||||
List<BaseLayer> layers = element.GetOptionalPropertyCustom<List<BaseLayer>>("layers", e => e.GetValueAsList<BaseLayer>(el => ReadLayer(el)), []);
|
List<BaseLayer> layers = element.GetOptionalPropertyCustom<List<BaseLayer>>("layers", e => e.GetValueAsList<BaseLayer>(el => ReadLayer(el))).GetValueOr([]);
|
||||||
List<Tileset> tilesets = element.GetOptionalPropertyCustom<List<Tileset>>("tilesets", e => e.GetValueAsList<Tileset>(el => ReadTileset(el)), []);
|
List<Tileset> tilesets = element.GetOptionalPropertyCustom<List<Tileset>>("tilesets", e => e.GetValueAsList<Tileset>(el => ReadTileset(el, version, tiledVersion))).GetValueOr([]);
|
||||||
|
|
||||||
return new Map
|
return new Map
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,29 +11,29 @@ public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
var id = element.GetRequiredProperty<uint>("id");
|
var id = element.GetRequiredProperty<uint>("id");
|
||||||
var name = element.GetRequiredProperty<string>("name");
|
var name = element.GetRequiredProperty<string>("name");
|
||||||
var @class = element.GetOptionalProperty<string>("class", "");
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var opacity = element.GetOptionalProperty<float>("opacity", 1.0f);
|
var opacity = element.GetOptionalProperty<float>("opacity").GetValueOr(1.0f);
|
||||||
var visible = element.GetOptionalProperty<bool>("visible", true);
|
var visible = element.GetOptionalProperty<bool>("visible").GetValueOr(true);
|
||||||
var tintColor = element.GetOptionalPropertyParseable<Color?>("tintcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var tintColor = element.GetOptionalPropertyParseable<Color>("tintcolor");
|
||||||
var offsetX = element.GetOptionalProperty<float>("offsetx", 0.0f);
|
var offsetX = element.GetOptionalProperty<float>("offsetx").GetValueOr(0.0f);
|
||||||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
var offsetY = element.GetOptionalProperty<float>("offsety").GetValueOr(0.0f);
|
||||||
var parallaxX = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
var parallaxX = element.GetOptionalProperty<float>("parallaxx").GetValueOr(1.0f);
|
||||||
var parallaxY = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
var parallaxY = element.GetOptionalProperty<float>("parallaxy").GetValueOr(1.0f);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
|
|
||||||
var x = element.GetOptionalProperty<uint>("x", 0);
|
var x = element.GetOptionalProperty<uint>("x").GetValueOr(0);
|
||||||
var y = element.GetOptionalProperty<uint>("y", 0);
|
var y = element.GetOptionalProperty<uint>("y").GetValueOr(0);
|
||||||
var width = element.GetOptionalProperty<uint?>("width", null);
|
var width = element.GetOptionalProperty<uint>("width").GetValueOr(0);
|
||||||
var height = element.GetOptionalProperty<uint?>("height", null);
|
var height = element.GetOptionalProperty<uint>("height").GetValueOr(0);
|
||||||
var color = element.GetOptionalPropertyParseable<Color?>("color", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var color = element.GetOptionalPropertyParseable<Color>("color");
|
||||||
var drawOrder = element.GetOptionalPropertyParseable<DrawOrder>("draworder", s => s switch
|
var drawOrder = element.GetOptionalPropertyParseable<DrawOrder>("draworder", s => s switch
|
||||||
{
|
{
|
||||||
"topdown" => DrawOrder.TopDown,
|
"topdown" => DrawOrder.TopDown,
|
||||||
"index" => DrawOrder.Index,
|
"index" => DrawOrder.Index,
|
||||||
_ => throw new JsonException($"Unknown draw order '{s}'.")
|
_ => throw new JsonException($"Unknown draw order '{s}'.")
|
||||||
}, DrawOrder.TopDown);
|
}).GetValueOr(DrawOrder.TopDown);
|
||||||
|
|
||||||
var objects = element.GetOptionalPropertyCustom<List<DotTiled.Object>>("objects", e => e.GetValueAsList<DotTiled.Object>(el => ReadObject(el)), []);
|
var objects = element.GetOptionalPropertyCustom<List<DotTiled.Object>>("objects", e => e.GetValueAsList<DotTiled.Object>(el => ReadObject(el))).GetValueOr([]);
|
||||||
|
|
||||||
return new ObjectLayer
|
return new ObjectLayer
|
||||||
{
|
{
|
||||||
|
@ -50,8 +50,8 @@ public abstract partial class TmjReaderBase
|
||||||
Properties = properties,
|
Properties = properties,
|
||||||
X = x,
|
X = x,
|
||||||
Y = y,
|
Y = y,
|
||||||
Width = width ?? 0,
|
Width = width,
|
||||||
Height = height ?? 0,
|
Height = height,
|
||||||
Color = color,
|
Color = color,
|
||||||
DrawOrder = drawOrder,
|
DrawOrder = drawOrder,
|
||||||
Objects = objects
|
Objects = objects
|
||||||
|
@ -60,7 +60,7 @@ public abstract partial class TmjReaderBase
|
||||||
|
|
||||||
internal DotTiled.Object ReadObject(JsonElement element)
|
internal DotTiled.Object ReadObject(JsonElement element)
|
||||||
{
|
{
|
||||||
uint? idDefault = null;
|
Optional<uint> idDefault = Optional<uint>.Empty;
|
||||||
string nameDefault = "";
|
string nameDefault = "";
|
||||||
string typeDefault = "";
|
string typeDefault = "";
|
||||||
float xDefault = 0f;
|
float xDefault = 0f;
|
||||||
|
@ -68,16 +68,16 @@ public abstract partial class TmjReaderBase
|
||||||
float widthDefault = 0f;
|
float widthDefault = 0f;
|
||||||
float heightDefault = 0f;
|
float heightDefault = 0f;
|
||||||
float rotationDefault = 0f;
|
float rotationDefault = 0f;
|
||||||
uint? gidDefault = null;
|
|
||||||
bool visibleDefault = true;
|
bool visibleDefault = true;
|
||||||
bool ellipseDefault = false;
|
bool ellipseDefault = false;
|
||||||
bool pointDefault = false;
|
bool pointDefault = false;
|
||||||
List<Vector2>? polygonDefault = null;
|
|
||||||
List<Vector2>? polylineDefault = null;
|
List<Vector2> polygonDefault = null;
|
||||||
|
List<Vector2> polylineDefault = null;
|
||||||
List<IProperty> propertiesDefault = [];
|
List<IProperty> propertiesDefault = [];
|
||||||
|
|
||||||
var template = element.GetOptionalProperty<string?>("template", null);
|
var template = element.GetOptionalProperty<string>("template");
|
||||||
if (template is not null)
|
if (template.HasValue)
|
||||||
{
|
{
|
||||||
var resolvedTemplate = _externalTemplateResolver(template);
|
var resolvedTemplate = _externalTemplateResolver(template);
|
||||||
var templObj = resolvedTemplate.Object;
|
var templObj = resolvedTemplate.Object;
|
||||||
|
@ -98,24 +98,24 @@ public abstract partial class TmjReaderBase
|
||||||
polylineDefault = (templObj is PolylineObject polylineObj) ? polylineObj.Points : null;
|
polylineDefault = (templObj is PolylineObject polylineObj) ? polylineObj.Points : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ellipse = element.GetOptionalProperty<bool>("ellipse", ellipseDefault);
|
var ellipse = element.GetOptionalProperty<bool>("ellipse").GetValueOr(ellipseDefault);
|
||||||
var gid = element.GetOptionalProperty<uint?>("gid", gidDefault);
|
var gid = element.GetOptionalProperty<uint>("gid");
|
||||||
var height = element.GetOptionalProperty<float>("height", heightDefault);
|
var height = element.GetOptionalProperty<float>("height").GetValueOr(heightDefault);
|
||||||
var id = element.GetOptionalProperty<uint?>("id", idDefault);
|
var id = element.GetOptionalProperty<uint>("id").GetValueOrOptional(idDefault);
|
||||||
var name = element.GetOptionalProperty<string>("name", nameDefault);
|
var name = element.GetOptionalProperty<string>("name").GetValueOr(nameDefault);
|
||||||
var point = element.GetOptionalProperty<bool>("point", pointDefault);
|
var point = element.GetOptionalProperty<bool>("point").GetValueOr(pointDefault);
|
||||||
var polygon = element.GetOptionalPropertyCustom<List<Vector2>?>("polygon", ReadPoints, polygonDefault);
|
var polygon = element.GetOptionalPropertyCustom<List<Vector2>>("polygon", ReadPoints).GetValueOr(polygonDefault);
|
||||||
var polyline = element.GetOptionalPropertyCustom<List<Vector2>?>("polyline", ReadPoints, polylineDefault);
|
var polyline = element.GetOptionalPropertyCustom<List<Vector2>>("polyline", ReadPoints).GetValueOr(polylineDefault);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, propertiesDefault);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr(propertiesDefault);
|
||||||
var rotation = element.GetOptionalProperty<float>("rotation", rotationDefault);
|
var rotation = element.GetOptionalProperty<float>("rotation").GetValueOr(rotationDefault);
|
||||||
var text = element.GetOptionalPropertyCustom<TextObject?>("text", ReadText, null);
|
var text = element.GetOptionalPropertyCustom<TextObject>("text", ReadText);
|
||||||
var type = element.GetOptionalProperty<string>("type", typeDefault);
|
var type = element.GetOptionalProperty<string>("type").GetValueOr(typeDefault);
|
||||||
var visible = element.GetOptionalProperty<bool>("visible", visibleDefault);
|
var visible = element.GetOptionalProperty<bool>("visible").GetValueOr(visibleDefault);
|
||||||
var width = element.GetOptionalProperty<float>("width", widthDefault);
|
var width = element.GetOptionalProperty<float>("width").GetValueOr(widthDefault);
|
||||||
var x = element.GetOptionalProperty<float>("x", xDefault);
|
var x = element.GetOptionalProperty<float>("x").GetValueOr(xDefault);
|
||||||
var y = element.GetOptionalProperty<float>("y", yDefault);
|
var y = element.GetOptionalProperty<float>("y").GetValueOr(yDefault);
|
||||||
|
|
||||||
if (gid is not null)
|
if (gid.HasValue)
|
||||||
{
|
{
|
||||||
return new TileObject
|
return new TileObject
|
||||||
{
|
{
|
||||||
|
@ -208,19 +208,19 @@ public abstract partial class TmjReaderBase
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text is not null)
|
if (text.HasValue)
|
||||||
{
|
{
|
||||||
text.ID = id;
|
text.Value.ID = id;
|
||||||
text.Name = name;
|
text.Value.Name = name;
|
||||||
text.Type = type;
|
text.Value.Type = type;
|
||||||
text.X = x;
|
text.Value.X = x;
|
||||||
text.Y = y;
|
text.Value.Y = y;
|
||||||
text.Width = width;
|
text.Value.Width = width;
|
||||||
text.Height = height;
|
text.Value.Height = height;
|
||||||
text.Rotation = rotation;
|
text.Value.Rotation = rotation;
|
||||||
text.Visible = visible;
|
text.Value.Visible = visible;
|
||||||
text.Template = template;
|
text.Value.Template = template;
|
||||||
text.Properties = properties;
|
text.Value.Properties = properties;
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,30 +250,30 @@ public abstract partial class TmjReaderBase
|
||||||
|
|
||||||
internal static TextObject ReadText(JsonElement element)
|
internal static TextObject ReadText(JsonElement element)
|
||||||
{
|
{
|
||||||
var bold = element.GetOptionalProperty<bool>("bold", false);
|
var bold = element.GetOptionalProperty<bool>("bold").GetValueOr(false);
|
||||||
var color = element.GetOptionalPropertyParseable<Color>("color", s => Color.Parse(s, CultureInfo.InvariantCulture), Color.Parse("#00000000", CultureInfo.InvariantCulture));
|
var color = element.GetOptionalPropertyParseable<Color>("color").GetValueOr(Color.Parse("#00000000", CultureInfo.InvariantCulture));
|
||||||
var fontfamily = element.GetOptionalProperty<string>("fontfamily", "sans-serif");
|
var fontfamily = element.GetOptionalProperty<string>("fontfamily").GetValueOr("sans-serif");
|
||||||
var halign = element.GetOptionalPropertyParseable<TextHorizontalAlignment>("halign", s => s switch
|
var halign = element.GetOptionalPropertyParseable<TextHorizontalAlignment>("halign", s => s switch
|
||||||
{
|
{
|
||||||
"left" => TextHorizontalAlignment.Left,
|
"left" => TextHorizontalAlignment.Left,
|
||||||
"center" => TextHorizontalAlignment.Center,
|
"center" => TextHorizontalAlignment.Center,
|
||||||
"right" => TextHorizontalAlignment.Right,
|
"right" => TextHorizontalAlignment.Right,
|
||||||
_ => throw new JsonException($"Unknown horizontal alignment '{s}'.")
|
_ => throw new JsonException($"Unknown horizontal alignment '{s}'.")
|
||||||
}, TextHorizontalAlignment.Left);
|
}).GetValueOr(TextHorizontalAlignment.Left);
|
||||||
var italic = element.GetOptionalProperty<bool>("italic", false);
|
var italic = element.GetOptionalProperty<bool>("italic").GetValueOr(false);
|
||||||
var kerning = element.GetOptionalProperty<bool>("kerning", true);
|
var kerning = element.GetOptionalProperty<bool>("kerning").GetValueOr(true);
|
||||||
var pixelsize = element.GetOptionalProperty<int>("pixelsize", 16);
|
var pixelsize = element.GetOptionalProperty<int>("pixelsize").GetValueOr(16);
|
||||||
var strikeout = element.GetOptionalProperty<bool>("strikeout", false);
|
var strikeout = element.GetOptionalProperty<bool>("strikeout").GetValueOr(false);
|
||||||
var text = element.GetRequiredProperty<string>("text");
|
var text = element.GetRequiredProperty<string>("text");
|
||||||
var underline = element.GetOptionalProperty<bool>("underline", false);
|
var underline = element.GetOptionalProperty<bool>("underline").GetValueOr(false);
|
||||||
var valign = element.GetOptionalPropertyParseable<TextVerticalAlignment>("valign", s => s switch
|
var valign = element.GetOptionalPropertyParseable<TextVerticalAlignment>("valign", s => s switch
|
||||||
{
|
{
|
||||||
"top" => TextVerticalAlignment.Top,
|
"top" => TextVerticalAlignment.Top,
|
||||||
"center" => TextVerticalAlignment.Center,
|
"center" => TextVerticalAlignment.Center,
|
||||||
"bottom" => TextVerticalAlignment.Bottom,
|
"bottom" => TextVerticalAlignment.Bottom,
|
||||||
_ => throw new JsonException($"Unknown vertical alignment '{s}'.")
|
_ => throw new JsonException($"Unknown vertical alignment '{s}'.")
|
||||||
}, TextVerticalAlignment.Top);
|
}).GetValueOr(TextVerticalAlignment.Top);
|
||||||
var wrap = element.GetOptionalProperty<bool>("wrap", false);
|
var wrap = element.GetOptionalProperty<bool>("wrap").GetValueOr(false);
|
||||||
|
|
||||||
return new TextObject
|
return new TextObject
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,9 +22,9 @@ public abstract partial class TmjReaderBase
|
||||||
"object" => PropertyType.Object,
|
"object" => PropertyType.Object,
|
||||||
"class" => PropertyType.Class,
|
"class" => PropertyType.Class,
|
||||||
_ => throw new JsonException("Invalid property type")
|
_ => throw new JsonException("Invalid property type")
|
||||||
}, PropertyType.String);
|
}).GetValueOr(PropertyType.String);
|
||||||
var propertyType = e.GetOptionalProperty<string?>("propertytype", null);
|
var propertyType = e.GetOptionalProperty<string>("propertytype");
|
||||||
if (propertyType is not null)
|
if (propertyType.HasValue)
|
||||||
{
|
{
|
||||||
return ReadPropertyWithCustomType(e);
|
return ReadPropertyWithCustomType(e);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public abstract partial class TmjReaderBase
|
||||||
|
|
||||||
internal IProperty ReadPropertyWithCustomType(JsonElement element)
|
internal IProperty ReadPropertyWithCustomType(JsonElement element)
|
||||||
{
|
{
|
||||||
var isClass = element.GetOptionalProperty<string?>("type", null) == "class";
|
var isClass = element.GetOptionalProperty<string>("type") == "class";
|
||||||
if (isClass)
|
if (isClass)
|
||||||
{
|
{
|
||||||
return ReadClassProperty(element);
|
return ReadClassProperty(element);
|
||||||
|
@ -66,7 +66,7 @@ public abstract partial class TmjReaderBase
|
||||||
if (customTypeDef is CustomClassDefinition ccd)
|
if (customTypeDef is CustomClassDefinition ccd)
|
||||||
{
|
{
|
||||||
var propsInType = Helpers.CreateInstanceOfCustomClass(ccd, _customTypeResolver);
|
var propsInType = Helpers.CreateInstanceOfCustomClass(ccd, _customTypeResolver);
|
||||||
var props = element.GetOptionalPropertyCustom<List<IProperty>>("value", e => ReadPropertiesInsideClass(e, ccd), []);
|
var props = element.GetOptionalPropertyCustom<List<IProperty>>("value", e => ReadPropertiesInsideClass(e, ccd)).GetValueOr([]);
|
||||||
var mergedProps = Helpers.MergeProperties(propsInType, props);
|
var mergedProps = Helpers.MergeProperties(propsInType, props);
|
||||||
|
|
||||||
return new ClassProperty
|
return new ClassProperty
|
||||||
|
@ -120,7 +120,7 @@ public abstract partial class TmjReaderBase
|
||||||
"string" => PropertyType.String,
|
"string" => PropertyType.String,
|
||||||
"int" => PropertyType.Int,
|
"int" => PropertyType.Int,
|
||||||
_ => throw new JsonException("Invalid property type")
|
_ => throw new JsonException("Invalid property type")
|
||||||
}, PropertyType.String);
|
}).GetValueOr(PropertyType.String);
|
||||||
var customTypeDef = _customTypeResolver(propertyType);
|
var customTypeDef = _customTypeResolver(propertyType);
|
||||||
|
|
||||||
if (customTypeDef is not CustomEnumDefinition ced)
|
if (customTypeDef is not CustomEnumDefinition ced)
|
||||||
|
|
|
@ -7,7 +7,7 @@ public abstract partial class TmjReaderBase
|
||||||
internal Template ReadTemplate(JsonElement element)
|
internal Template ReadTemplate(JsonElement element)
|
||||||
{
|
{
|
||||||
var type = element.GetRequiredProperty<string>("type");
|
var type = element.GetRequiredProperty<string>("type");
|
||||||
var tileset = element.GetOptionalPropertyCustom<Tileset?>("tileset", ReadTileset, null);
|
var tileset = element.GetOptionalPropertyCustom<Tileset>("tileset", e => ReadTileset(e));
|
||||||
var @object = element.GetRequiredPropertyCustom<DotTiled.Object>("object", ReadObject);
|
var @object = element.GetRequiredPropertyCustom<DotTiled.Object>("object", ReadObject);
|
||||||
|
|
||||||
return new Template
|
return new Template
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Globalization;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace DotTiled.Serialization.Tmj;
|
namespace DotTiled.Serialization.Tmj;
|
||||||
|
@ -7,43 +6,43 @@ public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
internal TileLayer ReadTileLayer(JsonElement element)
|
internal TileLayer ReadTileLayer(JsonElement element)
|
||||||
{
|
{
|
||||||
var compression = element.GetOptionalPropertyParseable<DataCompression?>("compression", s => s switch
|
|
||||||
{
|
|
||||||
"zlib" => DataCompression.ZLib,
|
|
||||||
"gzip" => DataCompression.GZip,
|
|
||||||
"" => null,
|
|
||||||
_ => throw new JsonException($"Unsupported compression '{s}'.")
|
|
||||||
}, null);
|
|
||||||
var encoding = element.GetOptionalPropertyParseable<DataEncoding>("encoding", s => s switch
|
var encoding = element.GetOptionalPropertyParseable<DataEncoding>("encoding", s => s switch
|
||||||
{
|
{
|
||||||
"csv" => DataEncoding.Csv,
|
"csv" => DataEncoding.Csv,
|
||||||
"base64" => DataEncoding.Base64,
|
"base64" => DataEncoding.Base64,
|
||||||
_ => throw new JsonException($"Unsupported encoding '{s}'.")
|
_ => throw new JsonException($"Unsupported encoding '{s}'.")
|
||||||
}, DataEncoding.Csv);
|
}).GetValueOr(DataEncoding.Csv);
|
||||||
var chunks = element.GetOptionalPropertyCustom<Data?>("chunks", e => ReadDataAsChunks(e, compression, encoding), null);
|
var compression = element.GetOptionalPropertyParseable<DataCompression>("compression", s => s switch
|
||||||
var @class = element.GetOptionalProperty<string>("class", "");
|
{
|
||||||
var data = element.GetOptionalPropertyCustom<Data?>("data", e => ReadDataWithoutChunks(e, compression, encoding), null);
|
"zlib" => DataCompression.ZLib,
|
||||||
|
"gzip" => DataCompression.GZip,
|
||||||
|
"" => Optional<DataCompression>.Empty,
|
||||||
|
_ => throw new JsonException($"Unsupported compression '{s}'.")
|
||||||
|
});
|
||||||
|
var chunks = element.GetOptionalPropertyCustom<Data>("chunks", e => ReadDataAsChunks(e, compression, encoding));
|
||||||
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
|
var data = element.GetOptionalPropertyCustom<Data>("data", e => ReadDataWithoutChunks(e, compression, encoding));
|
||||||
var height = element.GetRequiredProperty<uint>("height");
|
var height = element.GetRequiredProperty<uint>("height");
|
||||||
var id = element.GetRequiredProperty<uint>("id");
|
var id = element.GetRequiredProperty<uint>("id");
|
||||||
var name = element.GetRequiredProperty<string>("name");
|
var name = element.GetRequiredProperty<string>("name");
|
||||||
var offsetX = element.GetOptionalProperty<float>("offsetx", 0.0f);
|
var offsetX = element.GetOptionalProperty<float>("offsetx").GetValueOr(0.0f);
|
||||||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
var offsetY = element.GetOptionalProperty<float>("offsety").GetValueOr(0.0f);
|
||||||
var opacity = element.GetOptionalProperty<float>("opacity", 1.0f);
|
var opacity = element.GetOptionalProperty<float>("opacity").GetValueOr(1.0f);
|
||||||
var parallaxx = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
var parallaxx = element.GetOptionalProperty<float>("parallaxx").GetValueOr(1.0f);
|
||||||
var parallaxy = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
var parallaxy = element.GetOptionalProperty<float>("parallaxy").GetValueOr(1.0f);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
var repeatX = element.GetOptionalProperty<bool>("repeatx", false);
|
var repeatX = element.GetOptionalProperty<bool>("repeatx").GetValueOr(false);
|
||||||
var repeatY = element.GetOptionalProperty<bool>("repeaty", false);
|
var repeatY = element.GetOptionalProperty<bool>("repeaty").GetValueOr(false);
|
||||||
var startX = element.GetOptionalProperty<int>("startx", 0);
|
var startX = element.GetOptionalProperty<int>("startx").GetValueOr(0);
|
||||||
var startY = element.GetOptionalProperty<int>("starty", 0);
|
var startY = element.GetOptionalProperty<int>("starty").GetValueOr(0);
|
||||||
var tintColor = element.GetOptionalPropertyParseable<Color?>("tintcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var tintColor = element.GetOptionalPropertyParseable<Color>("tintcolor");
|
||||||
var transparentColor = element.GetOptionalPropertyParseable<Color?>("transparentcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var transparentColor = element.GetOptionalPropertyParseable<Color>("transparentcolor");
|
||||||
var visible = element.GetOptionalProperty<bool>("visible", true);
|
var visible = element.GetOptionalProperty<bool>("visible").GetValueOr(true);
|
||||||
var width = element.GetRequiredProperty<uint>("width");
|
var width = element.GetRequiredProperty<uint>("width");
|
||||||
var x = element.GetRequiredProperty<uint>("x");
|
var x = element.GetRequiredProperty<uint>("x");
|
||||||
var y = element.GetRequiredProperty<uint>("y");
|
var y = element.GetRequiredProperty<uint>("y");
|
||||||
|
|
||||||
if ((data ?? chunks) is null)
|
if (!data.HasValue && !chunks.HasValue)
|
||||||
throw new JsonException("Tile layer does not contain data.");
|
throw new JsonException("Tile layer does not contain data.");
|
||||||
|
|
||||||
return new TileLayer
|
return new TileLayer
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace DotTiled.Serialization.Tmj;
|
namespace DotTiled.Serialization.Tmj;
|
||||||
|
|
||||||
public abstract partial class TmjReaderBase
|
public abstract partial class TmjReaderBase
|
||||||
{
|
{
|
||||||
internal Tileset ReadTileset(JsonElement element)
|
internal Tileset ReadTileset(
|
||||||
|
JsonElement element,
|
||||||
|
Optional<string> parentVersion = null,
|
||||||
|
Optional<string> parentTiledVersion = null)
|
||||||
{
|
{
|
||||||
var backgroundColor = element.GetOptionalPropertyParseable<Color?>("backgroundcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var backgroundColor = element.GetOptionalPropertyParseable<Color>("backgroundcolor");
|
||||||
var @class = element.GetOptionalProperty<string>("class", "");
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var columns = element.GetOptionalProperty<uint?>("columns", null);
|
var columns = element.GetOptionalProperty<uint>("columns");
|
||||||
var fillMode = element.GetOptionalPropertyParseable<FillMode>("fillmode", s => s switch
|
var fillMode = element.GetOptionalPropertyParseable<FillMode>("fillmode", s => s switch
|
||||||
{
|
{
|
||||||
"stretch" => FillMode.Stretch,
|
"stretch" => FillMode.Stretch,
|
||||||
"preserve-aspect-fit" => FillMode.PreserveAspectFit,
|
"preserve-aspect-fit" => FillMode.PreserveAspectFit,
|
||||||
_ => throw new JsonException($"Unknown fill mode '{s}'")
|
_ => throw new JsonException($"Unknown fill mode '{s}'")
|
||||||
}, FillMode.Stretch);
|
}).GetValueOr(FillMode.Stretch);
|
||||||
var firstGID = element.GetOptionalProperty<uint?>("firstgid", null);
|
var firstGID = element.GetOptionalProperty<uint>("firstgid");
|
||||||
var grid = element.GetOptionalPropertyCustom<Grid?>("grid", ReadGrid, null);
|
var grid = element.GetOptionalPropertyCustom<Grid>("grid", ReadGrid);
|
||||||
var image = element.GetOptionalProperty<string?>("image", null);
|
var image = element.GetOptionalProperty<string>("image");
|
||||||
var imageHeight = element.GetOptionalProperty<uint?>("imageheight", null);
|
var imageHeight = element.GetOptionalProperty<uint>("imageheight");
|
||||||
var imageWidth = element.GetOptionalProperty<uint?>("imagewidth", null);
|
var imageWidth = element.GetOptionalProperty<uint>("imagewidth");
|
||||||
var margin = element.GetOptionalProperty<uint?>("margin", null);
|
var margin = element.GetOptionalProperty<uint>("margin");
|
||||||
var name = element.GetOptionalProperty<string?>("name", null);
|
var name = element.GetOptionalProperty<string>("name");
|
||||||
var objectAlignment = element.GetOptionalPropertyParseable<ObjectAlignment>("objectalignment", s => s switch
|
var objectAlignment = element.GetOptionalPropertyParseable<ObjectAlignment>("objectalignment", s => s switch
|
||||||
{
|
{
|
||||||
"unspecified" => ObjectAlignment.Unspecified,
|
"unspecified" => ObjectAlignment.Unspecified,
|
||||||
|
@ -37,29 +39,29 @@ public abstract partial class TmjReaderBase
|
||||||
"bottom" => ObjectAlignment.Bottom,
|
"bottom" => ObjectAlignment.Bottom,
|
||||||
"bottomright" => ObjectAlignment.BottomRight,
|
"bottomright" => ObjectAlignment.BottomRight,
|
||||||
_ => throw new JsonException($"Unknown object alignment '{s}'")
|
_ => throw new JsonException($"Unknown object alignment '{s}'")
|
||||||
}, ObjectAlignment.Unspecified);
|
}).GetValueOr(ObjectAlignment.Unspecified);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
var source = element.GetOptionalProperty<string?>("source", null);
|
var source = element.GetOptionalProperty<string>("source");
|
||||||
var spacing = element.GetOptionalProperty<uint?>("spacing", null);
|
var spacing = element.GetOptionalProperty<uint>("spacing");
|
||||||
var tileCount = element.GetOptionalProperty<uint?>("tilecount", null);
|
var tileCount = element.GetOptionalProperty<uint>("tilecount");
|
||||||
var tiledVersion = element.GetOptionalProperty<string?>("tiledversion", null);
|
var tiledVersion = element.GetOptionalProperty<string>("tiledversion").GetValueOrOptional(parentTiledVersion);
|
||||||
var tileHeight = element.GetOptionalProperty<uint?>("tileheight", null);
|
var tileHeight = element.GetOptionalProperty<uint>("tileheight");
|
||||||
var tileOffset = element.GetOptionalPropertyCustom<TileOffset?>("tileoffset", ReadTileOffset, null);
|
var tileOffset = element.GetOptionalPropertyCustom<TileOffset>("tileoffset", ReadTileOffset);
|
||||||
var tileRenderSize = element.GetOptionalPropertyParseable<TileRenderSize>("tilerendersize", s => s switch
|
var tileRenderSize = element.GetOptionalPropertyParseable<TileRenderSize>("tilerendersize", s => s switch
|
||||||
{
|
{
|
||||||
"tile" => TileRenderSize.Tile,
|
"tile" => TileRenderSize.Tile,
|
||||||
"grid" => TileRenderSize.Grid,
|
"grid" => TileRenderSize.Grid,
|
||||||
_ => throw new JsonException($"Unknown tile render size '{s}'")
|
_ => throw new JsonException($"Unknown tile render size '{s}'")
|
||||||
}, TileRenderSize.Tile);
|
}).GetValueOr(TileRenderSize.Tile);
|
||||||
var tiles = element.GetOptionalPropertyCustom<List<Tile>>("tiles", ReadTiles, []);
|
var tiles = element.GetOptionalPropertyCustom<List<Tile>>("tiles", ReadTiles).GetValueOr([]);
|
||||||
var tileWidth = element.GetOptionalProperty<uint?>("tilewidth", null);
|
var tileWidth = element.GetOptionalProperty<uint>("tilewidth");
|
||||||
var transparentColor = element.GetOptionalPropertyParseable<Color?>("transparentcolor", s => Color.Parse(s, CultureInfo.InvariantCulture), null);
|
var transparentColor = element.GetOptionalPropertyParseable<Color>("transparentcolor");
|
||||||
var type = element.GetOptionalProperty<string?>("type", null);
|
var type = element.GetOptionalProperty<string>("type");
|
||||||
var version = element.GetOptionalProperty<string?>("version", null);
|
var version = element.GetOptionalProperty<string>("version").GetValueOrOptional(parentVersion);
|
||||||
var transformations = element.GetOptionalPropertyCustom<Transformations?>("transformations", ReadTransformations, null);
|
var transformations = element.GetOptionalPropertyCustom<Transformations>("transformations", ReadTransformations);
|
||||||
var wangsets = element.GetOptionalPropertyCustom<List<Wangset>?>("wangsets", el => el.GetValueAsList<Wangset>(e => ReadWangset(e)), null);
|
var wangsets = element.GetOptionalPropertyCustom<List<Wangset>>("wangsets", el => el.GetValueAsList<Wangset>(e => ReadWangset(e))).GetValueOr([]);
|
||||||
|
|
||||||
if (source is not null)
|
if (source.HasValue)
|
||||||
{
|
{
|
||||||
var resolvedTileset = _externalTilesetResolver(source);
|
var resolvedTileset = _externalTilesetResolver(source);
|
||||||
resolvedTileset.FirstGID = firstGID;
|
resolvedTileset.FirstGID = firstGID;
|
||||||
|
@ -67,49 +69,48 @@ public abstract partial class TmjReaderBase
|
||||||
return resolvedTileset;
|
return resolvedTileset;
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageModel = image is not null ? new Image
|
Optional<Image> imageModel = image.HasValue ? new Image
|
||||||
{
|
{
|
||||||
Format = Helpers.ParseImageFormatFromSource(image),
|
Format = Helpers.ParseImageFormatFromSource(image),
|
||||||
Source = image,
|
Source = image,
|
||||||
Height = imageHeight,
|
Height = imageHeight,
|
||||||
Width = imageWidth,
|
Width = imageWidth,
|
||||||
TransparentColor = transparentColor
|
TransparentColor = transparentColor
|
||||||
} : null;
|
} : Optional<Image>.Empty;
|
||||||
|
|
||||||
return null;
|
return new Tileset
|
||||||
// return new Tileset
|
{
|
||||||
// {
|
Class = @class,
|
||||||
// Class = @class,
|
Columns = columns,
|
||||||
// Columns = columns,
|
FillMode = fillMode,
|
||||||
// FillMode = fillMode,
|
FirstGID = firstGID,
|
||||||
// FirstGID = firstGID,
|
Grid = grid,
|
||||||
// Grid = grid,
|
Image = imageModel,
|
||||||
// Image = imageModel,
|
Margin = margin,
|
||||||
// Margin = margin,
|
Name = name,
|
||||||
// Name = name,
|
ObjectAlignment = objectAlignment,
|
||||||
// ObjectAlignment = objectAlignment,
|
Properties = properties,
|
||||||
// Properties = properties,
|
Source = source,
|
||||||
// Source = source,
|
Spacing = spacing,
|
||||||
// Spacing = spacing,
|
TileCount = tileCount,
|
||||||
// TileCount = tileCount,
|
TiledVersion = tiledVersion,
|
||||||
// TiledVersion = tiledVersion,
|
TileHeight = tileHeight,
|
||||||
// TileHeight = tileHeight,
|
TileOffset = tileOffset,
|
||||||
// TileOffset = tileOffset,
|
RenderSize = tileRenderSize,
|
||||||
// RenderSize = tileRenderSize,
|
Tiles = tiles,
|
||||||
// Tiles = tiles,
|
TileWidth = tileWidth,
|
||||||
// TileWidth = tileWidth,
|
Version = version,
|
||||||
// Version = version,
|
Wangsets = wangsets,
|
||||||
// Wangsets = wangsets,
|
Transformations = transformations
|
||||||
// Transformations = transformations
|
};
|
||||||
// };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Transformations ReadTransformations(JsonElement element)
|
internal static Transformations ReadTransformations(JsonElement element)
|
||||||
{
|
{
|
||||||
var hFlip = element.GetOptionalProperty<bool>("hflip", false);
|
var hFlip = element.GetOptionalProperty<bool>("hflip").GetValueOr(false);
|
||||||
var vFlip = element.GetOptionalProperty<bool>("vflip", false);
|
var vFlip = element.GetOptionalProperty<bool>("vflip").GetValueOr(false);
|
||||||
var rotate = element.GetOptionalProperty<bool>("rotate", false);
|
var rotate = element.GetOptionalProperty<bool>("rotate").GetValueOr(false);
|
||||||
var preferUntransformed = element.GetOptionalProperty<bool>("preferuntransformed", false);
|
var preferUntransformed = element.GetOptionalProperty<bool>("preferuntransformed").GetValueOr(false);
|
||||||
|
|
||||||
return new Transformations
|
return new Transformations
|
||||||
{
|
{
|
||||||
|
@ -127,7 +128,7 @@ public abstract partial class TmjReaderBase
|
||||||
"orthogonal" => GridOrientation.Orthogonal,
|
"orthogonal" => GridOrientation.Orthogonal,
|
||||||
"isometric" => GridOrientation.Isometric,
|
"isometric" => GridOrientation.Isometric,
|
||||||
_ => throw new JsonException($"Unknown grid orientation '{s}'")
|
_ => throw new JsonException($"Unknown grid orientation '{s}'")
|
||||||
}, GridOrientation.Orthogonal);
|
}).GetValueOr(GridOrientation.Orthogonal);
|
||||||
var height = element.GetRequiredProperty<uint>("height");
|
var height = element.GetRequiredProperty<uint>("height");
|
||||||
var width = element.GetRequiredProperty<uint>("width");
|
var width = element.GetRequiredProperty<uint>("width");
|
||||||
|
|
||||||
|
@ -154,28 +155,27 @@ public abstract partial class TmjReaderBase
|
||||||
internal List<Tile> ReadTiles(JsonElement element) =>
|
internal List<Tile> ReadTiles(JsonElement element) =>
|
||||||
element.GetValueAsList<Tile>(e =>
|
element.GetValueAsList<Tile>(e =>
|
||||||
{
|
{
|
||||||
var animation = e.GetOptionalPropertyCustom<List<Frame>?>("animation", e => e.GetValueAsList<Frame>(ReadFrame), null);
|
var animation = e.GetOptionalPropertyCustom<List<Frame>>("animation", e => e.GetValueAsList<Frame>(ReadFrame)).GetValueOr([]);
|
||||||
var id = e.GetRequiredProperty<uint>("id");
|
var id = e.GetRequiredProperty<uint>("id");
|
||||||
var image = e.GetOptionalProperty<string?>("image", null);
|
var image = e.GetOptionalProperty<string>("image");
|
||||||
var imageHeight = e.GetOptionalProperty<uint?>("imageheight", null);
|
var imageHeight = e.GetOptionalProperty<uint>("imageheight");
|
||||||
var imageWidth = e.GetOptionalProperty<uint?>("imagewidth", null);
|
var imageWidth = e.GetOptionalProperty<uint>("imagewidth");
|
||||||
var x = e.GetOptionalProperty<uint>("x", 0);
|
var x = e.GetOptionalProperty<uint>("x").GetValueOr(0);
|
||||||
var y = e.GetOptionalProperty<uint>("y", 0);
|
var y = e.GetOptionalProperty<uint>("y").GetValueOr(0);
|
||||||
var width = e.GetOptionalProperty<uint>("width", imageWidth ?? 0);
|
var width = e.GetOptionalProperty<uint>("width").GetValueOr(imageWidth.GetValueOr(0));
|
||||||
var height = e.GetOptionalProperty<uint>("height", imageHeight ?? 0);
|
var height = e.GetOptionalProperty<uint>("height").GetValueOr(imageHeight.GetValueOr(0));
|
||||||
var objectGroup = e.GetOptionalPropertyCustom<ObjectLayer?>("objectgroup", e => ReadObjectLayer(e), null);
|
var objectGroup = e.GetOptionalPropertyCustom<ObjectLayer>("objectgroup", e => ReadObjectLayer(e));
|
||||||
var probability = e.GetOptionalProperty<float>("probability", 0.0f);
|
var probability = e.GetOptionalProperty<float>("probability").GetValueOr(0.0f);
|
||||||
var properties = e.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = e.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
// var terrain, replaced by wangsets
|
var type = e.GetOptionalProperty<string>("type").GetValueOr("");
|
||||||
var type = e.GetOptionalProperty<string>("type", "");
|
|
||||||
|
|
||||||
var imageModel = image != null ? new Image
|
Optional<Image> imageModel = image.HasValue ? new Image
|
||||||
{
|
{
|
||||||
Format = Helpers.ParseImageFormatFromSource(image),
|
Format = Helpers.ParseImageFormatFromSource(image),
|
||||||
Source = image,
|
Source = image,
|
||||||
Height = imageHeight ?? 0,
|
Height = imageHeight ?? 0,
|
||||||
Width = imageWidth ?? 0
|
Width = imageWidth ?? 0
|
||||||
} : null;
|
} : Optional<Image>.Empty;
|
||||||
|
|
||||||
return new Tile
|
return new Tile
|
||||||
{
|
{
|
||||||
|
@ -207,13 +207,13 @@ public abstract partial class TmjReaderBase
|
||||||
|
|
||||||
internal Wangset ReadWangset(JsonElement element)
|
internal Wangset ReadWangset(JsonElement element)
|
||||||
{
|
{
|
||||||
var @clalss = element.GetOptionalProperty<string>("class", "");
|
var @clalss = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var colors = element.GetOptionalPropertyCustom<List<WangColor>>("colors", e => e.GetValueAsList<WangColor>(el => ReadWangColor(el)), []);
|
var colors = element.GetOptionalPropertyCustom<List<WangColor>>("colors", e => e.GetValueAsList<WangColor>(el => ReadWangColor(el))).GetValueOr([]);
|
||||||
var name = element.GetRequiredProperty<string>("name");
|
var name = element.GetRequiredProperty<string>("name");
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
var tile = element.GetOptionalProperty<int>("tile", 0);
|
var tile = element.GetOptionalProperty<int>("tile").GetValueOr(0);
|
||||||
var type = element.GetOptionalProperty<string>("type", "");
|
var type = element.GetOptionalProperty<string>("type").GetValueOr("");
|
||||||
var wangTiles = element.GetOptionalPropertyCustom<List<WangTile>>("wangtiles", e => e.GetValueAsList<WangTile>(ReadWangTile), []);
|
var wangTiles = element.GetOptionalPropertyCustom<List<WangTile>>("wangtiles", e => e.GetValueAsList<WangTile>(ReadWangTile)).GetValueOr([]);
|
||||||
|
|
||||||
return new Wangset
|
return new Wangset
|
||||||
{
|
{
|
||||||
|
@ -228,12 +228,12 @@ public abstract partial class TmjReaderBase
|
||||||
|
|
||||||
internal WangColor ReadWangColor(JsonElement element)
|
internal WangColor ReadWangColor(JsonElement element)
|
||||||
{
|
{
|
||||||
var @class = element.GetOptionalProperty<string>("class", "");
|
var @class = element.GetOptionalProperty<string>("class").GetValueOr("");
|
||||||
var color = element.GetRequiredPropertyParseable<Color>("color", s => Color.Parse(s, CultureInfo.InvariantCulture));
|
var color = element.GetRequiredPropertyParseable<Color>("color");
|
||||||
var name = element.GetRequiredProperty<string>("name");
|
var name = element.GetRequiredProperty<string>("name");
|
||||||
var probability = element.GetOptionalProperty<float>("probability", 1.0f);
|
var probability = element.GetOptionalProperty<float>("probability").GetValueOr(1.0f);
|
||||||
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties, []);
|
var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]);
|
||||||
var tile = element.GetOptionalProperty<int>("tile", 0);
|
var tile = element.GetOptionalProperty<int>("tile").GetValueOr(0);
|
||||||
|
|
||||||
return new WangColor
|
return new WangColor
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ public abstract partial class TmjReaderBase
|
||||||
internal static WangTile ReadWangTile(JsonElement element)
|
internal static WangTile ReadWangTile(JsonElement element)
|
||||||
{
|
{
|
||||||
var tileID = element.GetRequiredProperty<uint>("tileid");
|
var tileID = element.GetRequiredProperty<uint>("tileid");
|
||||||
var wangID = element.GetOptionalPropertyCustom<List<byte>>("wangid", e => e.GetValueAsList<byte>(el => (byte)el.GetUInt32()), []);
|
var wangID = element.GetOptionalPropertyCustom<List<byte>>("wangid", e => e.GetValueAsList<byte>(el => (byte)el.GetUInt32())).GetValueOr([]);
|
||||||
|
|
||||||
return new WangTile
|
return new WangTile
|
||||||
{
|
{
|
||||||
|
|
|
@ -301,10 +301,10 @@ public abstract partial class TmxReaderBase
|
||||||
// No attributes
|
// No attributes
|
||||||
|
|
||||||
// At most one of
|
// At most one of
|
||||||
Tileset? tileset = null;
|
Tileset tileset = null;
|
||||||
|
|
||||||
// Should contain exactly one of
|
// Should contain exactly one of
|
||||||
DotTiled.Object? obj = null;
|
DotTiled.Object obj = null;
|
||||||
|
|
||||||
_reader.ProcessChildren("template", (r, elementName) => elementName switch
|
_reader.ProcessChildren("template", (r, elementName) => elementName switch
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ public class Template
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the template represents a tile object, this property will contain the tileset that the tile belongs to.
|
/// If the template represents a tile object, this property will contain the tileset that the tile belongs to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Tileset? Tileset { get; set; }
|
public Optional<Tileset> Tileset { get; set; } = Optional<Tileset>.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The object that this template represents.
|
/// The object that this template represents.
|
||||||
|
|
Loading…
Add table
Reference in a new issue