diff --git a/Source/Engine/Serialization/JsonCustomSerializers/ExtendedDefaultContractResolver.cs b/Source/Engine/Serialization/JsonCustomSerializers/ExtendedDefaultContractResolver.cs
index cc07597e8..2018015a9 100644
--- a/Source/Engine/Serialization/JsonCustomSerializers/ExtendedDefaultContractResolver.cs
+++ b/Source/Engine/Serialization/JsonCustomSerializers/ExtendedDefaultContractResolver.cs
@@ -47,6 +47,33 @@ namespace FlaxEngine.Json.JsonCustomSerializers
return contract;
}
+ ///
+ protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
+ {
+ var contract = base.CreateDictionaryContract(objectType);
+
+ // Override contract to save enums keys as integer
+ if (contract.DictionaryKeyType?.IsEnum ?? false)
+ {
+ var enumType = contract.DictionaryKeyType;
+ contract.DictionaryKeyResolver = name =>
+ {
+ try
+ {
+ var e = Enum.Parse(enumType, name);
+ name = Convert.ToInt32(e).ToString();
+ }
+ catch
+ {
+ // Ignore errors
+ }
+ return name;
+ };
+ }
+
+ return contract;
+ }
+
protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
{
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
diff --git a/Source/Engine/Serialization/Serialization.h b/Source/Engine/Serialization/Serialization.h
index 4ccbe533c..41517da58 100644
--- a/Source/Engine/Serialization/Serialization.h
+++ b/Source/Engine/Serialization/Serialization.h
@@ -18,6 +18,18 @@ struct VariantType;
namespace Serialization
{
+ inline int32 DeserializeInt(ISerializable::DeserializeStream& stream)
+ {
+ int32 result = 0;
+ if (stream.IsInt())
+ result = stream.GetInt();
+ else if (stream.IsFloat())
+ result = (int32)stream.GetFloat();
+ else if (stream.IsString())
+ StringUtils::Parse(stream.GetString(), &result);
+ return result;
+ }
+
// In-build types
inline bool ShouldSerialize(const bool& v, const void* otherObj)
@@ -43,7 +55,7 @@ namespace Serialization
}
inline void Deserialize(ISerializable::DeserializeStream& stream, int8& v, ISerializeModifier* modifier)
{
- v = stream.GetInt();
+ v = (int8)DeserializeInt(stream);
}
inline bool ShouldSerialize(const char& v, const void* otherObj)
@@ -82,7 +94,7 @@ namespace Serialization
}
inline void Deserialize(ISerializable::DeserializeStream& stream, int16& v, ISerializeModifier* modifier)
{
- v = stream.GetInt();
+ v = (int16)DeserializeInt(stream);
}
inline bool ShouldSerialize(const int32& v, const void* otherObj)
@@ -95,7 +107,7 @@ namespace Serialization
}
inline void Deserialize(ISerializable::DeserializeStream& stream, int32& v, ISerializeModifier* modifier)
{
- v = stream.GetInt();
+ v = DeserializeInt(stream);
}
inline bool ShouldSerialize(const int64& v, const void* otherObj)
@@ -204,7 +216,7 @@ namespace Serialization
template
inline typename TEnableIf::Value>::Type Deserialize(ISerializable::DeserializeStream& stream, T& v, ISerializeModifier* modifier)
{
- v = (T)stream.GetInt();
+ v = (T)(stream.IsInt() ? stream.GetInt() : 0);
}
// Common types
@@ -577,21 +589,34 @@ namespace Serialization
template
inline void Deserialize(ISerializable::DeserializeStream& stream, Dictionary& v, ISerializeModifier* modifier)
{
- if (!stream.IsArray())
- return;
- const auto& streamArray = stream.GetArray();
v.Clear();
- v.EnsureCapacity(streamArray.Size() * 3);
- for (rapidjson::SizeType i = 0; i < streamArray.Size(); i++)
+ if (stream.IsArray())
{
- auto& streamItem = streamArray[i];
- const auto mKey = SERIALIZE_FIND_MEMBER(streamItem, "Key");
- const auto mValue = SERIALIZE_FIND_MEMBER(streamItem, "Value");
- if (mKey != streamItem.MemberEnd() && mValue != streamItem.MemberEnd())
+ const auto& streamArray = stream.GetArray();
+ const int32 size = streamArray.Size();
+ v.EnsureCapacity(size * 3);
+ for (int32 i = 0; i < size; i++)
+ {
+ auto& streamItem = streamArray[i];
+ const auto mKey = SERIALIZE_FIND_MEMBER(streamItem, "Key");
+ const auto mValue = SERIALIZE_FIND_MEMBER(streamItem, "Value");
+ if (mKey != streamItem.MemberEnd() && mValue != streamItem.MemberEnd())
+ {
+ KeyType key;
+ Deserialize(mKey->value, key, modifier);
+ Deserialize(mValue->value, v[key], modifier);
+ }
+ }
+ }
+ else if (stream.IsObject())
+ {
+ const int32 size = stream.MemberCount();
+ v.EnsureCapacity(size * 3);
+ for (auto i = stream.MemberBegin(); i != stream.MemberEnd(); ++i)
{
KeyType key;
- Deserialize(mKey->value, key, modifier);
- Deserialize(mValue->value, v[key], modifier);
+ Deserialize(i->name, key, modifier);
+ Deserialize(i->value, v[key], modifier);
}
}
}