Added same CustomTypeDefinition stuff to Tmx

This commit is contained in:
Daniel Cronqvist 2024-08-10 21:36:13 +02:00
parent e9cf6e01f6
commit bb74d3ccee
9 changed files with 213 additions and 66 deletions

View file

@ -15,7 +15,7 @@ public partial class TmxMapReaderTests
// Act // Act
Action act = () => Action act = () =>
{ {
using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver); using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []);
}; };
// Assert // Assert
@ -34,7 +34,7 @@ public partial class TmxMapReaderTests
// Act // Act
Action act = () => Action act = () =>
{ {
using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver); using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []);
}; };
// Assert // Assert
@ -53,7 +53,7 @@ public partial class TmxMapReaderTests
// Act // Act
Action act = () => Action act = () =>
{ {
using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver); using var _ = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []);
}; };
// Assert // Assert
@ -70,7 +70,7 @@ public partial class TmxMapReaderTests
Func<string, Template> externalTemplateResolver = (_) => new Template { Object = new RectangleObject { } }; Func<string, Template> externalTemplateResolver = (_) => new Template { Object = new RectangleObject { } };
// Act // Act
using var tmxMapReader = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver); using var tmxMapReader = new TmxMapReader(xmlReader, externalTilesetResolver, externalTemplateResolver, []);
// Assert // Assert
Assert.NotNull(tmxMapReader); Assert.NotNull(tmxMapReader);
@ -91,20 +91,55 @@ public partial class TmxMapReaderTests
public void TmxMapReaderReadMap_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) public void TmxMapReaderReadMap_ValidXmlNoExternalTilesets_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap)
{ {
// Arrange // Arrange
CustomTypeDefinition[] customTypeDefinitions = [
new CustomClassDefinition
{
Name = "TestClass",
ID = 1,
UseAs = CustomClassUseAs.Property,
Members = [
new StringProperty
{
Name = "Name",
Value = ""
},
new FloatProperty
{
Name = "Amount",
Value = 0f
}
]
},
new CustomClassDefinition
{
Name = "Test",
ID = 2,
UseAs = CustomClassUseAs.All,
Members = [
new ClassProperty
{
Name = "Yep",
PropertyType = "TestClass",
Properties = []
}
]
}
];
using var reader = TestData.GetXmlReaderFor(testDataFile); using var reader = TestData.GetXmlReaderFor(testDataFile);
static Template ResolveTemplate(string source) Template ResolveTemplate(string source)
{ {
using var xmlTemplateReader = TestData.GetXmlReaderFor($"Serialization.TestData.Template.{source}"); using var xmlTemplateReader = TestData.GetXmlReaderFor($"Serialization.TestData.Template.{source}");
using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate); using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate, customTypeDefinitions);
return templateReader.ReadTemplate(); return templateReader.ReadTemplate();
} }
static Tileset ResolveTileset(string source) Tileset ResolveTileset(string source)
{ {
using var xmlTilesetReader = TestData.GetXmlReaderFor($"Serialization.TestData.Tileset.{source}"); using var xmlTilesetReader = TestData.GetXmlReaderFor($"Serialization.TestData.Tileset.{source}");
using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate); using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate, customTypeDefinitions);
return tilesetReader.ReadTileset(); return tilesetReader.ReadTileset();
} }
using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate); using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate, customTypeDefinitions);
// Act // Act
var map = mapReader.ReadMap(); var map = mapReader.ReadMap();
@ -125,20 +160,54 @@ public partial class TmxMapReaderTests
public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap) public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(string testDataFile, Map expectedMap)
{ {
// Arrange // Arrange
CustomTypeDefinition[] customTypeDefinitions = [
new CustomClassDefinition
{
Name = "TestClass",
ID = 1,
UseAs = CustomClassUseAs.Property,
Members = [
new StringProperty
{
Name = "Name",
Value = ""
},
new FloatProperty
{
Name = "Amount",
Value = 0f
}
]
},
new CustomClassDefinition
{
Name = "Test",
ID = 2,
UseAs = CustomClassUseAs.All,
Members = [
new ClassProperty
{
Name = "Yep",
PropertyType = "TestClass",
Properties = []
}
]
}
];
using var reader = TestData.GetXmlReaderFor(testDataFile); using var reader = TestData.GetXmlReaderFor(testDataFile);
static Template ResolveTemplate(string source) Template ResolveTemplate(string source)
{ {
using var xmlTemplateReader = TestData.GetXmlReaderFor($"Serialization.TestData.Template.{source}"); using var xmlTemplateReader = TestData.GetXmlReaderFor($"Serialization.TestData.Template.{source}");
using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate); using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate, customTypeDefinitions);
return templateReader.ReadTemplate(); return templateReader.ReadTemplate();
} }
static Tileset ResolveTileset(string source) Tileset ResolveTileset(string source)
{ {
using var xmlTilesetReader = TestData.GetXmlReaderFor($"Serialization.TestData.Tileset.{source}"); using var xmlTilesetReader = TestData.GetXmlReaderFor($"Serialization.TestData.Tileset.{source}");
using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate); using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTemplate, customTypeDefinitions);
return tilesetReader.ReadTileset(); return tilesetReader.ReadTileset();
} }
using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate); using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate, customTypeDefinitions);
// Act // Act
var map = mapReader.ReadMap(); var map = mapReader.ReadMap();

View file

@ -8,7 +8,11 @@ namespace DotTiled;
internal partial class Tmx internal partial class Tmx
{ {
internal static Map ReadMap(XmlReader reader, Func<string, Tileset> externalTilesetResolver, Func<string, Template> externalTemplateResolver) internal static Map ReadMap(
XmlReader reader,
Func<string, Tileset> externalTilesetResolver,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var version = reader.GetRequiredAttribute("version"); var version = reader.GetRequiredAttribute("version");
@ -64,12 +68,12 @@ internal partial class Tmx
reader.ProcessChildren("map", (r, elementName) => elementName switch reader.ProcessChildren("map", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
"tileset" => () => tilesets.Add(ReadTileset(r, externalTilesetResolver, externalTemplateResolver)), "tileset" => () => tilesets.Add(ReadTileset(r, externalTilesetResolver, externalTemplateResolver, customTypeDefinitions)),
"layer" => () => layers.Add(ReadTileLayer(r, dataUsesChunks: infinite)), "layer" => () => layers.Add(ReadTileLayer(r, infinite, customTypeDefinitions)),
"objectgroup" => () => layers.Add(ReadObjectLayer(r, externalTemplateResolver)), "objectgroup" => () => layers.Add(ReadObjectLayer(r, externalTemplateResolver, customTypeDefinitions)),
"imagelayer" => () => layers.Add(ReadImageLayer(r)), "imagelayer" => () => layers.Add(ReadImageLayer(r, customTypeDefinitions)),
"group" => () => layers.Add(ReadGroup(r, externalTemplateResolver)), "group" => () => layers.Add(ReadGroup(r, externalTemplateResolver, customTypeDefinitions)),
_ => r.Skip _ => r.Skip
}); });

View file

@ -9,7 +9,10 @@ namespace DotTiled;
internal partial class Tmx internal partial class Tmx
{ {
internal static ObjectLayer ReadObjectLayer(XmlReader reader, Func<string, Template> externalTemplateResolver) internal static ObjectLayer ReadObjectLayer(
XmlReader reader,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var id = reader.GetRequiredAttributeParseable<uint>("id"); var id = reader.GetRequiredAttributeParseable<uint>("id");
@ -40,8 +43,8 @@ internal partial class Tmx
reader.ProcessChildren("objectgroup", (r, elementName) => elementName switch reader.ProcessChildren("objectgroup", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
"object" => () => objects.Add(ReadObject(r, externalTemplateResolver)), "object" => () => objects.Add(ReadObject(r, externalTemplateResolver, customTypeDefinitions)),
_ => r.Skip _ => r.Skip
}); });
@ -68,7 +71,10 @@ internal partial class Tmx
}; };
} }
internal static Object ReadObject(XmlReader reader, Func<string, Template> externalTemplateResolver) internal static Object ReadObject(
XmlReader reader,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var template = reader.GetOptionalAttribute("template"); var template = reader.GetOptionalAttribute("template");
@ -122,7 +128,7 @@ internal partial class Tmx
reader.ProcessChildren("object", (r, elementName) => elementName switch reader.ProcessChildren("object", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, MergeProperties(properties, ReadProperties(r)), "Properties", ref propertiesCounter), "properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, MergeProperties(properties, ReadProperties(r, customTypeDefinitions)), "Properties", ref propertiesCounter),
"ellipse" => () => Helpers.SetAtMostOnce(ref obj, ReadEllipseObject(r), "Object marker"), "ellipse" => () => Helpers.SetAtMostOnce(ref obj, ReadEllipseObject(r), "Object marker"),
"point" => () => Helpers.SetAtMostOnce(ref obj, ReadPointObject(r), "Object marker"), "point" => () => Helpers.SetAtMostOnce(ref obj, ReadPointObject(r), "Object marker"),
"polygon" => () => Helpers.SetAtMostOnce(ref obj, ReadPolygonObject(r), "Object marker"), "polygon" => () => Helpers.SetAtMostOnce(ref obj, ReadPolygonObject(r), "Object marker"),
@ -280,7 +286,11 @@ internal partial class Tmx
}; };
} }
internal static Template ReadTemplate(XmlReader reader, Func<string, Tileset> externalTilesetResolver, Func<string, Template> externalTemplateResolver) internal static Template ReadTemplate(
XmlReader reader,
Func<string, Tileset> externalTilesetResolver,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// No attributes // No attributes
@ -292,8 +302,8 @@ internal partial class Tmx
reader.ProcessChildren("template", (r, elementName) => elementName switch reader.ProcessChildren("template", (r, elementName) => elementName switch
{ {
"tileset" => () => Helpers.SetAtMostOnce(ref tileset, ReadTileset(r, externalTilesetResolver, externalTemplateResolver), "Tileset"), "tileset" => () => Helpers.SetAtMostOnce(ref tileset, ReadTileset(r, externalTilesetResolver, externalTemplateResolver, customTypeDefinitions), "Tileset"),
"object" => () => Helpers.SetAtMostOnce(ref obj, ReadObject(r, externalTemplateResolver), "Object"), "object" => () => Helpers.SetAtMostOnce(ref obj, ReadObject(r, externalTemplateResolver, customTypeDefinitions), "Object"),
_ => r.Skip _ => r.Skip
}); });

View file

@ -6,7 +6,9 @@ namespace DotTiled;
internal partial class Tmx internal partial class Tmx
{ {
internal static Dictionary<string, IProperty> ReadProperties(XmlReader reader) internal static Dictionary<string, IProperty> ReadProperties(
XmlReader reader,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
return reader.ReadList("properties", "property", (r) => return reader.ReadList("properties", "property", (r) =>
{ {
@ -33,22 +35,38 @@ internal partial class Tmx
PropertyType.Color => new ColorProperty { Name = name, Value = r.GetRequiredAttributeParseable<Color>("value") }, PropertyType.Color => new ColorProperty { Name = name, Value = r.GetRequiredAttributeParseable<Color>("value") },
PropertyType.File => new FileProperty { Name = name, Value = r.GetRequiredAttribute("value") }, PropertyType.File => new FileProperty { Name = name, Value = r.GetRequiredAttribute("value") },
PropertyType.Object => new ObjectProperty { Name = name, Value = r.GetRequiredAttributeParseable<uint>("value") }, PropertyType.Object => new ObjectProperty { Name = name, Value = r.GetRequiredAttributeParseable<uint>("value") },
PropertyType.Class => ReadClassProperty(r), PropertyType.Class => ReadClassProperty(r, customTypeDefinitions),
_ => throw new XmlException("Invalid property type") _ => throw new XmlException("Invalid property type")
}; };
return (name, property); return (name, property);
}).ToDictionary(x => x.name, x => x.property); }).ToDictionary(x => x.name, x => x.property);
} }
internal static ClassProperty ReadClassProperty(XmlReader reader) internal static ClassProperty ReadClassProperty(
XmlReader reader,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
var name = reader.GetRequiredAttribute("name"); var name = reader.GetRequiredAttribute("name");
var propertyType = reader.GetRequiredAttribute("propertytype"); var propertyType = reader.GetRequiredAttribute("propertytype");
var customTypeDef = customTypeDefinitions.FirstOrDefault(ctd => ctd.Name == propertyType);
if (customTypeDef is CustomClassDefinition ccd)
{
reader.ReadStartElement("property"); reader.ReadStartElement("property");
var properties = ReadProperties(reader); var propsInType = CreateInstanceOfCustomClass(ccd);
reader.ReadEndElement(); var props = ReadProperties(reader, customTypeDefinitions);
return new ClassProperty { Name = name, PropertyType = propertyType, Properties = properties }; var mergedProps = MergeProperties(propsInType, props);
reader.ReadEndElement();
return new ClassProperty { Name = name, PropertyType = propertyType, Properties = mergedProps };
}
throw new XmlException($"Unkonwn custom class definition: {propertyType}");
}
internal static Dictionary<string, IProperty> CreateInstanceOfCustomClass(CustomClassDefinition customClassDefinition)
{
return customClassDefinition.Members.ToDictionary(m => m.Name, m => m.Clone());
} }
} }

View file

@ -7,7 +7,10 @@ namespace DotTiled;
internal partial class Tmx internal partial class Tmx
{ {
internal static TileLayer ReadTileLayer(XmlReader reader, bool dataUsesChunks) internal static TileLayer ReadTileLayer(
XmlReader reader,
bool dataUsesChunks,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
var id = reader.GetRequiredAttributeParseable<uint>("id"); var id = reader.GetRequiredAttributeParseable<uint>("id");
var name = reader.GetOptionalAttribute("name") ?? ""; var name = reader.GetOptionalAttribute("name") ?? "";
@ -30,7 +33,7 @@ internal partial class Tmx
reader.ProcessChildren("layer", (r, elementName) => elementName switch reader.ProcessChildren("layer", (r, elementName) => elementName switch
{ {
"data" => () => Helpers.SetAtMostOnce(ref data, ReadData(r, dataUsesChunks), "Data"), "data" => () => Helpers.SetAtMostOnce(ref data, ReadData(r, dataUsesChunks), "Data"),
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
_ => r.Skip _ => r.Skip
}); });
@ -55,7 +58,9 @@ internal partial class Tmx
}; };
} }
internal static ImageLayer ReadImageLayer(XmlReader reader) internal static ImageLayer ReadImageLayer(
XmlReader reader,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
var id = reader.GetRequiredAttributeParseable<uint>("id"); var id = reader.GetRequiredAttributeParseable<uint>("id");
var name = reader.GetOptionalAttribute("name") ?? ""; var name = reader.GetOptionalAttribute("name") ?? "";
@ -78,7 +83,7 @@ internal partial class Tmx
reader.ProcessChildren("imagelayer", (r, elementName) => elementName switch reader.ProcessChildren("imagelayer", (r, elementName) => elementName switch
{ {
"image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"), "image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"),
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
_ => r.Skip _ => r.Skip
}); });
@ -103,7 +108,10 @@ internal partial class Tmx
}; };
} }
internal static Group ReadGroup(XmlReader reader, Func<string, Template> externalTemplateResolver) internal static Group ReadGroup(
XmlReader reader,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
var id = reader.GetRequiredAttributeParseable<uint>("id"); var id = reader.GetRequiredAttributeParseable<uint>("id");
var name = reader.GetOptionalAttribute("name") ?? ""; var name = reader.GetOptionalAttribute("name") ?? "";
@ -121,11 +129,11 @@ internal partial class Tmx
reader.ProcessChildren("group", (r, elementName) => elementName switch reader.ProcessChildren("group", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
"layer" => () => layers.Add(ReadTileLayer(r, dataUsesChunks: false)), "layer" => () => layers.Add(ReadTileLayer(r, false, customTypeDefinitions)),
"objectgroup" => () => layers.Add(ReadObjectLayer(r, externalTemplateResolver)), "objectgroup" => () => layers.Add(ReadObjectLayer(r, externalTemplateResolver, customTypeDefinitions)),
"imagelayer" => () => layers.Add(ReadImageLayer(r)), "imagelayer" => () => layers.Add(ReadImageLayer(r, customTypeDefinitions)),
"group" => () => layers.Add(ReadGroup(r, externalTemplateResolver)), "group" => () => layers.Add(ReadGroup(r, externalTemplateResolver, customTypeDefinitions)),
_ => r.Skip _ => r.Skip
}); });

View file

@ -8,7 +8,11 @@ namespace DotTiled;
internal partial class Tmx internal partial class Tmx
{ {
internal static Tileset ReadTileset(XmlReader reader, Func<string, Tileset>? externalTilesetResolver, Func<string, Template> externalTemplateResolver) internal static Tileset ReadTileset(
XmlReader reader,
Func<string, Tileset>? externalTilesetResolver,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var version = reader.GetOptionalAttribute("version"); var version = reader.GetOptionalAttribute("version");
@ -64,10 +68,10 @@ internal partial class Tmx
"image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"), "image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"),
"tileoffset" => () => Helpers.SetAtMostOnce(ref tileOffset, ReadTileOffset(r), "TileOffset"), "tileoffset" => () => Helpers.SetAtMostOnce(ref tileOffset, ReadTileOffset(r), "TileOffset"),
"grid" => () => Helpers.SetAtMostOnce(ref grid, ReadGrid(r), "Grid"), "grid" => () => Helpers.SetAtMostOnce(ref grid, ReadGrid(r), "Grid"),
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
"wangsets" => () => Helpers.SetAtMostOnce(ref wangsets, ReadWangsets(r), "Wangsets"), "wangsets" => () => Helpers.SetAtMostOnce(ref wangsets, ReadWangsets(r, customTypeDefinitions), "Wangsets"),
"transformations" => () => Helpers.SetAtMostOnce(ref transformations, ReadTransformations(r), "Transformations"), "transformations" => () => Helpers.SetAtMostOnce(ref transformations, ReadTransformations(r), "Transformations"),
"tile" => () => tiles.Add(ReadTile(r, externalTemplateResolver)), "tile" => () => tiles.Add(ReadTile(r, externalTemplateResolver, customTypeDefinitions)),
_ => r.Skip _ => r.Skip
}); });
@ -198,7 +202,10 @@ internal partial class Tmx
return new Transformations { HFlip = hFlip, VFlip = vFlip, Rotate = rotate, PreferUntransformed = preferUntransformed }; return new Transformations { HFlip = hFlip, VFlip = vFlip, Rotate = rotate, PreferUntransformed = preferUntransformed };
} }
internal static Tile ReadTile(XmlReader reader, Func<string, Template> externalTemplateResolver) internal static Tile ReadTile(
XmlReader reader,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var id = reader.GetRequiredAttributeParseable<uint>("id"); var id = reader.GetRequiredAttributeParseable<uint>("id");
@ -217,9 +224,9 @@ internal partial class Tmx
reader.ProcessChildren("tile", (r, elementName) => elementName switch reader.ProcessChildren("tile", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
"image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"), "image" => () => Helpers.SetAtMostOnce(ref image, ReadImage(r), "Image"),
"objectgroup" => () => Helpers.SetAtMostOnce(ref objectLayer, ReadObjectLayer(r, externalTemplateResolver), "ObjectLayer"), "objectgroup" => () => Helpers.SetAtMostOnce(ref objectLayer, ReadObjectLayer(r, externalTemplateResolver, customTypeDefinitions), "ObjectLayer"),
"animation" => () => Helpers.SetAtMostOnce(ref animation, r.ReadList<Frame>("animation", "frame", (ar) => "animation" => () => Helpers.SetAtMostOnce(ref animation, r.ReadList<Frame>("animation", "frame", (ar) =>
{ {
var tileID = ar.GetRequiredAttributeParseable<uint>("tileid"); var tileID = ar.GetRequiredAttributeParseable<uint>("tileid");
@ -245,12 +252,16 @@ internal partial class Tmx
}; };
} }
internal static List<Wangset> ReadWangsets(XmlReader reader) internal static List<Wangset> ReadWangsets(
XmlReader reader,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
return reader.ReadList<Wangset>("wangsets", "wangset", ReadWangset); return reader.ReadList<Wangset>("wangsets", "wangset", r => ReadWangset(r, customTypeDefinitions));
} }
internal static Wangset ReadWangset(XmlReader reader) internal static Wangset ReadWangset(
XmlReader reader,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var name = reader.GetRequiredAttribute("name"); var name = reader.GetRequiredAttribute("name");
@ -264,8 +275,8 @@ internal partial class Tmx
reader.ProcessChildren("wangset", (r, elementName) => elementName switch reader.ProcessChildren("wangset", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
"wangcolor" => () => wangColors.Add(ReadWangColor(r)), "wangcolor" => () => wangColors.Add(ReadWangColor(r, customTypeDefinitions)),
"wangtile" => () => wangTiles.Add(ReadWangTile(r)), "wangtile" => () => wangTiles.Add(ReadWangTile(r)),
_ => r.Skip _ => r.Skip
}); });
@ -284,7 +295,9 @@ internal partial class Tmx
}; };
} }
internal static WangColor ReadWangColor(XmlReader reader) internal static WangColor ReadWangColor(
XmlReader reader,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
// Attributes // Attributes
var name = reader.GetRequiredAttribute("name"); var name = reader.GetRequiredAttribute("name");
@ -298,7 +311,7 @@ internal partial class Tmx
reader.ProcessChildren("wangcolor", (r, elementName) => elementName switch reader.ProcessChildren("wangcolor", (r, elementName) => elementName switch
{ {
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r), "Properties"), "properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
_ => r.Skip _ => r.Skip
}); });

View file

@ -13,11 +13,18 @@ public class TmxMapReader : IMapReader
private readonly XmlReader _reader; private readonly XmlReader _reader;
private bool disposedValue; private bool disposedValue;
public TmxMapReader(XmlReader reader, Func<string, Tileset> externalTilesetResolver, Func<string, Template> externalTemplateResolver) private readonly IReadOnlyCollection<CustomTypeDefinition> _customTypeDefinitions;
public TmxMapReader(
XmlReader reader,
Func<string, Tileset> externalTilesetResolver,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
_reader = reader ?? throw new ArgumentNullException(nameof(reader)); _reader = reader ?? throw new ArgumentNullException(nameof(reader));
_externalTilesetResolver = externalTilesetResolver ?? throw new ArgumentNullException(nameof(externalTilesetResolver)); _externalTilesetResolver = externalTilesetResolver ?? throw new ArgumentNullException(nameof(externalTilesetResolver));
_externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver)); _externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver));
_customTypeDefinitions = customTypeDefinitions ?? throw new ArgumentNullException(nameof(customTypeDefinitions));
// Prepare reader // Prepare reader
_reader.MoveToContent(); _reader.MoveToContent();
@ -25,7 +32,7 @@ public class TmxMapReader : IMapReader
public Map ReadMap() public Map ReadMap()
{ {
return Tmx.ReadMap(_reader, _externalTilesetResolver, _externalTemplateResolver); return Tmx.ReadMap(_reader, _externalTilesetResolver, _externalTemplateResolver, _customTypeDefinitions);
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Xml; using System.Xml;
namespace DotTiled; namespace DotTiled;
@ -11,13 +12,22 @@ public class TsxTilesetReader : ITilesetReader
private readonly XmlReader _reader; private readonly XmlReader _reader;
private bool disposedValue; private bool disposedValue;
public TsxTilesetReader(XmlReader reader, Func<string, Template> externalTemplateResolver) private readonly IReadOnlyCollection<CustomTypeDefinition> _customTypeDefinitions;
public TsxTilesetReader(
XmlReader reader,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
_reader = reader ?? throw new ArgumentNullException(nameof(reader)); _reader = reader ?? throw new ArgumentNullException(nameof(reader));
_externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver)); _externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver));
_customTypeDefinitions = customTypeDefinitions ?? throw new ArgumentNullException(nameof(customTypeDefinitions));
// Prepare reader
_reader.MoveToContent();
} }
public Tileset ReadTileset() => Tmx.ReadTileset(_reader, null, _externalTemplateResolver); public Tileset ReadTileset() => Tmx.ReadTileset(_reader, null, _externalTemplateResolver, _customTypeDefinitions);
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Xml; using System.Xml;
namespace DotTiled; namespace DotTiled;
@ -12,17 +13,24 @@ public class TxTemplateReader : ITemplateReader
private readonly XmlReader _reader; private readonly XmlReader _reader;
private bool disposedValue; private bool disposedValue;
public TxTemplateReader(XmlReader reader, Func<string, Tileset> externalTilesetResolver, Func<string, Template> externalTemplateResolver) private readonly IReadOnlyCollection<CustomTypeDefinition> _customTypeDefinitions;
public TxTemplateReader(
XmlReader reader,
Func<string, Tileset> externalTilesetResolver,
Func<string, Template> externalTemplateResolver,
IReadOnlyCollection<CustomTypeDefinition> customTypeDefinitions)
{ {
_reader = reader ?? throw new ArgumentNullException(nameof(reader)); _reader = reader ?? throw new ArgumentNullException(nameof(reader));
_externalTilesetResolver = externalTilesetResolver ?? throw new ArgumentNullException(nameof(externalTilesetResolver)); _externalTilesetResolver = externalTilesetResolver ?? throw new ArgumentNullException(nameof(externalTilesetResolver));
_externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver)); _externalTemplateResolver = externalTemplateResolver ?? throw new ArgumentNullException(nameof(externalTemplateResolver));
_customTypeDefinitions = customTypeDefinitions ?? throw new ArgumentNullException(nameof(customTypeDefinitions));
// Prepare reader // Prepare reader
_reader.MoveToContent(); _reader.MoveToContent();
} }
public Template ReadTemplate() => Tmx.ReadTemplate(_reader, _externalTilesetResolver, _externalTemplateResolver); public Template ReadTemplate() => Tmx.ReadTemplate(_reader, _externalTilesetResolver, _externalTemplateResolver, _customTypeDefinitions);
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {