|
|
@@ -1,161 +1,19 @@
|
|
|
#include "BsBinaryDiff.h"
|
|
|
+#include "BsSerializedObject.h"
|
|
|
#include "BsBinarySerializer.h"
|
|
|
#include "BsBinaryCloner.h"
|
|
|
#include "BsRTTIType.h"
|
|
|
|
|
|
namespace BansheeEngine
|
|
|
{
|
|
|
- SPtr<SerializedObject> BinaryDiff::generateDiff(const SPtr<SerializedObject>& orgObj,
|
|
|
+ SPtr<SerializedObject> IDiff::generateDiff(const SPtr<SerializedObject>& orgObj,
|
|
|
const SPtr<SerializedObject>& newObj)
|
|
|
{
|
|
|
ObjectMap objectMap;
|
|
|
return generateDiff(orgObj, newObj, objectMap);
|
|
|
}
|
|
|
|
|
|
- SPtr<SerializedObject> BinaryDiff::generateDiff(const SPtr<SerializedObject>& orgObj,
|
|
|
- const SPtr<SerializedObject>& newObj, ObjectMap& objectMap)
|
|
|
- {
|
|
|
- if (orgObj == nullptr || newObj == nullptr || orgObj->getRootTypeId() != newObj->getRootTypeId())
|
|
|
- return nullptr;
|
|
|
-
|
|
|
- RTTITypeBase* rootRtti = IReflectable::_getRTTIfromTypeId(newObj->getRootTypeId());
|
|
|
- if (rootRtti == nullptr)
|
|
|
- return nullptr;
|
|
|
-
|
|
|
- SPtr<SerializedObject> output;
|
|
|
- for (auto& subObject : newObj->subObjects)
|
|
|
- {
|
|
|
- RTTITypeBase* rtti = IReflectable::_getRTTIfromTypeId(subObject.typeId);
|
|
|
- if (rtti == nullptr)
|
|
|
- continue;
|
|
|
-
|
|
|
- SerializedSubObject* orgSubObject = nullptr;
|
|
|
- for (auto& curSubObject : orgObj->subObjects)
|
|
|
- {
|
|
|
- if (curSubObject.typeId == subObject.typeId)
|
|
|
- {
|
|
|
- orgSubObject = &curSubObject;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- SerializedSubObject* diffSubObject = nullptr;
|
|
|
- for (auto& newEntry : subObject.entries)
|
|
|
- {
|
|
|
- RTTIField* genericField = rtti->findField(newEntry.first);
|
|
|
- if (genericField == nullptr)
|
|
|
- continue;
|
|
|
-
|
|
|
- SPtr<SerializedInstance> newEntryData = newEntry.second.serialized;
|
|
|
- SPtr<SerializedInstance> orgEntryData;
|
|
|
-
|
|
|
- if (orgSubObject != nullptr)
|
|
|
- {
|
|
|
- auto orgEntryFind = orgSubObject->entries.find(newEntry.first);
|
|
|
- if (orgEntryFind != orgSubObject->entries.end())
|
|
|
- orgEntryData = newEntry.second.serialized;
|
|
|
- }
|
|
|
-
|
|
|
- SPtr<SerializedInstance> modification;
|
|
|
- bool hasModification = false;
|
|
|
- if (genericField->isArray())
|
|
|
- {
|
|
|
- SPtr<SerializedArray> orgArrayData = std::static_pointer_cast<SerializedArray>(orgEntryData);
|
|
|
- SPtr<SerializedArray> newArrayData = std::static_pointer_cast<SerializedArray>(newEntryData);
|
|
|
-
|
|
|
- SPtr<SerializedArray> serializedArray;
|
|
|
-
|
|
|
- if (newEntryData != nullptr && orgEntryData != nullptr)
|
|
|
- {
|
|
|
- for (auto& arrayEntryPair : newArrayData->entries)
|
|
|
- {
|
|
|
- SPtr<SerializedInstance> arrayModification;
|
|
|
-
|
|
|
- auto iterFind = orgArrayData->entries.find(arrayEntryPair.first);
|
|
|
- if (iterFind == orgArrayData->entries.end())
|
|
|
- arrayModification = arrayEntryPair.second.serialized->clone();
|
|
|
- else
|
|
|
- {
|
|
|
- arrayModification = generateDiff(genericField->mType, iterFind->second.serialized,
|
|
|
- arrayEntryPair.second.serialized, objectMap);
|
|
|
- }
|
|
|
-
|
|
|
- if (arrayModification != nullptr)
|
|
|
- {
|
|
|
- if (serializedArray == nullptr)
|
|
|
- {
|
|
|
- serializedArray = bs_shared_ptr<SerializedArray>();
|
|
|
- serializedArray->numElements = newArrayData->numElements;
|
|
|
- }
|
|
|
-
|
|
|
- SerializedArrayEntry arrayEntry;
|
|
|
- arrayEntry.index = arrayEntryPair.first;
|
|
|
- arrayEntry.serialized = arrayModification;
|
|
|
- serializedArray->entries[arrayEntryPair.first] = arrayEntry;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if (newEntryData == nullptr)
|
|
|
- {
|
|
|
- serializedArray = bs_shared_ptr<SerializedArray>();
|
|
|
- }
|
|
|
- else if (orgEntryData == nullptr)
|
|
|
- {
|
|
|
- serializedArray = std::static_pointer_cast<SerializedArray>(newArrayData->clone());
|
|
|
- }
|
|
|
-
|
|
|
- modification = serializedArray;
|
|
|
- hasModification = modification != nullptr;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (newEntryData != nullptr && orgEntryData != nullptr)
|
|
|
- {
|
|
|
- modification = generateDiff(genericField->mType, orgEntryData, newEntryData, objectMap);
|
|
|
- hasModification = modification != nullptr;
|
|
|
- }
|
|
|
- else if (newEntryData == nullptr)
|
|
|
- {
|
|
|
- switch (genericField->mType)
|
|
|
- {
|
|
|
- case SerializableFT_Plain:
|
|
|
- case SerializableFT_DataBlock:
|
|
|
- modification = bs_shared_ptr<SerializedField>();
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- hasModification = true;
|
|
|
- }
|
|
|
- else if (orgEntryData == nullptr)
|
|
|
- {
|
|
|
- modification = newEntryData->clone();
|
|
|
- hasModification = modification != nullptr;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (hasModification)
|
|
|
- {
|
|
|
- if (output == nullptr)
|
|
|
- output = bs_shared_ptr<SerializedObject>();
|
|
|
-
|
|
|
- if (diffSubObject == nullptr)
|
|
|
- {
|
|
|
- output->subObjects.push_back(SerializedSubObject());
|
|
|
- diffSubObject = &output->subObjects.back();
|
|
|
- }
|
|
|
-
|
|
|
- SerializedEntry modificationEntry;
|
|
|
- modificationEntry.fieldId = genericField->mUniqueId;
|
|
|
- modificationEntry.serialized = modification;
|
|
|
- diffSubObject->entries[genericField->mUniqueId] = modificationEntry;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return output;
|
|
|
- }
|
|
|
-
|
|
|
- SPtr<SerializedInstance> BinaryDiff::generateDiff(UINT32 fieldType, const SPtr<SerializedInstance>& orgData,
|
|
|
+ SPtr<SerializedInstance> IDiff::generateDiff(RTTITypeBase* rtti, UINT32 fieldType, const SPtr<SerializedInstance>& orgData,
|
|
|
const SPtr<SerializedInstance>& newData, ObjectMap& objectMap)
|
|
|
{
|
|
|
SPtr<SerializedInstance> modification;
|
|
|
@@ -172,7 +30,17 @@ namespace BansheeEngine
|
|
|
modification = iterFind->second;
|
|
|
else
|
|
|
{
|
|
|
- SPtr<SerializedObject> objectDiff = generateDiff(orgObjData, newObjData);
|
|
|
+ RTTITypeBase* childRtti = nullptr;
|
|
|
+ if (orgObjData->getRootTypeId() == newObjData->getRootTypeId())
|
|
|
+ childRtti = IReflectable::_getRTTIfromTypeId(newObjData->getRootTypeId());
|
|
|
+
|
|
|
+ SPtr<SerializedObject> objectDiff;
|
|
|
+ if (childRtti != nullptr)
|
|
|
+ {
|
|
|
+ IDiff& handler = childRtti->getDiffHandler();
|
|
|
+ objectDiff = handler.generateDiff(orgObjData, newObjData, objectMap);
|
|
|
+ }
|
|
|
+
|
|
|
if (objectDiff != nullptr)
|
|
|
objectMap[newObjData] = objectDiff;
|
|
|
|
|
|
@@ -188,7 +56,7 @@ namespace BansheeEngine
|
|
|
|
|
|
bool isModified = orgFieldData->size != newFieldData->size;
|
|
|
if (!isModified)
|
|
|
- isModified = memcmp(orgFieldData->value, newFieldData->value, newFieldData->size) == 0;
|
|
|
+ isModified = memcmp(orgFieldData->value, newFieldData->value, newFieldData->size) != 0;
|
|
|
|
|
|
if (isModified)
|
|
|
modification = newFieldData->clone();
|
|
|
@@ -199,26 +67,31 @@ namespace BansheeEngine
|
|
|
return modification;
|
|
|
}
|
|
|
|
|
|
- void BinaryDiff::applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff)
|
|
|
+ void IDiff::applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff)
|
|
|
{
|
|
|
Vector<DiffCommand> commands;
|
|
|
|
|
|
DiffObjectMap objectMap;
|
|
|
applyDiff(object, diff, objectMap, commands);
|
|
|
|
|
|
+ IReflectable* destObject = nullptr;
|
|
|
+ Stack<IReflectable*> objectStack;
|
|
|
+
|
|
|
for (auto& command : commands)
|
|
|
{
|
|
|
bool isArray = (command.type & Diff_ArrayFlag) != 0;
|
|
|
- DiffCommandType type = (DiffCommandType)(command.type & 0xFF);
|
|
|
- IReflectable* destObject = command.object.get();
|
|
|
+ DiffCommandType type = (DiffCommandType)(command.type & 0xF);
|
|
|
|
|
|
switch (type)
|
|
|
{
|
|
|
- case Diff_ArraySize:
|
|
|
- command.field->setArraySize(destObject, command.size);
|
|
|
+ case Diff_ArraySize:
|
|
|
+ command.field->setArraySize(destObject, command.arraySize);
|
|
|
break;
|
|
|
case Diff_ObjectStart:
|
|
|
{
|
|
|
+ destObject = command.object.get();
|
|
|
+ objectStack.push(destObject);
|
|
|
+
|
|
|
RTTITypeBase* curRtti = destObject->getRTTI();
|
|
|
while (curRtti != nullptr)
|
|
|
{
|
|
|
@@ -227,7 +100,7 @@ namespace BansheeEngine
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
- case Diff_ObjectEnd:
|
|
|
+ case Diff_ObjectEnd:
|
|
|
{
|
|
|
Stack<RTTITypeBase*> rttiTypes;
|
|
|
RTTITypeBase* curRtti = destObject->getRTTI();
|
|
|
@@ -242,6 +115,13 @@ namespace BansheeEngine
|
|
|
rttiTypes.top()->onDeserializationEnded(destObject);
|
|
|
rttiTypes.pop();
|
|
|
}
|
|
|
+
|
|
|
+ objectStack.pop();
|
|
|
+
|
|
|
+ if (!objectStack.empty())
|
|
|
+ destObject = objectStack.top();
|
|
|
+ else
|
|
|
+ destObject = nullptr;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
@@ -256,13 +136,13 @@ namespace BansheeEngine
|
|
|
field->setArrayValue(destObject, command.arrayIdx, command.object);
|
|
|
}
|
|
|
break;
|
|
|
- case Diff_Reflectable:
|
|
|
+ case Diff_Reflectable:
|
|
|
{
|
|
|
RTTIReflectableFieldBase* field = static_cast<RTTIReflectableFieldBase*>(command.field);
|
|
|
- field->setArrayValue(object.get(), command.arrayIdx, *command.object);
|
|
|
+ field->setArrayValue(destObject, command.arrayIdx, *command.object);
|
|
|
}
|
|
|
break;
|
|
|
- case Diff_Plain:
|
|
|
+ case Diff_Plain:
|
|
|
{
|
|
|
RTTIPlainFieldBase* field = static_cast<RTTIPlainFieldBase*>(command.field);
|
|
|
field->arrayElemFromBuffer(destObject, command.arrayIdx, command.value);
|
|
|
@@ -283,7 +163,7 @@ namespace BansheeEngine
|
|
|
case Diff_Reflectable:
|
|
|
{
|
|
|
RTTIReflectableFieldBase* field = static_cast<RTTIReflectableFieldBase*>(command.field);
|
|
|
- field->setValue(object.get(), *command.object);
|
|
|
+ field->setValue(destObject, *command.object);
|
|
|
}
|
|
|
break;
|
|
|
case Diff_Plain:
|
|
|
@@ -292,7 +172,7 @@ namespace BansheeEngine
|
|
|
field->fromBuffer(destObject, command.value);
|
|
|
}
|
|
|
break;
|
|
|
- case Diff_DataBlock:
|
|
|
+ case Diff_DataBlock:
|
|
|
{
|
|
|
RTTIManagedDataBlockFieldBase* field = static_cast<RTTIManagedDataBlockFieldBase*>(command.field);
|
|
|
UINT8* dataCopy = field->allocate(destObject, command.size);
|
|
|
@@ -307,6 +187,150 @@ namespace BansheeEngine
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ void IDiff::applyDiff(RTTITypeBase* rtti, const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff,
|
|
|
+ DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands)
|
|
|
+ {
|
|
|
+ IDiff& diffHandler = rtti->getDiffHandler();
|
|
|
+ diffHandler.applyDiff(object, diff, objectMap, diffCommands);
|
|
|
+ }
|
|
|
+
|
|
|
+ SPtr<SerializedObject> BinaryDiff::generateDiff(const SPtr<SerializedObject>& orgObj,
|
|
|
+ const SPtr<SerializedObject>& newObj, ObjectMap& objectMap)
|
|
|
+ {
|
|
|
+ SPtr<SerializedObject> output;
|
|
|
+ for (auto& subObject : newObj->subObjects)
|
|
|
+ {
|
|
|
+ RTTITypeBase* rtti = IReflectable::_getRTTIfromTypeId(subObject.typeId);
|
|
|
+ if (rtti == nullptr)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ SerializedSubObject* orgSubObject = nullptr;
|
|
|
+ for (auto& curSubObject : orgObj->subObjects)
|
|
|
+ {
|
|
|
+ if (curSubObject.typeId == subObject.typeId)
|
|
|
+ {
|
|
|
+ orgSubObject = &curSubObject;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ SerializedSubObject* diffSubObject = nullptr;
|
|
|
+ for (auto& newEntry : subObject.entries)
|
|
|
+ {
|
|
|
+ RTTIField* genericField = rtti->findField(newEntry.first);
|
|
|
+ if (genericField == nullptr)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ SPtr<SerializedInstance> newEntryData = newEntry.second.serialized;
|
|
|
+ SPtr<SerializedInstance> orgEntryData;
|
|
|
+
|
|
|
+ if (orgSubObject != nullptr)
|
|
|
+ {
|
|
|
+ auto orgEntryFind = orgSubObject->entries.find(newEntry.first);
|
|
|
+ if (orgEntryFind != orgSubObject->entries.end())
|
|
|
+ orgEntryData = orgEntryFind->second.serialized;
|
|
|
+ }
|
|
|
+
|
|
|
+ SPtr<SerializedInstance> modification;
|
|
|
+ bool hasModification = false;
|
|
|
+ if (genericField->isArray())
|
|
|
+ {
|
|
|
+ SPtr<SerializedArray> orgArrayData = std::static_pointer_cast<SerializedArray>(orgEntryData);
|
|
|
+ SPtr<SerializedArray> newArrayData = std::static_pointer_cast<SerializedArray>(newEntryData);
|
|
|
+
|
|
|
+ SPtr<SerializedArray> serializedArray;
|
|
|
+
|
|
|
+ if (newEntryData != nullptr && orgEntryData != nullptr)
|
|
|
+ {
|
|
|
+ for (auto& arrayEntryPair : newArrayData->entries)
|
|
|
+ {
|
|
|
+ SPtr<SerializedInstance> arrayModification;
|
|
|
+
|
|
|
+ auto iterFind = orgArrayData->entries.find(arrayEntryPair.first);
|
|
|
+ if (iterFind == orgArrayData->entries.end())
|
|
|
+ arrayModification = arrayEntryPair.second.serialized->clone();
|
|
|
+ else
|
|
|
+ {
|
|
|
+ arrayModification = IDiff::generateDiff(rtti, genericField->mType, iterFind->second.serialized,
|
|
|
+ arrayEntryPair.second.serialized, objectMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (arrayModification != nullptr)
|
|
|
+ {
|
|
|
+ if (serializedArray == nullptr)
|
|
|
+ {
|
|
|
+ serializedArray = bs_shared_ptr<SerializedArray>();
|
|
|
+ serializedArray->numElements = newArrayData->numElements;
|
|
|
+ }
|
|
|
+
|
|
|
+ SerializedArrayEntry arrayEntry;
|
|
|
+ arrayEntry.index = arrayEntryPair.first;
|
|
|
+ arrayEntry.serialized = arrayModification;
|
|
|
+ serializedArray->entries[arrayEntryPair.first] = arrayEntry;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (newEntryData == nullptr)
|
|
|
+ {
|
|
|
+ serializedArray = bs_shared_ptr<SerializedArray>();
|
|
|
+ }
|
|
|
+ else if (orgEntryData == nullptr)
|
|
|
+ {
|
|
|
+ serializedArray = std::static_pointer_cast<SerializedArray>(newArrayData->clone());
|
|
|
+ }
|
|
|
+
|
|
|
+ modification = serializedArray;
|
|
|
+ hasModification = modification != nullptr;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (newEntryData != nullptr && orgEntryData != nullptr)
|
|
|
+ {
|
|
|
+ modification = IDiff::generateDiff(rtti, genericField->mType, orgEntryData, newEntryData, objectMap);
|
|
|
+ hasModification = modification != nullptr;
|
|
|
+ }
|
|
|
+ else if (newEntryData == nullptr)
|
|
|
+ {
|
|
|
+ switch (genericField->mType)
|
|
|
+ {
|
|
|
+ case SerializableFT_Plain:
|
|
|
+ case SerializableFT_DataBlock:
|
|
|
+ modification = bs_shared_ptr<SerializedField>();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ hasModification = true;
|
|
|
+ }
|
|
|
+ else if (orgEntryData == nullptr)
|
|
|
+ {
|
|
|
+ modification = newEntryData->clone();
|
|
|
+ hasModification = modification != nullptr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hasModification)
|
|
|
+ {
|
|
|
+ if (output == nullptr)
|
|
|
+ output = bs_shared_ptr<SerializedObject>();
|
|
|
+
|
|
|
+ if (diffSubObject == nullptr)
|
|
|
+ {
|
|
|
+ output->subObjects.push_back(SerializedSubObject());
|
|
|
+ diffSubObject = &output->subObjects.back();
|
|
|
+ diffSubObject->typeId = rtti->getRTTIId();
|
|
|
+ }
|
|
|
+
|
|
|
+ SerializedEntry modificationEntry;
|
|
|
+ modificationEntry.fieldId = genericField->mUniqueId;
|
|
|
+ modificationEntry.serialized = modification;
|
|
|
+ diffSubObject->entries[genericField->mUniqueId] = modificationEntry;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return output;
|
|
|
+ }
|
|
|
+
|
|
|
void BinaryDiff::applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff,
|
|
|
DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands)
|
|
|
{
|
|
|
@@ -363,7 +387,7 @@ namespace BansheeEngine
|
|
|
UINT32 orgArraySize = genericField->getArraySize(object.get());
|
|
|
for (auto& arrayElem : diffArray->entries)
|
|
|
{
|
|
|
- SPtr<SerializedObject> arrayElemData = std::static_pointer_cast<SerializedObject>(diffData);
|
|
|
+ SPtr<SerializedObject> arrayElemData = std::static_pointer_cast<SerializedObject>(arrayElem.second.serialized);
|
|
|
|
|
|
DiffCommand command;
|
|
|
command.field = genericField;
|
|
|
@@ -383,7 +407,10 @@ namespace BansheeEngine
|
|
|
{
|
|
|
SPtr<IReflectable> childObj = field->getArrayValue(object.get(), arrayElem.first);
|
|
|
if (childObj != nullptr)
|
|
|
- applyDiff(childObj, arrayElemData);
|
|
|
+ {
|
|
|
+ IDiff::applyDiff(childObj->getRTTI(), childObj, arrayElemData, objectMap, diffCommands);
|
|
|
+ command.object = childObj;
|
|
|
+ }
|
|
|
else
|
|
|
needsNewObject = true;
|
|
|
}
|
|
|
@@ -400,7 +427,7 @@ namespace BansheeEngine
|
|
|
findObj = objectMap.insert(std::make_pair(arrayElemData, newObject)).first;
|
|
|
}
|
|
|
|
|
|
- applyDiff(findObj->second, arrayElemData);
|
|
|
+ IDiff::applyDiff(childRtti, findObj->second, arrayElemData, objectMap, diffCommands);
|
|
|
command.object = findObj->second;
|
|
|
diffCommands.push_back(command);
|
|
|
}
|
|
|
@@ -434,7 +461,8 @@ namespace BansheeEngine
|
|
|
|
|
|
if (arrayElem.first < orgArraySize)
|
|
|
{
|
|
|
- applyDiff(newArrayElements[arrayElem.first], arrayElemData);
|
|
|
+ SPtr<IReflectable> childObj = newArrayElements[arrayElem.first];
|
|
|
+ IDiff::applyDiff(childObj->getRTTI(), childObj, arrayElemData, objectMap, diffCommands);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -442,7 +470,7 @@ namespace BansheeEngine
|
|
|
if (childRtti != nullptr)
|
|
|
{
|
|
|
SPtr<IReflectable> newObject = childRtti->newRTTIObject();
|
|
|
- applyDiff(newObject, arrayElemData);
|
|
|
+ IDiff::applyDiff(childRtti, newObject, arrayElemData, objectMap, diffCommands);
|
|
|
|
|
|
newArrayElements[arrayElem.first] = newObject;
|
|
|
}
|
|
|
@@ -470,7 +498,7 @@ namespace BansheeEngine
|
|
|
{
|
|
|
DiffCommand command;
|
|
|
command.field = genericField;
|
|
|
- command.type = Diff_DataBlock | Diff_ArrayFlag;
|
|
|
+ command.type = Diff_Plain | Diff_ArrayFlag;
|
|
|
command.value = fieldData->value;
|
|
|
command.size = fieldData->size;
|
|
|
command.arrayIdx = arrayElem.first;
|
|
|
@@ -512,7 +540,7 @@ namespace BansheeEngine
|
|
|
findObj = objectMap.insert(std::make_pair(fieldObjectData, newObject)).first;
|
|
|
}
|
|
|
|
|
|
- applyDiff(findObj->second, fieldObjectData);
|
|
|
+ IDiff::applyDiff(childRtti, findObj->second, fieldObjectData, objectMap, diffCommands);
|
|
|
command.object = findObj->second;
|
|
|
}
|
|
|
else
|
|
|
@@ -522,7 +550,8 @@ namespace BansheeEngine
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- applyDiff(childObj, fieldObjectData);
|
|
|
+ IDiff::applyDiff(childObj->getRTTI(), childObj, fieldObjectData, objectMap, diffCommands);
|
|
|
+ command.object = childObj;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -537,7 +566,7 @@ namespace BansheeEngine
|
|
|
IReflectable& childObj = field->getValue(object.get());
|
|
|
std::shared_ptr<IReflectable> clonedObj = BinaryCloner::clone(&childObj, true);
|
|
|
|
|
|
- applyDiff(clonedObj, fieldObjectData);
|
|
|
+ IDiff::applyDiff(clonedObj->getRTTI(), clonedObj, fieldObjectData, objectMap, diffCommands);
|
|
|
|
|
|
DiffCommand command;
|
|
|
command.field = genericField;
|