From 0ad1347bc183e5e765b9e4b375a170915e42aef4 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Wed, 4 Sep 2024 22:11:45 +0200 Subject: [PATCH] Map now resolves props from class --- src/DotTiled.Tests/Serialization/TestData.cs | 1 + .../map-with-class-and-props.tmx | 15 ++++ .../Map/map-with-class/map-with-class.cs | 83 +++++++++++++++++++ .../Map/map-with-class/map-with-class.tmj | 33 ++++++++ .../Map/map-with-class/map-with-class.tmx | 12 +++ src/DotTiled/Serialization/Helpers.cs | 12 +++ .../Serialization/Tmj/TmjReaderBase.Map.cs | 4 +- .../Serialization/Tmx/TmxReaderBase.Map.cs | 2 +- 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/DotTiled.Tests/Serialization/TestData/Map/map-with-class-and-props/map-with-class-and-props.tmx create mode 100644 src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.cs create mode 100644 src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmj create mode 100644 src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmx diff --git a/src/DotTiled.Tests/Serialization/TestData.cs b/src/DotTiled.Tests/Serialization/TestData.cs index 7f68c9e..3e58e6d 100644 --- a/src/DotTiled.Tests/Serialization/TestData.cs +++ b/src/DotTiled.Tests/Serialization/TestData.cs @@ -41,5 +41,6 @@ public static partial class TestData ["Serialization/TestData/Map/map_external_tileset_wangset/map-external-tileset-wangset", (string f) => MapExternalTilesetWangset(f), Array.Empty()], ["Serialization/TestData/Map/map_with_many_layers/map-with-many-layers", (string f) => MapWithManyLayers(f), Array.Empty()], ["Serialization/TestData/Map/map_with_deep_props/map-with-deep-props", (string f) => MapWithDeepProps(), MapWithDeepPropsCustomTypeDefinitions()], + ["Serialization/TestData/Map/map_with_class/map-with-class", (string f) => MapWithClass(), MapWithClassCustomTypeDefinitions()], ]; } diff --git a/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class-and-props/map-with-class-and-props.tmx b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class-and-props/map-with-class-and-props.tmx new file mode 100644 index 0000000..4da805d --- /dev/null +++ b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class-and-props/map-with-class-and-props.tmx @@ -0,0 +1,15 @@ + + + + + + + +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0 + + + diff --git a/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.cs b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.cs new file mode 100644 index 0000000..80d50a5 --- /dev/null +++ b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.cs @@ -0,0 +1,83 @@ +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithClass() => new Map + { + Class = "TestClass", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = new Color { R = 0, G = 0, B = 0, A = 0 }, + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + GlobalTileIDs = new Optional([ + 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 = new Optional([ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, 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 BoolProperty + { + Name = "classbool", + Value = true + }, + new StringProperty + { + Name = "stringbool", + Value = "Hello there default value" + } + ] + }; + + public static IReadOnlyCollection MapWithClassCustomTypeDefinitions() => [ + new CustomClassDefinition + { + Name = "TestClass", + UseAs = CustomClassUseAs.Map, + Members = [ + new BoolProperty + { + Name = "classbool", + Value = true + }, + new StringProperty + { + Name = "stringbool", + Value = "Hello there default value" + } + ] + }, + ]; +} diff --git a/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmj b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmj new file mode 100644 index 0000000..480e3bb --- /dev/null +++ b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmj @@ -0,0 +1,33 @@ +{ "class":"TestClass", + "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 +} \ No newline at end of file diff --git a/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmx b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmx new file mode 100644 index 0000000..b3382eb --- /dev/null +++ b/src/DotTiled.Tests/Serialization/TestData/Map/map-with-class/map-with-class.tmx @@ -0,0 +1,12 @@ + + + + +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0, +0,0,0,0,0 + + + diff --git a/src/DotTiled/Serialization/Helpers.cs b/src/DotTiled/Serialization/Helpers.cs index b259d15..e784b80 100644 --- a/src/DotTiled/Serialization/Helpers.cs +++ b/src/DotTiled/Serialization/Helpers.cs @@ -86,6 +86,18 @@ internal static partial class Helpers }; } + internal static List ResolveClassProperties(string className, Func customTypeResolver) + { + if (string.IsNullOrWhiteSpace(className)) + return null; + + var customType = customTypeResolver(className) ?? throw new InvalidOperationException($"Could not resolve custom type '{className}'."); + if (customType is not CustomClassDefinition ccd) + throw new InvalidOperationException($"Custom type '{className}' is not a class."); + + return CreateInstanceOfCustomClass(ccd, customTypeResolver); + } + internal static List CreateInstanceOfCustomClass( CustomClassDefinition customClassDefinition, Func customTypeResolver) diff --git a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Map.cs b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Map.cs index eaa0a9e..8779dde 100644 --- a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Map.cs +++ b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Map.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Text.Json; namespace DotTiled.Serialization.Tmj; @@ -52,7 +53,8 @@ public abstract partial class TmjReaderBase var nextObjectID = element.GetRequiredProperty("nextobjectid"); var infinite = element.GetOptionalProperty("infinite").GetValueOr(false); - var properties = element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]); + var classProps = Helpers.ResolveClassProperties(@class, _customTypeResolver); + var properties = Helpers.MergeProperties(element.GetOptionalPropertyCustom("properties", ReadProperties).GetValueOr([]), classProps).ToList(); List layers = element.GetOptionalPropertyCustom>("layers", e => e.GetValueAsList(el => ReadLayer(el))).GetValueOr([]); List tilesets = element.GetOptionalPropertyCustom>("tilesets", e => e.GetValueAsList(el => ReadTileset(el, version, tiledVersion))).GetValueOr([]); diff --git a/src/DotTiled/Serialization/Tmx/TmxReaderBase.Map.cs b/src/DotTiled/Serialization/Tmx/TmxReaderBase.Map.cs index 3ba3eed..a16b715 100644 --- a/src/DotTiled/Serialization/Tmx/TmxReaderBase.Map.cs +++ b/src/DotTiled/Serialization/Tmx/TmxReaderBase.Map.cs @@ -56,7 +56,7 @@ public abstract partial class TmxReaderBase var infinite = _reader.GetOptionalAttributeParseable("infinite").GetValueOr(0) == 1; // At most one of - List properties = null; + List properties = Helpers.ResolveClassProperties(@class, _customTypeResolver); // Any number of List layers = [];