ソースを参照

Bugfix: Fixing crash on shutdown
- GUI elements are properly deallocated before script system shutdown
- Freeing a persistent reference to components allocated from script code

BearishSun 8 年 前
コミット
0a6233e4bd

+ 11 - 5
Source/BansheeEngine/GUI/BsGUIManager.cpp

@@ -133,9 +133,8 @@ namespace bs
 		for(auto& widget : widgetCopy)
 		for(auto& widget : widgetCopy)
 			widget.widget->_destroy();
 			widget.widget->_destroy();
 
 
-		// Ensure everything queued get destroyed, loop until queue empties
-		while (processDestroyQueue())
-		{ }
+		// Ensure everything queued get destroyed
+		processDestroyQueue();
 
 
 		mOnPointerPressedConn.disconnect();
 		mOnPointerPressedConn.disconnect();
 		mOnPointerReleasedConn.disconnect();
 		mOnPointerReleasedConn.disconnect();
@@ -350,7 +349,7 @@ namespace bs
 
 
 			mForcedFocusElements.clear();
 			mForcedFocusElements.clear();
 
 
-		} while (processDestroyQueue());
+		} while (processDestroyQueueIteration());
 
 
 		// Blink caret
 		// Blink caret
 		float curTime = gTime().getTime();
 		float curTime = gTime().getTime();
@@ -423,6 +422,13 @@ namespace bs
 		}
 		}
 	}
 	}
 
 
+	void GUIManager::processDestroyQueue()
+	{
+		// Loop until everything empties
+		while (processDestroyQueueIteration())
+		{ }
+	}
+
 	void GUIManager::updateMeshes()
 	void GUIManager::updateMeshes()
 	{
 	{
 		for(auto& cachedMeshData : mCachedGUIData)
 		for(auto& cachedMeshData : mCachedGUIData)
@@ -1539,7 +1545,7 @@ namespace bs
 		mForcedFocusElements.push_back(efi);
 		mForcedFocusElements.push_back(efi);
 	}
 	}
 
 
-	bool GUIManager::processDestroyQueue()
+	bool GUIManager::processDestroyQueueIteration()
 	{
 	{
 		Stack<GUIElement*> toDestroy = mScheduledForDestruction;
 		Stack<GUIElement*> toDestroy = mScheduledForDestruction;
 		mScheduledForDestruction = Stack<GUIElement*>();
 		mScheduledForDestruction = Stack<GUIElement*>();

+ 5 - 2
Source/BansheeEngine/GUI/BsGUIManager.h

@@ -156,6 +156,9 @@ namespace bs
 		/** Queues the GUI element for destruction. Element will be destroyed during the next call to update(). */
 		/** Queues the GUI element for destruction. Element will be destroyed during the next call to update(). */
 		void queueForDestroy(GUIElement* element);
 		void queueForDestroy(GUIElement* element);
 
 
+		/** Forces all GUI elements that are queued for destruction to be destroyed immediately. */
+		void processDestroyQueue();
+
 		/**	Change the GUI element focus state. */
 		/**	Change the GUI element focus state. */
 		void setFocus(GUIElement* element, bool focus);
 		void setFocus(GUIElement* element, bool focus);
 
 
@@ -245,9 +248,9 @@ namespace bs
 		 *
 		 *
 		 * @note	
 		 * @note	
 		 * Returns true if more elements have been added for destruction (will happen when destruction of one element
 		 * Returns true if more elements have been added for destruction (will happen when destruction of one element
-		 * queues up destruction of another).
+		 * queues up destruction of another). Usually needs to be run in a loop with multiple iterations.
 		 */
 		 */
-		bool processDestroyQueue();
+		bool processDestroyQueueIteration();
 
 
 		/**
 		/**
 		 * Finds a GUI element under the pointer at the specified screen position. This method will also trigger pointer
 		 * Finds a GUI element under the pointer at the specified screen position. This method will also trigger pointer

+ 6 - 2
Source/BansheeUtility/Reflection/BsIReflectable.cpp

@@ -22,10 +22,14 @@ namespace bs
 	{
 	{
 		RTTITypeBase* type = _getRTTIfromTypeId(rttiTypeId);
 		RTTITypeBase* type = _getRTTIfromTypeId(rttiTypeId);
 
 
+		SPtr<IReflectable> output;
 		if(type != nullptr)
 		if(type != nullptr)
-			return type->newRTTIObject();
+		{
+			output = type->newRTTIObject();
+			output->mRTTIData = nullptr;
+		}
 		
 		
-		return nullptr;
+		return output;
 	}
 	}
 
 
 	RTTITypeBase* IReflectable::_getRTTIfromTypeId(UINT32 rttiTypeId)
 	RTTITypeBase* IReflectable::_getRTTIfromTypeId(UINT32 rttiTypeId)

+ 5 - 1
Source/SBansheeEngine/BsEngineScriptLibrary.cpp

@@ -18,6 +18,7 @@
 #include "Wrappers/GUI/BsScriptGUI.h"
 #include "Wrappers/GUI/BsScriptGUI.h"
 #include "BsPlayInEditorManager.h"
 #include "BsPlayInEditorManager.h"
 #include "Wrappers/BsScriptScene.h"
 #include "Wrappers/BsScriptScene.h"
+#include "GUI/BsGUIManager.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -117,5 +118,8 @@ namespace bs
 		GameResourceManager::shutDown();
 		GameResourceManager::shutDown();
 		ScriptDebug::shutDown();
 		ScriptDebug::shutDown();
 		PlayInEditorManager::shutDown();
 		PlayInEditorManager::shutDown();
+
+		// Make sure all GUI elements are actually destroyed
+		GUIManager::instance().processDestroyQueue();
 	}
 	}
-}
+}