mirror of
https://github.com/dcronqvist/DotTiled.git
synced 2025-02-05 08:52:50 +02:00
Fix rest of model to use new structure and prepare docs
This commit is contained in:
parent
b46eed774a
commit
4580772ced
25 changed files with 94 additions and 200 deletions
1
docs/docs/accessing-properties.md
Normal file
1
docs/docs/accessing-properties.md
Normal file
|
@ -0,0 +1 @@
|
|||
# Accessing properties
|
|
@ -3,4 +3,5 @@
|
|||
- href: quickstart.md
|
||||
|
||||
- name: Essentials
|
||||
- href: loading-a-map.md
|
||||
- href: loading-a-map.md
|
||||
- href: accessing-properties.md
|
|
@ -91,7 +91,7 @@ public static partial class DotTiledAssert
|
|||
AssertEqual(expected.NextObjectID, actual.NextObjectID, nameof(Map.NextObjectID));
|
||||
AssertEqual(expected.Infinite, actual.Infinite, nameof(Map.Infinite));
|
||||
|
||||
AssertPropertiesList(actual.Properties, expected.Properties);
|
||||
AssertProperties(actual.Properties, expected.Properties);
|
||||
|
||||
Assert.NotNull(actual.Tilesets);
|
||||
AssertEqual(expected.Tilesets.Count, actual.Tilesets.Count, "Tilesets.Count");
|
||||
|
|
|
@ -4,24 +4,7 @@ namespace DotTiled.Tests;
|
|||
|
||||
public static partial class DotTiledAssert
|
||||
{
|
||||
internal static void AssertProperties(Dictionary<string, IProperty>? expected, Dictionary<string, IProperty>? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
Assert.Null(actual);
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.NotNull(actual);
|
||||
AssertEqual(expected.Count, actual.Count, "Properties.Count");
|
||||
foreach (var kvp in expected)
|
||||
{
|
||||
Assert.Contains(kvp.Key, actual.Keys);
|
||||
AssertProperty((dynamic)kvp.Value, (dynamic)actual[kvp.Key]);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void AssertPropertiesList(IList<IProperty>? expected, IList<IProperty>? actual)
|
||||
internal static void AssertProperties(IList<IProperty>? expected, IList<IProperty>? actual)
|
||||
{
|
||||
if (expected is null)
|
||||
{
|
||||
|
@ -36,17 +19,13 @@ public static partial class DotTiledAssert
|
|||
Assert.Contains(actual, p => p.Name == prop.Name);
|
||||
|
||||
var actualProp = actual.First(p => p.Name == prop.Name);
|
||||
AssertEqual(prop.Type, actualProp.Type, "Property.Type");
|
||||
AssertEqual(prop.Name, actualProp.Name, "Property.Name");
|
||||
|
||||
AssertProperty((dynamic)prop, (dynamic)actualProp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AssertProperty(IProperty expected, IProperty actual)
|
||||
{
|
||||
AssertEqual(expected.Type, actual.Type, "Property.Type");
|
||||
AssertEqual(expected.Name, actual.Name, "Property.Name");
|
||||
AssertProperties((dynamic)actual, (dynamic)expected);
|
||||
}
|
||||
|
||||
private static void AssertProperty(StringProperty expected, StringProperty actual) => AssertEqual(expected.Value, actual.Value, "StringProperty.Value");
|
||||
|
||||
private static void AssertProperty(IntProperty expected, IntProperty actual) => AssertEqual(expected.Value, actual.Value, "IntProperty.Value");
|
||||
|
@ -64,6 +43,6 @@ public static partial class DotTiledAssert
|
|||
private static void AssertProperty(ClassProperty expected, ClassProperty actual)
|
||||
{
|
||||
AssertEqual(expected.PropertyType, actual.PropertyType, "ClassProperty.PropertyType");
|
||||
AssertPropertiesList(expected.Value, actual.Value);
|
||||
AssertProperties(expected.Value, actual.Value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,16 +49,15 @@ public partial class TestData
|
|||
Width = 1,
|
||||
Height = 1
|
||||
},
|
||||
Properties = new Dictionary<string, IProperty>
|
||||
{
|
||||
["tilesetbool"] = new BoolProperty { Name = "tilesetbool", Value = true },
|
||||
["tilesetcolor"] = new ColorProperty { Name = "tilesetcolor", Value = Color.Parse("#ffff0000", CultureInfo.InvariantCulture) },
|
||||
["tilesetfile"] = new FileProperty { Name = "tilesetfile", Value = "" },
|
||||
["tilesetfloat"] = new FloatProperty { Name = "tilesetfloat", Value = 5.2f },
|
||||
["tilesetint"] = new IntProperty { Name = "tilesetint", Value = 9 },
|
||||
["tilesetobject"] = new ObjectProperty { Name = "tilesetobject", Value = 0 },
|
||||
["tilesetstring"] = new StringProperty { Name = "tilesetstring", Value = "hello world!" }
|
||||
},
|
||||
Properties = [
|
||||
new BoolProperty { Name = "tilesetbool", Value = true },
|
||||
new ColorProperty { Name = "tilesetcolor", Value = Color.Parse("#ffff0000", CultureInfo.InvariantCulture) },
|
||||
new FileProperty { Name = "tilesetfile", Value = "" },
|
||||
new FloatProperty { Name = "tilesetfloat", Value = 5.2f },
|
||||
new IntProperty { Name = "tilesetint", Value = 9 },
|
||||
new ObjectProperty { Name = "tilesetobject", Value = 0 },
|
||||
new StringProperty { Name = "tilesetstring", Value = "hello world!" }
|
||||
],
|
||||
Tiles = [
|
||||
new Tile
|
||||
{
|
||||
|
|
|
@ -95,10 +95,9 @@ public partial class TestData
|
|||
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" }
|
||||
}
|
||||
Properties = [
|
||||
new StringProperty { Name = "templateprop", Value = "helo there" }
|
||||
]
|
||||
},
|
||||
new TileObject
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace DotTiled.Model;
|
|||
/// To check the type of a layer, <see href="https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/pattern-matching">use C# pattern matching</see>,
|
||||
/// or some other mechanism to determine the type of the layer at runtime.
|
||||
/// </summary>
|
||||
public abstract class BaseLayer
|
||||
public abstract class BaseLayer : HasPropertiesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID of the layer. Each layer that is added to a map gets a unique ID. Even if a layer is deleted, no layer ever gets the same ID.
|
||||
|
@ -62,5 +62,8 @@ public abstract class BaseLayer
|
|||
/// <summary>
|
||||
/// Layer properties.
|
||||
/// </summary>
|
||||
public Dictionary<string, IProperty>? Properties { get; set; }
|
||||
public List<IProperty> Properties { get; set; } = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IList<IProperty> GetProperties() => Properties;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace DotTiled.Model;
|
|||
/// <summary>
|
||||
/// Base class for objects in object layers.
|
||||
/// </summary>
|
||||
public abstract class Object
|
||||
public abstract class Object : HasPropertiesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID of the objects. Each object that is placed on a map gets a unique ID. Even if an object was deleted, no object gets the same ID.
|
||||
|
@ -60,5 +60,8 @@ public abstract class Object
|
|||
/// <summary>
|
||||
/// Object properties.
|
||||
/// </summary>
|
||||
public Dictionary<string, IProperty>? Properties { get; set; }
|
||||
public List<IProperty> Properties { get; set; } = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IList<IProperty> GetProperties() => Properties;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace DotTiled.Model;
|
|||
/// Represents a single tile in a tileset, when using a collection of images to represent the tileset.
|
||||
/// <see href="https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tile">Tiled documentation for Tileset tiles</see>
|
||||
/// </summary>
|
||||
public class Tile
|
||||
public class Tile : HasPropertiesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The local tile ID within its tileset.
|
||||
|
@ -46,7 +46,10 @@ public class Tile
|
|||
/// <summary>
|
||||
/// Tile properties.
|
||||
/// </summary>
|
||||
public Dictionary<string, IProperty>? Properties { get; set; }
|
||||
public List<IProperty> Properties { get; set; } = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IList<IProperty> GetProperties() => Properties;
|
||||
|
||||
/// <summary>
|
||||
/// The image representing this tile. Only used for tilesets that composed of a collection of images.
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace DotTiled.Model;
|
|||
public enum ObjectAlignment
|
||||
{
|
||||
/// <summary>
|
||||
/// The alignment is unspecified. Tile objects will use <see cref="BottomLeft"/> in orthogonal maps, and <see cref="Bottom"/> in isometric maps.
|
||||
/// The alignment is unspecified. Tile objects will use <see cref="BottomLeft"/> in orthogonal maps, and <see cref="Bottom"/> in isometric maps.
|
||||
/// </summary>
|
||||
Unspecified,
|
||||
|
||||
|
@ -93,7 +93,7 @@ public enum FillMode
|
|||
/// <summary>
|
||||
/// A tileset is a collection of tiles that can be used in a tile layer, or by tile objects.
|
||||
/// </summary>
|
||||
public class Tileset
|
||||
public class Tileset : HasPropertiesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The TMX format version. Is incremented to match minor Tiled releases.
|
||||
|
@ -161,7 +161,7 @@ public class Tileset
|
|||
public ObjectAlignment ObjectAlignment { get; set; } = ObjectAlignment.Unspecified;
|
||||
|
||||
/// <summary>
|
||||
/// The size to use when rendering tiles from thie tileset on a tile layer. When set to <see cref="TileRenderSize.Grid"/>, the tile is drawn at the tile grid size of the map.
|
||||
/// The size to use when rendering tiles from thie tileset on a tile layer. When set to <see cref="TileRenderSize.Grid"/>, the tile is drawn at the tile grid size of the map.
|
||||
/// </summary>
|
||||
public TileRenderSize RenderSize { get; set; } = TileRenderSize.Tile;
|
||||
|
||||
|
@ -188,7 +188,10 @@ public class Tileset
|
|||
/// <summary>
|
||||
/// Tileset properties.
|
||||
/// </summary>
|
||||
public Dictionary<string, IProperty>? Properties { get; set; }
|
||||
public List<IProperty> Properties { get; set; } = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IList<IProperty> GetProperties() => Properties;
|
||||
|
||||
// public List<Terrain>? TerrainTypes { get; set; } TODO: Implement Terrain -> Wangset conversion during deserialization
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace DotTiled.Model;
|
|||
/// <summary>
|
||||
/// Represents a Wang color in a Wang set.
|
||||
/// </summary>
|
||||
public class WangColor
|
||||
public class WangColor : HasPropertiesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of this color.
|
||||
|
@ -35,5 +35,8 @@ public class WangColor
|
|||
/// <summary>
|
||||
/// The Wang color properties.
|
||||
/// </summary>
|
||||
public Dictionary<string, IProperty>? Properties { get; set; }
|
||||
public List<IProperty> Properties { get; set; } = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IList<IProperty> GetProperties() => Properties;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace DotTiled.Model;
|
|||
/// <summary>
|
||||
/// Defines a list of colors and any number of Wang tiles using these colors.
|
||||
/// </summary>
|
||||
public class Wangset
|
||||
public class Wangset : HasPropertiesBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the Wang set.
|
||||
|
@ -25,7 +25,10 @@ public class Wangset
|
|||
/// <summary>
|
||||
/// The Wang set properties.
|
||||
/// </summary>
|
||||
public Dictionary<string, IProperty>? Properties { get; set; }
|
||||
public List<IProperty> Properties { get; set; } = [];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override IList<IProperty> GetProperties() => Properties;
|
||||
|
||||
// Up to 254 Wang colors
|
||||
/// <summary>
|
||||
|
|
|
@ -76,39 +76,7 @@ internal static partial class Helpers
|
|||
internal static List<IProperty> CreateInstanceOfCustomClass(CustomClassDefinition customClassDefinition) =>
|
||||
customClassDefinition.Members.Select(x => x.Clone()).ToList();
|
||||
|
||||
internal static Dictionary<string, IProperty> MergeProperties(Dictionary<string, IProperty>? baseProperties, Dictionary<string, IProperty>? overrideProperties)
|
||||
{
|
||||
if (baseProperties is null)
|
||||
return overrideProperties ?? new Dictionary<string, IProperty>();
|
||||
|
||||
if (overrideProperties is null)
|
||||
return baseProperties;
|
||||
|
||||
var result = baseProperties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Clone());
|
||||
foreach (var (key, value) in overrideProperties)
|
||||
{
|
||||
if (!result.TryGetValue(key, out var baseProp))
|
||||
{
|
||||
result[key] = value;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value is ClassProperty classProp)
|
||||
{
|
||||
((ClassProperty)baseProp).Value = MergePropertiesList(((ClassProperty)baseProp).Value, classProp.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static IList<IProperty> MergePropertiesList(IList<IProperty>? baseProperties, IList<IProperty>? overrideProperties)
|
||||
internal static IList<IProperty> MergeProperties(IList<IProperty>? baseProperties, IList<IProperty>? overrideProperties)
|
||||
{
|
||||
if (baseProperties is null)
|
||||
return overrideProperties ?? [];
|
||||
|
@ -129,7 +97,7 @@ internal static partial class Helpers
|
|||
var existingProp = result.First(x => x.Name == overrideProp.Name);
|
||||
if (existingProp is ClassProperty classProp)
|
||||
{
|
||||
classProp.Value = MergePropertiesList(classProp.Value, ((ClassProperty)overrideProp).Value);
|
||||
classProp.Value = MergeProperties(classProp.Value, ((ClassProperty)overrideProp).Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ internal partial class Tmj
|
|||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
||||
var parallaxX = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
||||
var parallaxY = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), []);
|
||||
var layers = element.GetOptionalPropertyCustom<List<BaseLayer>>("layers", e => e.GetValueAsList<BaseLayer>(el => ReadLayer(el, externalTemplateResolver, customTypeDefinitions)), []);
|
||||
|
||||
return new Group
|
||||
|
|
|
@ -21,7 +21,7 @@ internal partial class Tmj
|
|||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
||||
var parallaxX = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
||||
var parallaxY = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), []);
|
||||
|
||||
var image = element.GetRequiredProperty<string>("image");
|
||||
var repeatX = element.GetOptionalProperty<bool>("repeatx", false);
|
||||
|
|
|
@ -58,7 +58,7 @@ internal partial class Tmj
|
|||
var nextObjectID = element.GetRequiredProperty<uint>("nextobjectid");
|
||||
var infinite = element.GetOptionalProperty<bool>("infinite", false);
|
||||
|
||||
var properties = element.GetOptionalPropertyCustom<List<IProperty>?>("properties", el => ReadPropertiesList(el, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", el => ReadProperties(el, customTypeDefinitions), []);
|
||||
|
||||
List<BaseLayer> layers = element.GetOptionalPropertyCustom<List<BaseLayer>>("layers", e => e.GetValueAsList<BaseLayer>(el => ReadLayer(el, externalTemplateResolver, customTypeDefinitions)), []);
|
||||
List<Tileset> tilesets = element.GetOptionalPropertyCustom<List<Tileset>>("tilesets", e => e.GetValueAsList<Tileset>(el => ReadTileset(el, externalTilesetResolver, externalTemplateResolver, customTypeDefinitions)), []);
|
||||
|
@ -84,7 +84,7 @@ internal partial class Tmj
|
|||
NextLayerID = nextLayerID,
|
||||
NextObjectID = nextObjectID,
|
||||
Infinite = infinite,
|
||||
Properties = properties ?? [],
|
||||
Properties = properties,
|
||||
Tilesets = tilesets,
|
||||
Layers = layers
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ internal partial class Tmj
|
|||
var offsetY = element.GetOptionalProperty<float>("offsety", 0.0f);
|
||||
var parallaxX = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
||||
var parallaxY = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), []);
|
||||
|
||||
var x = element.GetOptionalProperty<uint>("x", 0);
|
||||
var y = element.GetOptionalProperty<uint>("y", 0);
|
||||
|
@ -82,7 +82,7 @@ internal partial class Tmj
|
|||
bool pointDefault = false;
|
||||
List<Vector2>? polygonDefault = null;
|
||||
List<Vector2>? polylineDefault = null;
|
||||
Dictionary<string, IProperty>? propertiesDefault = null;
|
||||
List<IProperty> propertiesDefault = [];
|
||||
|
||||
var template = element.GetOptionalProperty<string?>("template", null);
|
||||
if (template is not null)
|
||||
|
@ -114,7 +114,7 @@ internal partial class Tmj
|
|||
var point = element.GetOptionalProperty<bool>("point", pointDefault);
|
||||
var polygon = element.GetOptionalPropertyCustom<List<Vector2>?>("polygon", ReadPoints, polygonDefault);
|
||||
var polyline = element.GetOptionalPropertyCustom<List<Vector2>?>("polyline", ReadPoints, polylineDefault);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), propertiesDefault);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), propertiesDefault);
|
||||
var rotation = element.GetOptionalProperty<float>("rotation", rotationDefault);
|
||||
var text = element.GetOptionalPropertyCustom<TextObject?>("text", ReadText, null);
|
||||
var type = element.GetOptionalProperty<string>("type", typeDefault);
|
||||
|
|
|
@ -8,42 +8,7 @@ namespace DotTiled.Serialization.Tmj;
|
|||
|
||||
internal partial class Tmj
|
||||
{
|
||||
internal static Dictionary<string, IProperty> ReadProperties(
|
||||
JsonElement element,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions) =>
|
||||
element.GetValueAsList<IProperty>(e =>
|
||||
{
|
||||
var name = e.GetRequiredProperty<string>("name");
|
||||
var type = e.GetOptionalPropertyParseable<PropertyType>("type", s => s switch
|
||||
{
|
||||
"string" => PropertyType.String,
|
||||
"int" => PropertyType.Int,
|
||||
"float" => PropertyType.Float,
|
||||
"bool" => PropertyType.Bool,
|
||||
"color" => PropertyType.Color,
|
||||
"file" => PropertyType.File,
|
||||
"object" => PropertyType.Object,
|
||||
"class" => PropertyType.Class,
|
||||
_ => throw new JsonException("Invalid property type")
|
||||
}, PropertyType.String);
|
||||
|
||||
IProperty property = type switch
|
||||
{
|
||||
PropertyType.String => new StringProperty { Name = name, Value = e.GetRequiredProperty<string>("value") },
|
||||
PropertyType.Int => new IntProperty { Name = name, Value = e.GetRequiredProperty<int>("value") },
|
||||
PropertyType.Float => new FloatProperty { Name = name, Value = e.GetRequiredProperty<float>("value") },
|
||||
PropertyType.Bool => new BoolProperty { Name = name, Value = e.GetRequiredProperty<bool>("value") },
|
||||
PropertyType.Color => new ColorProperty { Name = name, Value = e.GetRequiredPropertyParseable<Color>("value") },
|
||||
PropertyType.File => new FileProperty { Name = name, Value = e.GetRequiredProperty<string>("value") },
|
||||
PropertyType.Object => new ObjectProperty { Name = name, Value = e.GetRequiredProperty<uint>("value") },
|
||||
PropertyType.Class => ReadClassProperty(e, customTypeDefinitions),
|
||||
_ => throw new JsonException("Invalid property type")
|
||||
};
|
||||
|
||||
return property!;
|
||||
}).ToDictionary(p => p.Name);
|
||||
|
||||
internal static List<IProperty> ReadPropertiesList(
|
||||
internal static List<IProperty> ReadProperties(
|
||||
JsonElement element,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions) =>
|
||||
element.GetValueAsList<IProperty>(e =>
|
||||
|
@ -92,7 +57,7 @@ internal partial class Tmj
|
|||
var propsInType = Helpers.CreateInstanceOfCustomClass(ccd);
|
||||
var props = element.GetOptionalPropertyCustom<List<IProperty>>("value", el => ReadCustomClassProperties(el, ccd, customTypeDefinitions), []);
|
||||
|
||||
var mergedProps = Helpers.MergePropertiesList(propsInType, props);
|
||||
var mergedProps = Helpers.MergeProperties(propsInType, props);
|
||||
|
||||
return new ClassProperty
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ internal partial class Tmj
|
|||
var opacity = element.GetOptionalProperty<float>("opacity", 1.0f);
|
||||
var parallaxx = element.GetOptionalProperty<float>("parallaxx", 1.0f);
|
||||
var parallaxy = element.GetOptionalProperty<float>("parallaxy", 1.0f);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), []);
|
||||
var repeatX = element.GetOptionalProperty<bool>("repeatx", false);
|
||||
var repeatY = element.GetOptionalProperty<bool>("repeaty", false);
|
||||
var startX = element.GetOptionalProperty<int>("startx", 0);
|
||||
|
|
|
@ -44,7 +44,7 @@ internal partial class Tmj
|
|||
"bottomright" => ObjectAlignment.BottomRight,
|
||||
_ => throw new JsonException($"Unknown object alignment '{s}'")
|
||||
}, ObjectAlignment.Unspecified);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", el => ReadProperties(el, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", el => ReadProperties(el, customTypeDefinitions), []);
|
||||
var source = element.GetOptionalProperty<string?>("source", null);
|
||||
var spacing = element.GetOptionalProperty<uint?>("spacing", null);
|
||||
var tileCount = element.GetOptionalProperty<uint?>("tilecount", null);
|
||||
|
@ -176,7 +176,7 @@ internal partial class Tmj
|
|||
var height = e.GetOptionalProperty<uint>("height", imageHeight ?? 0);
|
||||
var objectGroup = e.GetOptionalPropertyCustom<ObjectLayer?>("objectgroup", e => ReadObjectLayer(e, externalTemplateResolver, customTypeDefinitions), null);
|
||||
var probability = e.GetOptionalProperty<float>("probability", 0.0f);
|
||||
var properties = e.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", el => ReadProperties(el, customTypeDefinitions), null);
|
||||
var properties = e.GetOptionalPropertyCustom("properties", el => ReadProperties(el, customTypeDefinitions), []);
|
||||
// var terrain, replaced by wangsets
|
||||
var type = e.GetOptionalProperty<string>("type", "");
|
||||
|
||||
|
@ -223,7 +223,7 @@ internal partial class Tmj
|
|||
var @clalss = element.GetOptionalProperty<string>("class", "");
|
||||
var colors = element.GetOptionalPropertyCustom<List<WangColor>>("colors", e => e.GetValueAsList<WangColor>(el => ReadWangColor(el, customTypeDefinitions)), []);
|
||||
var name = element.GetRequiredProperty<string>("name");
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), []);
|
||||
var tile = element.GetOptionalProperty<int>("tile", 0);
|
||||
var type = element.GetOptionalProperty<string>("type", "");
|
||||
var wangTiles = element.GetOptionalPropertyCustom<List<WangTile>>("wangtiles", e => e.GetValueAsList<WangTile>(ReadWangTile), []);
|
||||
|
@ -247,7 +247,7 @@ internal partial class Tmj
|
|||
var color = element.GetRequiredPropertyParseable<Color>("color", s => Color.Parse(s, CultureInfo.InvariantCulture));
|
||||
var name = element.GetRequiredProperty<string>("name");
|
||||
var probability = element.GetOptionalProperty<float>("probability", 1.0f);
|
||||
var properties = element.GetOptionalPropertyCustom<Dictionary<string, IProperty>?>("properties", e => ReadProperties(e, customTypeDefinitions), null);
|
||||
var properties = element.GetOptionalPropertyCustom("properties", e => ReadProperties(e, customTypeDefinitions), []);
|
||||
var tile = element.GetOptionalProperty<int>("tile", 0);
|
||||
|
||||
return new WangColor
|
||||
|
|
|
@ -69,7 +69,7 @@ internal partial class Tmx
|
|||
|
||||
reader.ProcessChildren("map", (r, elementName) => elementName switch
|
||||
{
|
||||
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadPropertiesList(r, customTypeDefinitions), "Properties"),
|
||||
"properties" => () => Helpers.SetAtMostOnce(ref properties, ReadProperties(r, customTypeDefinitions), "Properties"),
|
||||
"tileset" => () => tilesets.Add(ReadTileset(r, externalTilesetResolver, externalTemplateResolver, customTypeDefinitions)),
|
||||
"layer" => () => layers.Add(ReadTileLayer(r, infinite, customTypeDefinitions)),
|
||||
"objectgroup" => () => layers.Add(ReadObjectLayer(r, externalTemplateResolver, customTypeDefinitions)),
|
||||
|
|
|
@ -39,7 +39,7 @@ internal partial class Tmx
|
|||
}) ?? DrawOrder.TopDown;
|
||||
|
||||
// Elements
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
List<Model.Object> objects = [];
|
||||
|
||||
reader.ProcessChildren("objectgroup", (r, elementName) => elementName switch
|
||||
|
@ -66,7 +66,7 @@ internal partial class Tmx
|
|||
ParallaxX = parallaxX,
|
||||
ParallaxY = parallaxY,
|
||||
Color = color,
|
||||
Properties = properties,
|
||||
Properties = properties ?? [],
|
||||
DrawOrder = drawOrder,
|
||||
Objects = objects
|
||||
};
|
||||
|
@ -93,7 +93,7 @@ internal partial class Tmx
|
|||
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;
|
||||
List<IProperty>? propertiesDefault = obj?.Properties ?? null;
|
||||
|
||||
var id = reader.GetOptionalAttributeParseable<uint>("id") ?? idDefault;
|
||||
var name = reader.GetOptionalAttribute("name") ?? nameDefault;
|
||||
|
@ -109,11 +109,11 @@ internal partial class Tmx
|
|||
// Elements
|
||||
Model.Object? foundObject = null;
|
||||
int propertiesCounter = 0;
|
||||
Dictionary<string, IProperty>? properties = propertiesDefault;
|
||||
List<IProperty>? properties = propertiesDefault;
|
||||
|
||||
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)).ToList(), "Properties", ref propertiesCounter),
|
||||
"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"),
|
||||
|
@ -139,7 +139,7 @@ internal partial class Tmx
|
|||
foundObject.Height = height;
|
||||
foundObject.Rotation = rotation;
|
||||
foundObject.Visible = visible;
|
||||
foundObject.Properties = properties;
|
||||
foundObject.Properties = properties ?? [];
|
||||
foundObject.Template = template;
|
||||
|
||||
return OverrideObject(obj, foundObject);
|
||||
|
@ -161,7 +161,7 @@ internal partial class Tmx
|
|||
obj.Height = foundObject.Height;
|
||||
obj.Rotation = foundObject.Rotation;
|
||||
obj.Visible = foundObject.Visible;
|
||||
obj.Properties = Helpers.MergeProperties(obj.Properties, foundObject.Properties);
|
||||
obj.Properties = Helpers.MergeProperties(obj.Properties, foundObject.Properties).ToList();
|
||||
obj.Template = foundObject.Template;
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -7,43 +7,7 @@ namespace DotTiled.Serialization.Tmx;
|
|||
|
||||
internal partial class Tmx
|
||||
{
|
||||
internal static Dictionary<string, IProperty> ReadProperties(
|
||||
XmlReader reader,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
return reader.ReadList("properties", "property", (r) =>
|
||||
{
|
||||
var name = r.GetRequiredAttribute("name");
|
||||
var type = r.GetOptionalAttributeEnum<PropertyType>("type", (s) => s switch
|
||||
{
|
||||
"string" => PropertyType.String,
|
||||
"int" => PropertyType.Int,
|
||||
"float" => PropertyType.Float,
|
||||
"bool" => PropertyType.Bool,
|
||||
"color" => PropertyType.Color,
|
||||
"file" => PropertyType.File,
|
||||
"object" => PropertyType.Object,
|
||||
"class" => PropertyType.Class,
|
||||
_ => throw new XmlException("Invalid property type")
|
||||
}) ?? PropertyType.String;
|
||||
|
||||
IProperty property = type switch
|
||||
{
|
||||
PropertyType.String => new StringProperty { Name = name, Value = r.GetRequiredAttribute("value") },
|
||||
PropertyType.Int => new IntProperty { Name = name, Value = r.GetRequiredAttributeParseable<int>("value") },
|
||||
PropertyType.Float => new FloatProperty { Name = name, Value = r.GetRequiredAttributeParseable<float>("value") },
|
||||
PropertyType.Bool => new BoolProperty { Name = name, Value = r.GetRequiredAttributeParseable<bool>("value") },
|
||||
PropertyType.Color => new ColorProperty { Name = name, Value = r.GetRequiredAttributeParseable<Color>("value") },
|
||||
PropertyType.File => new FileProperty { Name = name, Value = r.GetRequiredAttribute("value") },
|
||||
PropertyType.Object => new ObjectProperty { Name = name, Value = r.GetRequiredAttributeParseable<uint>("value") },
|
||||
PropertyType.Class => ReadClassProperty(r, customTypeDefinitions),
|
||||
_ => throw new XmlException("Invalid property type")
|
||||
};
|
||||
return (name, property);
|
||||
}).ToDictionary(x => x.name, x => x.property);
|
||||
}
|
||||
|
||||
internal static List<IProperty> ReadPropertiesList(
|
||||
internal static List<IProperty> ReadProperties(
|
||||
XmlReader reader,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
|
@ -91,8 +55,8 @@ internal partial class Tmx
|
|||
{
|
||||
reader.ReadStartElement("property");
|
||||
var propsInType = Helpers.CreateInstanceOfCustomClass(ccd);
|
||||
var props = ReadPropertiesList(reader, customTypeDefinitions);
|
||||
var mergedProps = Helpers.MergePropertiesList(propsInType, props);
|
||||
var props = ReadProperties(reader, customTypeDefinitions);
|
||||
var mergedProps = Helpers.MergeProperties(propsInType, props);
|
||||
|
||||
reader.ReadEndElement();
|
||||
return new ClassProperty { Name = name, PropertyType = propertyType, Value = mergedProps };
|
||||
|
|
|
@ -28,7 +28,7 @@ internal partial class Tmx
|
|||
var parallaxX = reader.GetOptionalAttributeParseable<float>("parallaxx") ?? 1.0f;
|
||||
var parallaxY = reader.GetOptionalAttributeParseable<float>("parallaxy") ?? 1.0f;
|
||||
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
Data? data = null;
|
||||
|
||||
reader.ProcessChildren("layer", (r, elementName) => elementName switch
|
||||
|
@ -55,7 +55,7 @@ internal partial class Tmx
|
|||
ParallaxX = parallaxX,
|
||||
ParallaxY = parallaxY,
|
||||
Data = data,
|
||||
Properties = properties
|
||||
Properties = properties ?? []
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ internal partial class Tmx
|
|||
var repeatX = (reader.GetOptionalAttributeParseable<uint>("repeatx") ?? 0) == 1;
|
||||
var repeatY = (reader.GetOptionalAttributeParseable<uint>("repeaty") ?? 0) == 1;
|
||||
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
Image? image = null;
|
||||
|
||||
reader.ProcessChildren("imagelayer", (r, elementName) => elementName switch
|
||||
|
@ -102,7 +102,7 @@ internal partial class Tmx
|
|||
OffsetY = offsetY,
|
||||
ParallaxX = parallaxX,
|
||||
ParallaxY = parallaxY,
|
||||
Properties = properties,
|
||||
Properties = properties ?? [],
|
||||
Image = image,
|
||||
RepeatX = repeatX,
|
||||
RepeatY = repeatY
|
||||
|
@ -125,7 +125,7 @@ internal partial class Tmx
|
|||
var parallaxX = reader.GetOptionalAttributeParseable<float>("parallaxx") ?? 1.0f;
|
||||
var parallaxY = reader.GetOptionalAttributeParseable<float>("parallaxy") ?? 1.0f;
|
||||
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
List<BaseLayer> layers = [];
|
||||
|
||||
reader.ProcessChildren("group", (r, elementName) => elementName switch
|
||||
|
@ -150,7 +150,7 @@ internal partial class Tmx
|
|||
OffsetY = offsetY,
|
||||
ParallaxX = parallaxX,
|
||||
ParallaxY = parallaxY,
|
||||
Properties = properties,
|
||||
Properties = properties ?? [],
|
||||
Layers = layers
|
||||
};
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ internal partial class Tmx
|
|||
Image? image = null;
|
||||
TileOffset? tileOffset = null;
|
||||
Grid? grid = null;
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
List<Wangset>? wangsets = null;
|
||||
Transformations? transformations = null;
|
||||
List<Tile> tiles = [];
|
||||
|
@ -109,7 +109,7 @@ internal partial class Tmx
|
|||
Image = image,
|
||||
TileOffset = tileOffset,
|
||||
Grid = grid,
|
||||
Properties = properties,
|
||||
Properties = properties ?? [],
|
||||
Wangsets = wangsets,
|
||||
Transformations = transformations,
|
||||
Tiles = tiles
|
||||
|
@ -219,7 +219,7 @@ internal partial class Tmx
|
|||
var height = reader.GetOptionalAttributeParseable<uint>("height");
|
||||
|
||||
// Elements
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
Image? image = null;
|
||||
ObjectLayer? objectLayer = null;
|
||||
List<Frame>? animation = null;
|
||||
|
@ -247,7 +247,7 @@ internal partial class Tmx
|
|||
Y = y,
|
||||
Width = width ?? image?.Width ?? 0,
|
||||
Height = height ?? image?.Height ?? 0,
|
||||
Properties = properties,
|
||||
Properties = properties ?? [],
|
||||
Image = image,
|
||||
ObjectLayer = objectLayer,
|
||||
Animation = animation
|
||||
|
@ -269,7 +269,7 @@ internal partial class Tmx
|
|||
var tile = reader.GetRequiredAttributeParseable<int>("tile");
|
||||
|
||||
// Elements
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
List<WangColor> wangColors = [];
|
||||
List<WangTile> wangTiles = [];
|
||||
|
||||
|
@ -289,7 +289,7 @@ internal partial class Tmx
|
|||
Name = name,
|
||||
Class = @class,
|
||||
Tile = tile,
|
||||
Properties = properties,
|
||||
Properties = properties ?? [],
|
||||
WangColors = wangColors,
|
||||
WangTiles = wangTiles
|
||||
};
|
||||
|
@ -307,7 +307,7 @@ internal partial class Tmx
|
|||
var probability = reader.GetOptionalAttributeParseable<float>("probability") ?? 0f;
|
||||
|
||||
// Elements
|
||||
Dictionary<string, IProperty>? properties = null;
|
||||
List<IProperty>? properties = null;
|
||||
|
||||
reader.ProcessChildren("wangcolor", (r, elementName) => elementName switch
|
||||
{
|
||||
|
@ -322,7 +322,7 @@ internal partial class Tmx
|
|||
Color = color,
|
||||
Tile = tile,
|
||||
Probability = probability,
|
||||
Properties = properties
|
||||
Properties = properties ?? []
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue