UserProperties.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using System.Linq;
  6. using Newtonsoft.Json;
  7. namespace InABox.Core
  8. {
  9. public class UserProperty
  10. {
  11. [DoNotSerialize]
  12. public Type Type { get; set; }
  13. public object? Value { get; set; }
  14. }
  15. [Serializable]
  16. public class UserProperties
  17. {
  18. public delegate void PropertyChangedEventHandler(object sender, string name, object? before, object? after);
  19. public UserProperties()
  20. {
  21. Dictionary = new Dictionary<string, UserProperty>();
  22. //_dictionary = new Dictionary<string, UserProperty>();
  23. }
  24. public Dictionary<string, UserProperty> Dictionary { get; set; }
  25. //public Type ParentType { get; set; }
  26. public object? this[string key]
  27. {
  28. get => Get(key);
  29. set => Set(key, value);
  30. }
  31. [JsonIgnore]
  32. public Dictionary<string, object?> AsDictionary
  33. {
  34. get
  35. {
  36. var result = new Dictionary<string, object?>();
  37. foreach (var key in Dictionary.Keys)
  38. result[key] = this[key];
  39. return result;
  40. }
  41. set
  42. {
  43. Clear();
  44. foreach (var key in value.Keys)
  45. this[key] = value[key];
  46. }
  47. }
  48. [JsonIgnore]
  49. public int Count => Dictionary.Count;
  50. public override bool Equals(object obj)
  51. {
  52. if (!(obj is UserProperties other))
  53. return false;
  54. if (Dictionary.Count != other.Count) // Require equal count.
  55. return false;
  56. foreach (var pair in Dictionary)
  57. try
  58. {
  59. var value = other[pair.Key];
  60. if (value == null)
  61. {
  62. if (pair.Value != null)
  63. return false;
  64. }
  65. else if (!value.Equals(pair.Value))
  66. {
  67. return false;
  68. }
  69. }
  70. catch
  71. {
  72. return false;
  73. }
  74. return true;
  75. }
  76. public event PropertyChangedEventHandler? OnPropertyChanged;
  77. private object? Get(string key)
  78. {
  79. var prop = new UserProperty { Type = typeof(string), Value = "" };
  80. if (Dictionary.ContainsKey(key))
  81. prop = Dictionary[key];
  82. if (prop.Type == null)
  83. return prop.Value;
  84. if (prop.Value == null)
  85. return prop.Type == typeof(object) ? null : Activator.CreateInstance(prop.Type);
  86. if (prop.Value.GetType() == prop.Type)
  87. return prop.Value;
  88. var tc = TypeDescriptor.GetConverter(prop.Type);
  89. return tc.ConvertFrom(prop.Value);
  90. }
  91. private void Set(string key, object? obj)
  92. {
  93. var before = Dictionary.GetValueOrDefault(key);
  94. Dictionary[key] = new UserProperty { Type = obj?.GetType() ?? typeof(object), Value = obj };
  95. OnPropertyChanged?.Invoke(this, key, before, obj);
  96. }
  97. public bool ContainsKey(string key)
  98. {
  99. return Dictionary.ContainsKey(key);
  100. }
  101. public void Clear()
  102. {
  103. Dictionary.Clear();
  104. }
  105. public string[] GetKeys()
  106. {
  107. return Dictionary.Keys.ToArray();
  108. }
  109. internal void Load(IEnumerable<KeyValuePair<string, object?>> pairs)
  110. {
  111. foreach (var pair in pairs)
  112. Dictionary[pair.Key] = new UserProperty { Type = pair.Value != null ? pair.Value.GetType() : typeof(object), Value = pair.Value };
  113. }
  114. internal void LoadFromDictionary(Dictionary<string, object?> defaultProperties)
  115. {
  116. foreach (var pair in defaultProperties)
  117. Dictionary[pair.Key] = new UserProperty { Type = pair.Value != null ? pair.Value.GetType() : typeof(object), Value = pair.Value };
  118. }
  119. }
  120. public class UserPropertiesJsonConverter : JsonConverter
  121. {
  122. public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
  123. {
  124. if (!(value is UserProperties props)) return;
  125. writer.WriteStartObject();
  126. foreach (var key in props.GetKeys())
  127. if (props[key] != null)
  128. {
  129. writer.WritePropertyName(key);
  130. writer.WriteValue(props[key] is string ? props[key] as string : props[key]);
  131. }
  132. writer.WriteEndObject();
  133. }
  134. public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
  135. {
  136. var result = new UserProperties();
  137. while (reader.TokenType != JsonToken.EndObject && reader.Read())
  138. if (reader.Value != null)
  139. {
  140. var key = reader.Value.ToString();
  141. reader.Read();
  142. result[key] = reader.Value;
  143. }
  144. return result;
  145. }
  146. public override bool CanConvert(Type objectType)
  147. {
  148. return objectType == typeof(UserProperties);
  149. }
  150. }
  151. }