diff --git a/src/DotTiled.Tests/IntegrationTests/CustomTypes/FromTypeUsedInLoaderTests.cs b/src/DotTiled.Tests/IntegrationTests/CustomTypes/FromTypeUsedInLoaderTests.cs index dae9464..c0d580f 100644 --- a/src/DotTiled.Tests/IntegrationTests/CustomTypes/FromTypeUsedInLoaderTests.cs +++ b/src/DotTiled.Tests/IntegrationTests/CustomTypes/FromTypeUsedInLoaderTests.cs @@ -177,4 +177,96 @@ public void LoadMap_MapHasClassAndClassIsDefinedAndFieldIsOverridenFromDefault_R // Assert DotTiledAssert.AssertMap(expectedMap, result); } + + private enum TestEnum + { + Value1, + Value2 + } + + private sealed class TestClassWithEnum + { + public TestEnum Enum { get; set; } = TestEnum.Value1; + } + + [Fact] + public void LoadMap_MapHasClassWithEnumAndClassIsDefined_ReturnsCorrectMap() + { + // Arrange + var resourceReader = Substitute.For(); + resourceReader.Read("map.tmx").Returns( + """ + + + + + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0 + + + + """); + var classDefinition = CustomClassDefinition.FromClass(); + var loader = Loader.DefaultWith( + resourceReader: resourceReader, + customTypeDefinitions: [classDefinition]); + var expectedMap = new Map + { + Class = "TestClassWithEnum", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = new Color { R = 0, G = 0, B = 0, A = 0 }, + Version = "1.10", + TiledVersion = "1.11.0", + NextLayerID = 2, + NextObjectID = 1, + Layers = [ + new TileLayer + { + ID = 1, + Name = "Tile Layer 1", + Width = 5, + Height = 5, + Data = new Data + { + Encoding = DataEncoding.Csv, + GlobalTileIDs = new Optional([ + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ]), + FlippingFlags = new Optional([ + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, + FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None + ]) + } + } + ], + Properties = [ + new EnumProperty { Name = "Enum", PropertyType = "TestEnum", Value = new HashSet { "Value1" } } + ] + }; + + // Act + var result = loader.LoadMap("map.tmx"); + + // Assert + DotTiledAssert.AssertMap(expectedMap, result); + } } diff --git a/src/DotTiled.Tests/UnitTests/Properties/CustomTypes/CustomClassDefinitionTests.cs b/src/DotTiled.Tests/UnitTests/Properties/CustomTypes/CustomClassDefinitionTests.cs index 7e920e3..74e716c 100644 --- a/src/DotTiled.Tests/UnitTests/Properties/CustomTypes/CustomClassDefinitionTests.cs +++ b/src/DotTiled.Tests/UnitTests/Properties/CustomTypes/CustomClassDefinitionTests.cs @@ -70,11 +70,42 @@ private sealed class TestClass3WithOverridenNestedClass ] }; + private enum TestEnum1 + { + Value1, + Value2 + } + + [Flags] + private enum TestFlags1 + { + Value1 = 0b001, + Value2 = 0b010, + Value3 = 0b100 + } + + private sealed class TestClass4WithEnums + { + public TestEnum1 Enum { get; set; } = TestEnum1.Value2; + public TestFlags1 Flags { get; set; } = TestFlags1.Value1 | TestFlags1.Value2; + } + + private static CustomClassDefinition ExpectedTestClass4WithEnumsDefinition => new CustomClassDefinition + { + Name = "TestClass4WithEnums", + UseAs = CustomClassUseAs.All, + Members = [ + new EnumProperty { Name = "Enum", PropertyType = "TestEnum1", Value = new HashSet { "Value2" } }, + new EnumProperty { Name = "Flags", PropertyType = "TestFlags1", Value = new HashSet { "Value1", "Value2" } } + ] + }; + private static IEnumerable<(Type, CustomClassDefinition)> GetCustomClassDefinitionTestData() { yield return (typeof(TestClass1), ExpectedTestClass1Definition); yield return (typeof(TestClass2WithNestedClass), ExpectedTestClass2WithNestedClassDefinition); yield return (typeof(TestClass3WithOverridenNestedClass), ExpectedTestClass3WithOverridenNestedClassDefinition); + yield return (typeof(TestClass4WithEnums), ExpectedTestClass4WithEnumsDefinition); } public static IEnumerable CustomClassDefinitionTestData => diff --git a/src/DotTiled/Properties/CustomTypes/CustomClassDefinition.cs b/src/DotTiled/Properties/CustomTypes/CustomClassDefinition.cs index 83e0fbe..37b8c6e 100644 --- a/src/DotTiled/Properties/CustomTypes/CustomClassDefinition.cs +++ b/src/DotTiled/Properties/CustomTypes/CustomClassDefinition.cs @@ -165,6 +165,17 @@ private static IProperty ConvertPropertyInfoToIProperty(object instance, Propert return new IntProperty { Name = propertyInfo.Name, Value = (int)propertyInfo.GetValue(instance) }; case Type t when t.IsClass: return new ClassProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = GetNestedProperties(propertyInfo.PropertyType, propertyInfo.GetValue(instance)) }; + case Type t when t.IsEnum: + var enumDefinition = CustomEnumDefinition.FromEnum(t); + + if (!enumDefinition.ValueAsFlags) + return new EnumProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = new HashSet { propertyInfo.GetValue(instance).ToString() } }; + + var flags = (Enum)propertyInfo.GetValue(instance); + var enumValues = Enum.GetValues(t).Cast(); + var enumNames = enumValues.Where(flags.HasFlag).Select(e => e.ToString()); + + return new EnumProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = enumNames.ToHashSet() }; default: break; }