summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-06-03 10:15:45 +0800
committerchai <215380520@qq.com>2024-06-03 10:15:45 +0800
commitacea7b2e728787a0d83bbf83c8c1f042d2c32e7e (patch)
tree0bfec05c1ca2d71be2c337bcd110a0421f19318b /Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs
parent88febcb02bf127d961c6471d9e846c0e1315f5c3 (diff)
+ plugins project
Diffstat (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs')
-rw-r--r--Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs89
1 files changed, 89 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs
new file mode 100644
index 0000000..c31549b
--- /dev/null
+++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Gui/Serialization/ControlStyleJsonConverter.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using MonoGame.Extended.Collections;
+using MonoGame.Extended.Gui.Controls;
+
+namespace MonoGame.Extended.Gui.Serialization
+{
+ public class ControlStyleJsonConverter : JsonConverter<ControlStyle>
+ {
+ private readonly Dictionary<string, Type> _controlTypes;
+ private const string _typeProperty = "Type";
+ private const string _nameProperty = "Name";
+
+ public ControlStyleJsonConverter(params Type[] customControlTypes)
+ {
+ _controlTypes = typeof(Control)
+ .GetTypeInfo()
+ .Assembly
+ .ExportedTypes
+ .Concat(customControlTypes)
+ .Where(t => t.GetTypeInfo().IsSubclassOf(typeof(Control)))
+ .ToDictionary(t => t.Name);
+ }
+
+ /// <inheritdoc />
+ public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(ControlStyle);
+
+ /// <inheritdoc />
+ public override ControlStyle Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var dictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options);
+ var name = dictionary.GetValueOrDefault(_nameProperty) as string;
+ var typeName = dictionary.GetValueOrDefault(_typeProperty) as string;
+
+ if (!_controlTypes.TryGetValue(typeName, out Type controlType))
+ throw new FormatException("invalid control type: " + typeName);
+
+ var targetType = typeName != null ? controlType : typeof(Control);
+ var properties = targetType
+ .GetRuntimeProperties()
+ .ToDictionary(p => p.Name);
+ var style = new ControlStyle(name, targetType);
+
+ foreach (var keyValuePair in dictionary.Where(i => i.Key != _typeProperty))
+ {
+ var propertyName = keyValuePair.Key;
+ var rawValue = keyValuePair.Value;
+
+ PropertyInfo propertyInfo;
+ var value = properties.TryGetValue(propertyName, out propertyInfo)
+ ? DeserializeValueAs(rawValue, propertyInfo.PropertyType)
+ : DeserializeValueAs(rawValue, typeof(object));
+
+ style.Add(propertyName, value);
+ }
+
+ return style;
+ }
+
+ private static object DeserializeValueAs(object value, Type type)
+ {
+ var json = JsonSerializer.Serialize(value, type);
+ return JsonSerializer.Deserialize(json, type);
+ }
+
+ /// <inheritdoc />
+ public override void Write(Utf8JsonWriter writer, ControlStyle value, JsonSerializerOptions options)
+ {
+ var style = (ControlStyle)value;
+ var dictionary = new Dictionary<string, object> { [_typeProperty] = style.TargetType.Name };
+
+ foreach (var keyValuePair in style)
+ dictionary.Add(keyValuePair.Key, keyValuePair.Value);
+
+ JsonSerializer.Serialize(writer, dictionary);
+ }
+
+
+
+
+
+
+ }
+}