Fix C# Json serialization to use proper value comparison for structures with Scene Object references
#3499
This commit is contained in:
@@ -13,7 +13,7 @@ namespace FlaxEngine
|
||||
public bool ValueEquals(object other)
|
||||
{
|
||||
var o = (MeshReference)other;
|
||||
return JsonSerializer.ValueEquals(Actor, o.Actor) &&
|
||||
return JsonSerializer.SceneObjectEquals(Actor, o.Actor) &&
|
||||
LODIndex == o.LODIndex &&
|
||||
MeshIndex == o.MeshIndex;
|
||||
}
|
||||
|
||||
@@ -227,9 +227,9 @@ public:
|
||||
void PrefabInstanceData::CollectPrefabInstances(PrefabInstancesData& prefabInstancesData, const Guid& prefabId, Actor* defaultInstance, Actor* targetActor)
|
||||
{
|
||||
ScopeLock lock(PrefabManager::PrefabsReferencesLocker);
|
||||
if (PrefabManager::PrefabsReferences.ContainsKey(prefabId))
|
||||
if (auto instancesPtr = PrefabManager::PrefabsReferences.TryGet(prefabId))
|
||||
{
|
||||
auto& instances = PrefabManager::PrefabsReferences[prefabId];
|
||||
auto& instances = *instancesPtr;
|
||||
int32 usedCount = 0;
|
||||
for (int32 instanceIndex = 0; instanceIndex < instances.Count(); instanceIndex++)
|
||||
{
|
||||
|
||||
@@ -270,8 +270,8 @@ namespace FlaxEngine.Json
|
||||
|
||||
// Special case when saving reference to prefab object and the objects are different but the point to the same prefab object
|
||||
// In that case, skip saving reference as it's defined in prefab (will be populated via IdsMapping during deserialization)
|
||||
if (objA is SceneObject sceneA && objB is SceneObject sceneB && sceneA && sceneB && sceneA.HasPrefabLink && sceneB.HasPrefabLink)
|
||||
return sceneA.PrefabObjectID == sceneB.PrefabObjectID;
|
||||
if (objA is SceneObject sceneObjA && objB is SceneObject sceneObjB && sceneObjA && sceneObjB && sceneObjA.HasPrefabLink && sceneObjB.HasPrefabLink)
|
||||
return sceneObjA.PrefabObjectID == sceneObjB.PrefabObjectID;
|
||||
|
||||
// Comparing an Int32 and Int64 both of the same value returns false, make types the same then compare
|
||||
if (objA.GetType() != objB.GetType())
|
||||
@@ -286,7 +286,6 @@ namespace FlaxEngine.Json
|
||||
type == typeof(Int32) ||
|
||||
type == typeof(UInt32) ||
|
||||
type == typeof(Int64) ||
|
||||
type == typeof(SByte) ||
|
||||
type == typeof(UInt64);
|
||||
}
|
||||
if (IsInteger(objA) && IsInteger(objB))
|
||||
@@ -301,6 +300,12 @@ namespace FlaxEngine.Json
|
||||
{
|
||||
if (aList.Count != bList.Count)
|
||||
return false;
|
||||
for (int i = 0; i < aList.Count; i++)
|
||||
{
|
||||
if (!ValueEquals(aList[i], bList[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (objA is IEnumerable aEnumerable && objB is IEnumerable bEnumerable)
|
||||
{
|
||||
@@ -316,8 +321,29 @@ namespace FlaxEngine.Json
|
||||
return !bEnumerator.MoveNext();
|
||||
}
|
||||
|
||||
if (objA is ICustomValueEquals customValueEquals && objA.GetType() == objB.GetType())
|
||||
// Custom comparer
|
||||
if (objA is ICustomValueEquals customValueEquals)
|
||||
return customValueEquals.ValueEquals(objB);
|
||||
|
||||
// If type contains SceneObject references then it needs to use custom comparision that handles prefab links (see SceneObjectEquals)
|
||||
if (objA.GetType().IsStructure())
|
||||
{
|
||||
var contract = Settings.ContractResolver.ResolveContract(objA.GetType());
|
||||
if (contract is JsonObjectContract objContract)
|
||||
{
|
||||
foreach (var property in objContract.Properties)
|
||||
{
|
||||
var valueProvider = property.ValueProvider;
|
||||
var propA = valueProvider.GetValue(objA);
|
||||
var propB = valueProvider.GetValue(objB);
|
||||
if (!ValueEquals(propA, propB))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Generic fallback
|
||||
return objA.Equals(objB);
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user