Przeglądaj źródła

Fixing a crash due to SceneObject restore operation (objects were instantiated before their IDs were restored)

BearishSun 9 lat temu
rodzic
commit
90a42af3f4

+ 6 - 6
Source/BansheeCore/Include/BsSceneObject.h

@@ -134,6 +134,12 @@ namespace BansheeEngine
 		/** Assigns a new prefab diff object. Caller must ensure the prefab diff was generated for this object. */
 		/** Assigns a new prefab diff object. Caller must ensure the prefab diff was generated for this object. */
 		void _setPrefabDiff(const SPtr<PrefabDiff>& diff) { mPrefabDiff = diff; }
 		void _setPrefabDiff(const SPtr<PrefabDiff>& diff) { mPrefabDiff = diff; }
 
 
+		/** Recursively enables the provided set of flags on this object and all children. */
+		void _setFlags(UINT32 flags);
+
+		/** Recursively disables the provided set of flags on this object and all children. */
+		void _unsetFlags(UINT32 flags);
+
 		/** @} */
 		/** @} */
 
 
 	private:
 	private:
@@ -170,12 +176,6 @@ namespace BansheeEngine
 		 */
 		 */
 		void destroyInternal(GameObjectHandleBase& handle, bool immediate = false) override;
 		void destroyInternal(GameObjectHandleBase& handle, bool immediate = false) override;
 
 
-		/** Recursively enables the provided set of flags on this object and all children. */
-		void setFlags(UINT32 flags);
-
-		/** Recursively disables the provided set of flags on this object and all children. */
-		void unsetFlags(UINT32 flags);
-
 		/**	Checks is the scene object instantiated and visible in the scene. */
 		/**	Checks is the scene object instantiated and visible in the scene. */
 		bool isInstantiated() const { return (mFlags & SOF_DontInstantiate) == 0; }
 		bool isInstantiated() const { return (mFlags & SOF_DontInstantiate) == 0; }
 
 

+ 9 - 9
Source/BansheeCore/Source/BsSceneObject.cpp

@@ -183,20 +183,20 @@ namespace BansheeEngine
 		return (mFlags & flag) != 0;
 		return (mFlags & flag) != 0;
 	}
 	}
 
 
-	void SceneObject::setFlags(UINT32 flags)
+	void SceneObject::_setFlags(UINT32 flags)
 	{
 	{
 		mFlags |= flags;
 		mFlags |= flags;
 
 
 		for (auto& child : mChildren)
 		for (auto& child : mChildren)
-			child->setFlags(flags);
+			child->_setFlags(flags);
 	}
 	}
 
 
-	void SceneObject::unsetFlags(UINT32 flags)
+	void SceneObject::_unsetFlags(UINT32 flags)
 	{
 	{
 		mFlags &= ~flags;
 		mFlags &= ~flags;
 
 
 		for (auto& child : mChildren)
 		for (auto& child : mChildren)
-			child->unsetFlags(flags);
+			child->_unsetFlags(flags);
 	}
 	}
 
 
 	void SceneObject::_instantiate(bool prefabOnly)
 	void SceneObject::_instantiate(bool prefabOnly)
@@ -585,7 +585,7 @@ namespace BansheeEngine
 	{
 	{
 		mChildren.push_back(object); 
 		mChildren.push_back(object); 
 
 
-		object->setFlags(mFlags);
+		object->_setFlags(mFlags);
 	}
 	}
 
 
 	void SceneObject::removeChild(const HSceneObject& object)
 	void SceneObject::removeChild(const HSceneObject& object)
@@ -694,9 +694,9 @@ namespace BansheeEngine
 		bool isInstantiated = !hasFlag(SOF_DontInstantiate);
 		bool isInstantiated = !hasFlag(SOF_DontInstantiate);
 
 
 		if (!instantiate)
 		if (!instantiate)
-			setFlags(SOF_DontInstantiate);
+			_setFlags(SOF_DontInstantiate);
 		else
 		else
-			unsetFlags(SOF_DontInstantiate);
+			_unsetFlags(SOF_DontInstantiate);
 
 
 		UINT32 bufferSize = 0;
 		UINT32 bufferSize = 0;
 
 
@@ -708,9 +708,9 @@ namespace BansheeEngine
 		bs_free(buffer);
 		bs_free(buffer);
 
 
 		if(isInstantiated)
 		if(isInstantiated)
-			unsetFlags(SOF_DontInstantiate);
+			_unsetFlags(SOF_DontInstantiate);
 		else
 		else
-			setFlags(SOF_DontInstantiate);
+			_setFlags(SOF_DontInstantiate);
 
 
 		return cloneObj->mThisHandle;
 		return cloneObj->mThisHandle;
 	}
 	}

+ 8 - 0
Source/BansheeEditor/Source/BsCmdDeleteSO.cpp

@@ -72,13 +72,21 @@ namespace BansheeEngine
 
 
 		EditorUtility::restoreIds(restored->getHandle(), mSceneObjectProxy);
 		EditorUtility::restoreIds(restored->getHandle(), mSceneObjectProxy);
 		restored->setParent(parent);
 		restored->setParent(parent);
+
+		restored->_instantiate();
 	}
 	}
 
 
 	void CmdDeleteSO::recordSO(const HSceneObject& sceneObject)
 	void CmdDeleteSO::recordSO(const HSceneObject& sceneObject)
 	{
 	{
+		bool isInstantiated = !mSceneObject->hasFlag(SOF_DontInstantiate);
+		mSceneObject->_setFlags(SOF_DontInstantiate);
+
 		MemorySerializer serializer;
 		MemorySerializer serializer;
 		mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
 		mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
 
 
+		if (isInstantiated)
+			mSceneObject->_unsetFlags(SOF_DontInstantiate);
+
 		HSceneObject parent = mSceneObject->getParent();
 		HSceneObject parent = mSceneObject->getParent();
 		if (parent != nullptr)
 		if (parent != nullptr)
 			mSerializedObjectParentId = parent->getInstanceId();
 			mSerializedObjectParentId = parent->getInstanceId();

+ 8 - 0
Source/BansheeEditor/Source/BsCmdRecordSO.cpp

@@ -87,6 +87,8 @@ namespace BansheeEngine
 
 
 			bs_stack_delete(children, numChildren);
 			bs_stack_delete(children, numChildren);
 		}
 		}
+
+		restored->_instantiate();
 	}
 	}
 
 
 	void CmdRecordSO::recordSO(const HSceneObject& sceneObject)
 	void CmdRecordSO::recordSO(const HSceneObject& sceneObject)
@@ -106,9 +108,15 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
+		bool isInstantiated = !mSceneObject->hasFlag(SOF_DontInstantiate);
+		mSceneObject->_setFlags(SOF_DontInstantiate);
+
 		MemorySerializer serializer;
 		MemorySerializer serializer;
 		mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
 		mSerializedObject = serializer.encode(mSceneObject.get(), mSerializedObjectSize);
 
 
+		if (isInstantiated)
+			mSceneObject->_unsetFlags(SOF_DontInstantiate);
+
 		mSceneObjectProxy = EditorUtility::createProxy(mSceneObject);
 		mSceneObjectProxy = EditorUtility::createProxy(mSceneObject);
 
 
 		if (!mRecordHierarchy)
 		if (!mRecordHierarchy)

+ 8 - 0
Source/SBansheeEditor/Source/BsScriptSerializedSceneObject.cpp

@@ -30,9 +30,15 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
+		bool isInstantiated = !mSO->hasFlag(SOF_DontInstantiate);
+		mSO->_setFlags(SOF_DontInstantiate);
+
 		MemorySerializer serializer;
 		MemorySerializer serializer;
 		mSerializedObject = serializer.encode(mSO.get(), mSerializedObjectSize);
 		mSerializedObject = serializer.encode(mSO.get(), mSerializedObjectSize);
 
 
+		if (isInstantiated)
+			mSO->_unsetFlags(SOF_DontInstantiate);
+
 		mSceneObjectProxy = EditorUtility::createProxy(mSO);
 		mSceneObjectProxy = EditorUtility::createProxy(mSO);
 
 
 		if (!mRecordHierarchy)
 		if (!mRecordHierarchy)
@@ -106,5 +112,7 @@ namespace BansheeEngine
 
 
 			bs_stack_delete(children, numChildren);
 			bs_stack_delete(children, numChildren);
 		}
 		}
+
+		restored->_instantiate();
 	}
 	}
 }
 }