More tests

This commit is contained in:
Daniel Cronqvist 2024-08-14 20:29:55 +02:00
parent 653e5b5326
commit aecd97bd7d
8 changed files with 159 additions and 88 deletions

View file

@ -17,6 +17,8 @@ public static partial class DotTiledAssert
AssertEqual(expected.Template, actual.Template, nameof(Object.Template));
AssertProperties(expected.Properties, actual.Properties);
Assert.True(expected.GetType() == actual.GetType(), $"Expected object type {expected.GetType()} but got {actual.GetType()}");
AssertObject((dynamic)expected, (dynamic)actual);
}

View file

@ -92,7 +92,12 @@ public partial class TestData
new Vector2(0, 0),
new Vector2(104,20),
new Vector2(35.6667f, 32.3333f)
]
],
Template = fileExt == "tmx" ? "poly.tx" : "poly.tj",
Properties = new Dictionary<string, IProperty>
{
["templateprop"] = new StringProperty { Name = "templateprop", Value = "helo there" }
}
},
new TileObject
{

View file

@ -11,15 +11,15 @@
"name":"Objects",
"objects":[
{
"height":31.3333333333333,
"height":31.3333,
"id":1,
"name":"Object 1",
"rotation":0,
"type":"",
"visible":true,
"width":31.3333333333333,
"x":25.6666666666667,
"y":28.6666666666667
"width":31.3333,
"x":25.6667,
"y":28.6667
},
{
"height":0,
@ -30,44 +30,26 @@
"type":"",
"visible":true,
"width":0,
"x":117.666666666667,
"y":48.6666666666667
"x":117.667,
"y":48.6667
},
{
"ellipse":true,
"height":34.6666666666667,
"height":34.6667,
"id":4,
"name":"Circle1",
"rotation":0,
"type":"",
"visible":true,
"width":34.6666666666667,
"width":34.6667,
"x":77,
"y":72.3333333333333
"y":72.3333
},
{
"height":0,
"id":5,
"name":"Poly",
"polygon":[
{
"x":0,
"y":0
},
{
"x":104,
"y":20
},
{
"x":35.6666666666667,
"y":32.3333333333333
}],
"rotation":0,
"type":"",
"visible":true,
"width":0,
"x":20.6666666666667,
"y":114.666666666667
"template":"poly.tj",
"x":20.6667,
"y":114.667
},
{
"gid":7,
@ -79,7 +61,7 @@
"visible":true,
"width":64,
"x":-35,
"y":110.333333333333
"y":110.333
}],
"opacity":1,
"type":"objectgroup",

View file

@ -10,9 +10,7 @@
<object id="4" name="Circle1" x="77" y="72.3333" width="34.6667" height="34.6667">
<ellipse/>
</object>
<object id="5" name="Poly" x="20.6667" y="114.667">
<polygon points="0,0 104,20 35.6667,32.3333"/>
</object>
<object id="5" template="poly.tx" x="20.6667" y="114.667"/>
<object id="6" name="TileObj" gid="7" x="-35" y="110.333" width="64" height="146"/>
</objectgroup>
<group id="5" name="Sub">

View file

@ -0,0 +1,31 @@
{ "object":
{
"height":0,
"id":5,
"name":"Poly",
"polygon":[
{
"x":0,
"y":0
},
{
"x":104,
"y":20
},
{
"x":35.6667,
"y":32.3333
}],
"properties":[
{
"name":"templateprop",
"type":"string",
"value":"helo there"
}],
"rotation":0,
"type":"",
"visible":true,
"width":0
},
"type":"template"
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<object name="Poly">
<properties>
<property name="templateprop" value="helo there"/>
</properties>
<polygon points="0,0 104,20 35.6667,32.3333"/>
</object>
</template>

View file

@ -72,7 +72,7 @@ internal static partial class Helpers
};
}
internal static Dictionary<string, IProperty> MergeProperties(Dictionary<string, IProperty>? baseProperties, Dictionary<string, IProperty> overrideProperties)
internal static Dictionary<string, IProperty> MergeProperties(Dictionary<string, IProperty>? baseProperties, Dictionary<string, IProperty>? overrideProperties)
{
if (baseProperties is null)
return overrideProperties ?? new Dictionary<string, IProperty>();

View file

@ -78,36 +78,21 @@ internal partial class Tmx
{
// Attributes
var template = reader.GetOptionalAttribute("template");
uint? idDefault = null;
string nameDefault = "";
string typeDefault = "";
float xDefault = 0f;
float yDefault = 0f;
float widthDefault = 0f;
float heightDefault = 0f;
float rotationDefault = 0f;
uint? gidDefault = null;
bool visibleDefault = true;
Dictionary<string, IProperty>? propertiesDefault = null;
// Perform template copy first
Object? obj = null;
if (template is not null)
{
var resolvedTemplate = externalTemplateResolver(template);
var templObj = resolvedTemplate.Object;
obj = externalTemplateResolver(template).Object;
idDefault = templObj.ID;
nameDefault = templObj.Name;
typeDefault = templObj.Type;
xDefault = templObj.X;
yDefault = templObj.Y;
widthDefault = templObj.Width;
heightDefault = templObj.Height;
rotationDefault = templObj.Rotation;
visibleDefault = templObj.Visible;
propertiesDefault = templObj.Properties;
}
uint? idDefault = obj?.ID ?? null;
string nameDefault = obj?.Name ?? "";
string typeDefault = obj?.Type ?? "";
float xDefault = obj?.X ?? 0f;
float yDefault = obj?.Y ?? 0f;
float widthDefault = obj?.Width ?? 0f;
float heightDefault = obj?.Height ?? 0f;
float rotationDefault = obj?.Rotation ?? 0f;
uint? gidDefault = obj is TileObject tileObj ? tileObj.GID : null;
bool visibleDefault = obj?.Visible ?? true;
Dictionary<string, IProperty>? propertiesDefault = obj?.Properties ?? null;
var id = reader.GetOptionalAttributeParseable<uint>("id") ?? idDefault;
var name = reader.GetOptionalAttribute("name") ?? nameDefault;
@ -121,46 +106,66 @@ internal partial class Tmx
var visible = reader.GetOptionalAttributeParseable<bool>("visible") ?? visibleDefault;
// Elements
Object? obj = null;
Object? foundObject = null;
int propertiesCounter = 0;
Dictionary<string, IProperty>? properties = propertiesDefault;
reader.ProcessChildren("object", (r, elementName) => elementName switch
{
"properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, Helpers.MergeProperties(properties, ReadProperties(r, customTypeDefinitions)), "Properties", ref propertiesCounter),
"ellipse" => () => Helpers.SetAtMostOnce(ref obj, ReadEllipseObject(r), "Object marker"),
"point" => () => Helpers.SetAtMostOnce(ref obj, ReadPointObject(r), "Object marker"),
"polygon" => () => Helpers.SetAtMostOnce(ref obj, ReadPolygonObject(r), "Object marker"),
"polyline" => () => Helpers.SetAtMostOnce(ref obj, ReadPolylineObject(r), "Object marker"),
"text" => () => Helpers.SetAtMostOnce(ref obj, ReadTextObject(r), "Object marker"),
"ellipse" => () => Helpers.SetAtMostOnce(ref foundObject, ReadEllipseObject(r), "Object marker"),
"point" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPointObject(r), "Object marker"),
"polygon" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPolygonObject(r), "Object marker"),
"polyline" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPolylineObject(r), "Object marker"),
"text" => () => Helpers.SetAtMostOnce(ref foundObject, ReadTextObject(r), "Object marker"),
_ => throw new Exception($"Unknown object marker '{elementName}'")
});
if (foundObject is null)
{
if (gid is not null)
{
obj = new TileObject { ID = id, GID = gid.Value };
reader.Skip();
foundObject = new TileObject { ID = id, GID = gid.Value };
else
foundObject = new RectangleObject { ID = id };
}
foundObject.ID = id;
foundObject.Name = name;
foundObject.Type = type;
foundObject.X = x;
foundObject.Y = y;
foundObject.Width = width;
foundObject.Height = height;
foundObject.Rotation = rotation;
foundObject.Visible = visible;
foundObject.Properties = properties;
foundObject.Template = template;
return OverrideObject(obj, foundObject);
}
internal static Object OverrideObject(Object? obj, Object foundObject)
{
if (obj is null)
return foundObject;
if (obj.GetType() != foundObject.GetType())
{
obj = new RectangleObject { ID = id };
reader.Skip();
obj.ID = foundObject.ID;
obj.Name = foundObject.Name;
obj.Type = foundObject.Type;
obj.X = foundObject.X;
obj.Y = foundObject.Y;
obj.Width = foundObject.Width;
obj.Height = foundObject.Height;
obj.Rotation = foundObject.Rotation;
obj.Visible = foundObject.Visible;
obj.Properties = Helpers.MergeProperties(obj.Properties, foundObject.Properties);
obj.Template = foundObject.Template;
return obj;
}
obj.ID = id;
obj.Name = name;
obj.Type = type;
obj.X = x;
obj.Y = y;
obj.Width = width;
obj.Height = height;
obj.Rotation = rotation;
obj.Visible = visible;
obj.Template = template;
obj.Properties = properties;
return obj;
return OverrideObject((dynamic)obj, (dynamic)foundObject);
}
internal static EllipseObject ReadEllipseObject(XmlReader reader)
@ -169,12 +174,16 @@ internal partial class Tmx
return new EllipseObject { };
}
internal static EllipseObject OverrideObject(EllipseObject obj, EllipseObject foundObject) => obj;
internal static PointObject ReadPointObject(XmlReader reader)
{
reader.Skip();
return new PointObject { };
}
internal static PointObject OverrideObject(PointObject obj, PointObject foundObject) => obj;
internal static PolygonObject ReadPolygonObject(XmlReader reader)
{
// Attributes
@ -193,6 +202,12 @@ internal partial class Tmx
return new PolygonObject { Points = points };
}
internal static PolygonObject OverrideObject(PolygonObject obj, PolygonObject foundObject)
{
obj.Points = foundObject.Points;
return obj;
}
internal static PolylineObject ReadPolylineObject(XmlReader reader)
{
// Attributes
@ -211,6 +226,12 @@ internal partial class Tmx
return new PolylineObject { Points = points };
}
internal static PolylineObject OverrideObject(PolylineObject obj, PolylineObject foundObject)
{
obj.Points = foundObject.Points;
return obj;
}
internal static TextObject ReadTextObject(XmlReader reader)
{
// Attributes
@ -259,6 +280,29 @@ internal partial class Tmx
};
}
internal static TextObject OverrideObject(TextObject obj, TextObject foundObject)
{
obj.FontFamily = foundObject.FontFamily;
obj.PixelSize = foundObject.PixelSize;
obj.Wrap = foundObject.Wrap;
obj.Color = foundObject.Color;
obj.Bold = foundObject.Bold;
obj.Italic = foundObject.Italic;
obj.Underline = foundObject.Underline;
obj.Strikeout = foundObject.Strikeout;
obj.Kerning = foundObject.Kerning;
obj.HorizontalAlignment = foundObject.HorizontalAlignment;
obj.VerticalAlignment = foundObject.VerticalAlignment;
obj.Text = foundObject.Text;
return obj;
}
internal static TileObject OverrideObject(TileObject obj, TileObject foundObject)
{
obj.GID = foundObject.GID;
return obj;
}
internal static Template ReadTemplate(
XmlReader reader,
Func<string, Tileset> externalTilesetResolver,