void ScriptSerializedSceneObject::internal_Restore(ScriptSerializedSceneObject* thisPtr) { HSceneObject sceneObj = thisPtr->mSO; if (sceneObj.isDestroyed()) return; HSceneObject parent = sceneObj->getParent(); UINT32 numChildren = sceneObj->getNumChildren(); HSceneObject* children = nullptr; if (!thisPtr->mRecordHierarchy) { children = bs_stack_new<HSceneObject>(numChildren); for (UINT32 i = 0; i < numChildren; i++) { HSceneObject child = sceneObj->getChild(i); children[i] = child; child->setParent(HSceneObject()); } } sceneObj->destroy(true); GameObjectManager::instance().setDeserializationMode(GODM_RestoreExternal | GODM_UseNewIds); MemorySerializer serializer; SPtr<SceneObject> restored = std::static_pointer_cast<SceneObject>( serializer.decode(thisPtr->mSerializedObject, thisPtr->mSerializedObjectSize)); EditorUtility::restoreIds(restored->getHandle(), thisPtr->mSceneObjectProxy); restored->setParent(parent); if (!thisPtr->mRecordHierarchy) { for (UINT32 i = 0; i < numChildren; i++) children[i]->setParent(restored->getHandle()); bs_stack_delete(children, numChildren); } restored->_instantiate(); }
void PrefabDiff::applyDiff(const SPtr<PrefabObjectDiff>& diff, const HSceneObject& object) { if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Name) != 0) object->setName(diff->name); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Position) != 0) object->setPosition(diff->position); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Rotation) != 0) object->setRotation(diff->rotation); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Scale) != 0) object->setScale(diff->scale); if ((diff->soFlags & (UINT32)SceneObjectDiffFlags::Active) != 0) object->setActive(diff->isActive); // Note: It is important to remove objects and components first, before adding them. // Some systems rely on the fact that applyDiff added components/objects are // always at the end. const Vector<HComponent>& components = object->getComponents(); for (auto& removedId : diff->removedComponents) { for (auto component : components) { if (removedId == component->getLinkId()) { component->destroy(); break; } } } for (auto& removedId : diff->removedChildren) { UINT32 childCount = object->getNumChildren(); for (UINT32 i = 0; i < childCount; i++) { HSceneObject child = object->getChild(i); if (removedId == child->getLinkId()) { child->destroy(); break; } } } for (auto& addedComponentData : diff->addedComponents) { BinarySerializer bs; SPtr<Component> component = std::static_pointer_cast<Component>(bs._decodeFromIntermediate(addedComponentData)); object->addAndInitializeComponent(component); } for (auto& addedChildData : diff->addedChildren) { BinarySerializer bs; SPtr<SceneObject> sceneObject = std::static_pointer_cast<SceneObject>(bs._decodeFromIntermediate(addedChildData)); sceneObject->setParent(object); if(object->isInstantiated()) sceneObject->_instantiate(); } for (auto& componentDiff : diff->componentDiffs) { for (auto& component : components) { if (componentDiff->id == component->getLinkId()) { IDiff& diffHandler = component->getRTTI()->getDiffHandler(); diffHandler.applyDiff(component.getInternalPtr(), componentDiff->data); break; } } } for (auto& childDiff : diff->childDiffs) { UINT32 childCount = object->getNumChildren(); for (UINT32 i = 0; i < childCount; i++) { HSceneObject child = object->getChild(i); if (childDiff->id == child->getLinkId()) { applyDiff(childDiff, child); break; } } } }