mirror of
https://github.com/dcronqvist/DotTiled.git
synced 2025-02-05 17:02:49 +02:00
More tests
This commit is contained in:
parent
653e5b5326
commit
aecd97bd7d
8 changed files with 159 additions and 88 deletions
|
@ -17,6 +17,8 @@ public static partial class DotTiledAssert
|
||||||
AssertEqual(expected.Template, actual.Template, nameof(Object.Template));
|
AssertEqual(expected.Template, actual.Template, nameof(Object.Template));
|
||||||
|
|
||||||
AssertProperties(expected.Properties, actual.Properties);
|
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);
|
AssertObject((dynamic)expected, (dynamic)actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,12 @@ public partial class TestData
|
||||||
new Vector2(0, 0),
|
new Vector2(0, 0),
|
||||||
new Vector2(104,20),
|
new Vector2(104,20),
|
||||||
new Vector2(35.6667f, 32.3333f)
|
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
|
new TileObject
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,15 +11,15 @@
|
||||||
"name":"Objects",
|
"name":"Objects",
|
||||||
"objects":[
|
"objects":[
|
||||||
{
|
{
|
||||||
"height":31.3333333333333,
|
"height":31.3333,
|
||||||
"id":1,
|
"id":1,
|
||||||
"name":"Object 1",
|
"name":"Object 1",
|
||||||
"rotation":0,
|
"rotation":0,
|
||||||
"type":"",
|
"type":"",
|
||||||
"visible":true,
|
"visible":true,
|
||||||
"width":31.3333333333333,
|
"width":31.3333,
|
||||||
"x":25.6666666666667,
|
"x":25.6667,
|
||||||
"y":28.6666666666667
|
"y":28.6667
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"height":0,
|
"height":0,
|
||||||
|
@ -30,44 +30,26 @@
|
||||||
"type":"",
|
"type":"",
|
||||||
"visible":true,
|
"visible":true,
|
||||||
"width":0,
|
"width":0,
|
||||||
"x":117.666666666667,
|
"x":117.667,
|
||||||
"y":48.6666666666667
|
"y":48.6667
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ellipse":true,
|
"ellipse":true,
|
||||||
"height":34.6666666666667,
|
"height":34.6667,
|
||||||
"id":4,
|
"id":4,
|
||||||
"name":"Circle1",
|
"name":"Circle1",
|
||||||
"rotation":0,
|
"rotation":0,
|
||||||
"type":"",
|
"type":"",
|
||||||
"visible":true,
|
"visible":true,
|
||||||
"width":34.6666666666667,
|
"width":34.6667,
|
||||||
"x":77,
|
"x":77,
|
||||||
"y":72.3333333333333
|
"y":72.3333
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"height":0,
|
|
||||||
"id":5,
|
"id":5,
|
||||||
"name":"Poly",
|
"template":"poly.tj",
|
||||||
"polygon":[
|
"x":20.6667,
|
||||||
{
|
"y":114.667
|
||||||
"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
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"gid":7,
|
"gid":7,
|
||||||
|
@ -79,7 +61,7 @@
|
||||||
"visible":true,
|
"visible":true,
|
||||||
"width":64,
|
"width":64,
|
||||||
"x":-35,
|
"x":-35,
|
||||||
"y":110.333333333333
|
"y":110.333
|
||||||
}],
|
}],
|
||||||
"opacity":1,
|
"opacity":1,
|
||||||
"type":"objectgroup",
|
"type":"objectgroup",
|
||||||
|
|
|
@ -10,9 +10,7 @@
|
||||||
<object id="4" name="Circle1" x="77" y="72.3333" width="34.6667" height="34.6667">
|
<object id="4" name="Circle1" x="77" y="72.3333" width="34.6667" height="34.6667">
|
||||||
<ellipse/>
|
<ellipse/>
|
||||||
</object>
|
</object>
|
||||||
<object id="5" name="Poly" x="20.6667" y="114.667">
|
<object id="5" template="poly.tx" x="20.6667" y="114.667"/>
|
||||||
<polygon points="0,0 104,20 35.6667,32.3333"/>
|
|
||||||
</object>
|
|
||||||
<object id="6" name="TileObj" gid="7" x="-35" y="110.333" width="64" height="146"/>
|
<object id="6" name="TileObj" gid="7" x="-35" y="110.333" width="64" height="146"/>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
<group id="5" name="Sub">
|
<group id="5" name="Sub">
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
{ "object":
|
||||||
|
{
|
||||||
|
"height":0,
|
||||||
|
"id":5,
|
||||||
|
"name":"Poly",
|
||||||
|
"polygon":[
|
||||||
|
{
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x":104,
|
||||||
|
"y":20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x":35.6667,
|
||||||
|
"y":32.3333
|
||||||
|
}],
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"templateprop",
|
||||||
|
"type":"string",
|
||||||
|
"value":"helo there"
|
||||||
|
}],
|
||||||
|
"rotation":0,
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":0
|
||||||
|
},
|
||||||
|
"type":"template"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<template>
|
||||||
|
<object name="Poly">
|
||||||
|
<properties>
|
||||||
|
<property name="templateprop" value="helo there"/>
|
||||||
|
</properties>
|
||||||
|
<polygon points="0,0 104,20 35.6667,32.3333"/>
|
||||||
|
</object>
|
||||||
|
</template>
|
|
@ -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)
|
if (baseProperties is null)
|
||||||
return overrideProperties ?? new Dictionary<string, IProperty>();
|
return overrideProperties ?? new Dictionary<string, IProperty>();
|
||||||
|
|
|
@ -78,36 +78,21 @@ internal partial class Tmx
|
||||||
{
|
{
|
||||||
// Attributes
|
// Attributes
|
||||||
var template = reader.GetOptionalAttribute("template");
|
var template = reader.GetOptionalAttribute("template");
|
||||||
|
Object? obj = null;
|
||||||
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
|
|
||||||
if (template is not null)
|
if (template is not null)
|
||||||
{
|
obj = externalTemplateResolver(template).Object;
|
||||||
var resolvedTemplate = externalTemplateResolver(template);
|
|
||||||
var templObj = resolvedTemplate.Object;
|
|
||||||
|
|
||||||
idDefault = templObj.ID;
|
uint? idDefault = obj?.ID ?? null;
|
||||||
nameDefault = templObj.Name;
|
string nameDefault = obj?.Name ?? "";
|
||||||
typeDefault = templObj.Type;
|
string typeDefault = obj?.Type ?? "";
|
||||||
xDefault = templObj.X;
|
float xDefault = obj?.X ?? 0f;
|
||||||
yDefault = templObj.Y;
|
float yDefault = obj?.Y ?? 0f;
|
||||||
widthDefault = templObj.Width;
|
float widthDefault = obj?.Width ?? 0f;
|
||||||
heightDefault = templObj.Height;
|
float heightDefault = obj?.Height ?? 0f;
|
||||||
rotationDefault = templObj.Rotation;
|
float rotationDefault = obj?.Rotation ?? 0f;
|
||||||
visibleDefault = templObj.Visible;
|
uint? gidDefault = obj is TileObject tileObj ? tileObj.GID : null;
|
||||||
propertiesDefault = templObj.Properties;
|
bool visibleDefault = obj?.Visible ?? true;
|
||||||
}
|
Dictionary<string, IProperty>? propertiesDefault = obj?.Properties ?? null;
|
||||||
|
|
||||||
var id = reader.GetOptionalAttributeParseable<uint>("id") ?? idDefault;
|
var id = reader.GetOptionalAttributeParseable<uint>("id") ?? idDefault;
|
||||||
var name = reader.GetOptionalAttribute("name") ?? nameDefault;
|
var name = reader.GetOptionalAttribute("name") ?? nameDefault;
|
||||||
|
@ -121,46 +106,66 @@ internal partial class Tmx
|
||||||
var visible = reader.GetOptionalAttributeParseable<bool>("visible") ?? visibleDefault;
|
var visible = reader.GetOptionalAttributeParseable<bool>("visible") ?? visibleDefault;
|
||||||
|
|
||||||
// Elements
|
// Elements
|
||||||
Object? obj = null;
|
Object? foundObject = null;
|
||||||
int propertiesCounter = 0;
|
int propertiesCounter = 0;
|
||||||
Dictionary<string, IProperty>? properties = propertiesDefault;
|
Dictionary<string, IProperty>? properties = propertiesDefault;
|
||||||
|
|
||||||
reader.ProcessChildren("object", (r, elementName) => elementName switch
|
reader.ProcessChildren("object", (r, elementName) => elementName switch
|
||||||
{
|
{
|
||||||
"properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, Helpers.MergeProperties(properties, ReadProperties(r, customTypeDefinitions)), "Properties", ref propertiesCounter),
|
"properties" => () => Helpers.SetAtMostOnceUsingCounter(ref properties, Helpers.MergeProperties(properties, ReadProperties(r, customTypeDefinitions)), "Properties", ref propertiesCounter),
|
||||||
"ellipse" => () => Helpers.SetAtMostOnce(ref obj, ReadEllipseObject(r), "Object marker"),
|
"ellipse" => () => Helpers.SetAtMostOnce(ref foundObject, ReadEllipseObject(r), "Object marker"),
|
||||||
"point" => () => Helpers.SetAtMostOnce(ref obj, ReadPointObject(r), "Object marker"),
|
"point" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPointObject(r), "Object marker"),
|
||||||
"polygon" => () => Helpers.SetAtMostOnce(ref obj, ReadPolygonObject(r), "Object marker"),
|
"polygon" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPolygonObject(r), "Object marker"),
|
||||||
"polyline" => () => Helpers.SetAtMostOnce(ref obj, ReadPolylineObject(r), "Object marker"),
|
"polyline" => () => Helpers.SetAtMostOnce(ref foundObject, ReadPolylineObject(r), "Object marker"),
|
||||||
"text" => () => Helpers.SetAtMostOnce(ref obj, ReadTextObject(r), "Object marker"),
|
"text" => () => Helpers.SetAtMostOnce(ref foundObject, ReadTextObject(r), "Object marker"),
|
||||||
_ => throw new Exception($"Unknown object marker '{elementName}'")
|
_ => throw new Exception($"Unknown object marker '{elementName}'")
|
||||||
});
|
});
|
||||||
|
|
||||||
if (gid is not null)
|
if (foundObject is null)
|
||||||
{
|
{
|
||||||
obj = new TileObject { ID = id, GID = gid.Value };
|
if (gid is not null)
|
||||||
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)
|
if (obj is null)
|
||||||
|
return foundObject;
|
||||||
|
|
||||||
|
if (obj.GetType() != foundObject.GetType())
|
||||||
{
|
{
|
||||||
obj = new RectangleObject { ID = id };
|
obj.ID = foundObject.ID;
|
||||||
reader.Skip();
|
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;
|
return OverrideObject((dynamic)obj, (dynamic)foundObject);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static EllipseObject ReadEllipseObject(XmlReader reader)
|
internal static EllipseObject ReadEllipseObject(XmlReader reader)
|
||||||
|
@ -169,12 +174,16 @@ internal partial class Tmx
|
||||||
return new EllipseObject { };
|
return new EllipseObject { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static EllipseObject OverrideObject(EllipseObject obj, EllipseObject foundObject) => obj;
|
||||||
|
|
||||||
internal static PointObject ReadPointObject(XmlReader reader)
|
internal static PointObject ReadPointObject(XmlReader reader)
|
||||||
{
|
{
|
||||||
reader.Skip();
|
reader.Skip();
|
||||||
return new PointObject { };
|
return new PointObject { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static PointObject OverrideObject(PointObject obj, PointObject foundObject) => obj;
|
||||||
|
|
||||||
internal static PolygonObject ReadPolygonObject(XmlReader reader)
|
internal static PolygonObject ReadPolygonObject(XmlReader reader)
|
||||||
{
|
{
|
||||||
// Attributes
|
// Attributes
|
||||||
|
@ -193,6 +202,12 @@ internal partial class Tmx
|
||||||
return new PolygonObject { Points = points };
|
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)
|
internal static PolylineObject ReadPolylineObject(XmlReader reader)
|
||||||
{
|
{
|
||||||
// Attributes
|
// Attributes
|
||||||
|
@ -211,6 +226,12 @@ internal partial class Tmx
|
||||||
return new PolylineObject { Points = points };
|
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)
|
internal static TextObject ReadTextObject(XmlReader reader)
|
||||||
{
|
{
|
||||||
// Attributes
|
// 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(
|
internal static Template ReadTemplate(
|
||||||
XmlReader reader,
|
XmlReader reader,
|
||||||
Func<string, Tileset> externalTilesetResolver,
|
Func<string, Tileset> externalTilesetResolver,
|
||||||
|
|
Loading…
Add table
Reference in a new issue