Fix crashes in various dictionary usages caused by duplicated keys
#1925 #1924
This commit is contained in:
@@ -253,7 +253,7 @@ void PrefabInstanceData::SerializePrefabInstances(PrefabInstancesData& prefabIns
|
|||||||
for (int32 i = 0; i < sceneObjects->Count(); i++)
|
for (int32 i = 0; i < sceneObjects->Count(); i++)
|
||||||
{
|
{
|
||||||
SceneObject* obj = sceneObjects.Value->At(i);
|
SceneObject* obj = sceneObjects.Value->At(i);
|
||||||
instance.PrefabInstanceIdToDataIndex.Add(obj->GetSceneObjectId(), i);
|
instance.PrefabInstanceIdToDataIndex[obj->GetSceneObjectId()] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmpBuffer.Clear();
|
tmpBuffer.Clear();
|
||||||
@@ -313,15 +313,13 @@ bool PrefabInstanceData::SynchronizePrefabInstances(PrefabInstancesData& prefabI
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier.Value->IdsMapping.Add(obj->GetPrefabObjectID(), obj->GetSceneObjectId());
|
modifier.Value->IdsMapping[obj->GetPrefabObjectID()] = obj->GetSceneObjectId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate new IDs for the added objects (objects in prefab has to have a unique Ids, other than the targetActor instance objects to prevent Id collisions)
|
// Generate new IDs for the added objects (objects in prefab has to have a unique Ids, other than the targetActor instance objects to prevent Id collisions)
|
||||||
for (int32 i = 0; i < newPrefabObjectIds.Count(); i++)
|
for (int32 i = 0; i < newPrefabObjectIds.Count(); i++)
|
||||||
{
|
modifier->IdsMapping[newPrefabObjectIds[i]] = Guid::New();
|
||||||
modifier->IdsMapping.Add(newPrefabObjectIds[i], Guid::New());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new objects added to prefab
|
// Create new objects added to prefab
|
||||||
int32 deserializeSceneObjectIndex = sceneObjects->Count();
|
int32 deserializeSceneObjectIndex = sceneObjects->Count();
|
||||||
@@ -786,7 +784,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache connection for fast lookup
|
// Cache connection for fast lookup
|
||||||
diffPrefabObjectIdToDataIndex.Add(obj->GetPrefabObjectID(), i);
|
diffPrefabObjectIdToDataIndex[obj->GetPrefabObjectID()] = i;
|
||||||
|
|
||||||
// Strip unwanted data
|
// Strip unwanted data
|
||||||
data.RemoveMember("ID");
|
data.RemoveMember("ID");
|
||||||
@@ -796,7 +794,7 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Object if a new thing
|
// Object if a new thing
|
||||||
newPrefabInstanceIdToDataIndex.Add(obj->GetSceneObjectId(), i);
|
newPrefabInstanceIdToDataIndex[obj->GetSceneObjectId()] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,8 +834,8 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr
|
|||||||
for (auto i = newPrefabInstanceIdToDataIndex.Begin(); i.IsNotEnd(); ++i)
|
for (auto i = newPrefabInstanceIdToDataIndex.Begin(); i.IsNotEnd(); ++i)
|
||||||
{
|
{
|
||||||
const auto prefabObjectId = Guid::New();
|
const auto prefabObjectId = Guid::New();
|
||||||
newPrefabInstanceIdToPrefabObjectId.Add(i->Key, prefabObjectId);
|
newPrefabInstanceIdToPrefabObjectId[i->Key] = prefabObjectId;
|
||||||
modifier->IdsMapping.Add(i->Key, prefabObjectId);
|
modifier->IdsMapping[i->Key] = prefabObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add inverse IDs mapping to link added objects and references inside them to the prefab objects
|
// Add inverse IDs mapping to link added objects and references inside them to the prefab objects
|
||||||
|
|||||||
@@ -374,13 +374,13 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat
|
|||||||
if (targetActor->HasParent())
|
if (targetActor->HasParent())
|
||||||
{
|
{
|
||||||
// Unlink from parent actor
|
// Unlink from parent actor
|
||||||
objectInstanceIdToPrefabObjectId.Add(targetActor->GetParent()->GetID(), Guid::Empty);
|
objectInstanceIdToPrefabObjectId[targetActor->GetParent()->GetID()] = Guid::Empty;
|
||||||
}
|
}
|
||||||
for (int32 i = 0; i < sceneObjects->Count(); i++)
|
for (int32 i = 0; i < sceneObjects->Count(); i++)
|
||||||
{
|
{
|
||||||
// Generate new IDs for the prefab objects (other than reference instance used to create prefab)
|
// Generate new IDs for the prefab objects (other than reference instance used to create prefab)
|
||||||
const SceneObject* obj = sceneObjects->At(i);
|
const SceneObject* obj = sceneObjects->At(i);
|
||||||
objectInstanceIdToPrefabObjectId.Add(obj->GetSceneObjectId(), Guid::New());
|
objectInstanceIdToPrefabObjectId[obj->GetSceneObjectId()] = Guid::New();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// Parse json to DOM document
|
// Parse json to DOM document
|
||||||
|
|||||||
@@ -1026,30 +1026,28 @@ bool Scripting::IsTypeFromGameScripts(MClass* type)
|
|||||||
|
|
||||||
void Scripting::RegisterObject(ScriptingObject* obj)
|
void Scripting::RegisterObject(ScriptingObject* obj)
|
||||||
{
|
{
|
||||||
|
const Guid id = obj->GetID();
|
||||||
ScopeLock lock(_objectsLocker);
|
ScopeLock lock(_objectsLocker);
|
||||||
|
|
||||||
//ASSERT(!_objectsDictionary.ContainsValue(obj));
|
//ASSERT(!_objectsDictionary.ContainsValue(obj));
|
||||||
#if ENABLE_ASSERTION
|
#if ENABLE_ASSERTION
|
||||||
#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING
|
#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING
|
||||||
ScriptingObjectData other;
|
ScriptingObjectData other;
|
||||||
if (_objectsDictionary.TryGet(obj->GetID(), other))
|
if (_objectsDictionary.TryGet(id, other))
|
||||||
#else
|
#else
|
||||||
ScriptingObject* other;
|
ScriptingObject* other;
|
||||||
if (_objectsDictionary.TryGet(obj->GetID(), other))
|
if (_objectsDictionary.TryGet(id, other))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Something went wrong...
|
// Something went wrong...
|
||||||
LOG(Error, "Objects registry already contains object with ID={0} (type '{3}')! Trying to register object {1} (type '{2}').", obj->GetID(), obj->ToString(), String(obj->GetClass()->GetFullName()), String(other->GetClass()->GetFullName()));
|
LOG(Error, "Objects registry already contains object with ID={0} (type '{3}')! Trying to register object {1} (type '{2}').", id, obj->ToString(), String(obj->GetClass()->GetFullName()), String(other->GetClass()->GetFullName()));
|
||||||
_objectsDictionary.Remove(obj->GetID());
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
ASSERT(!_objectsDictionary.ContainsKey(obj->_id));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING
|
#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING
|
||||||
LOG(Info, "[RegisterObject] obj = 0x{0:x}, {1}", (uint64)obj, String(ScriptingObjectData(obj).TypeName));
|
LOG(Info, "[RegisterObject] obj = 0x{0:x}, {1}", (uint64)obj, String(ScriptingObjectData(obj).TypeName));
|
||||||
#endif
|
#endif
|
||||||
_objectsDictionary.Add(obj->GetID(), obj);
|
_objectsDictionary[id] = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scripting::UnregisterObject(ScriptingObject* obj)
|
void Scripting::UnregisterObject(ScriptingObject* obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user