Browse Source

Handle abort signal instead of exit
Properly clean up editor widgets upon close
Properly clean up editor windows upon close
Fix for renderer where renderable has null mesh or material
Thread pool properly cleans up worker method once done so it doesn't keep holding bound parameters
Fix for nullref exception when destroying managed GUIArea

Marko Pintera 11 years ago
parent
commit
e4d4e884c9

+ 5 - 3
BansheeCore/Source/BsCoreApplication.cpp

@@ -46,18 +46,20 @@
 
 #include "BsRendererManager.h"
 
+#include <csignal>
+
 namespace BansheeEngine
 {
-	void atExit()
+	void handleAbort(int error)
 	{
-		BS_EXCEPT(InternalErrorException, "exit() called. Please shut down Banshee normally and do not use exit().");
+		BS_EXCEPT(InternalErrorException, "abort() called.");
 	}
 
 	CoreApplication::CoreApplication(START_UP_DESC& desc)
 		:mPrimaryWindow(nullptr), mIsFrameRenderingFinished(true), mRunMainLoop(false), 
 		mSceneManagerPlugin(nullptr), mRendererPlugin(nullptr)
 	{
-		atexit(atExit);
+		signal(SIGABRT, handleAbort);
 
 		UINT32 numWorkerThreads = BS_THREAD_HARDWARE_CONCURRENCY - 1; // Number of cores while excluding current thread.
 

+ 1 - 0
BansheeEditor/Include/BsEditorWidgetManager.h

@@ -15,6 +15,7 @@ namespace BansheeEngine
 	{
 	public:
 		EditorWidgetManager();
+		~EditorWidgetManager();
 
 		/**
 		 * @brief	Registers a widget that can then be opened by calling "open". When loading

+ 8 - 0
BansheeEditor/Source/BsEditorWidgetManager.cpp

@@ -23,6 +23,14 @@ namespace BansheeEngine
 		}
 	}
 
+	EditorWidgetManager::~EditorWidgetManager()
+	{
+		Map<String, EditorWidgetBase*> widgetsCopy = mActiveWidgets;
+
+		for (auto& widget : widgetsCopy)
+			widget.second->close();
+	}
+
 	void EditorWidgetManager::registerWidget(const String& name, std::function<EditorWidgetBase*(EditorWidgetContainer&)> createCallback)
 	{
 		auto iterFind = mCreateCallbacks.find(name);

+ 5 - 0
BansheeEditor/Source/BsEditorWindowManager.cpp

@@ -15,6 +15,11 @@ namespace BansheeEngine
 		while(mEditorWindows.size() > 0)
 			destroy(mEditorWindows[0]);
 
+		for (auto& windowToDestroy : mScheduledForDestruction)
+			bs_delete(windowToDestroy);
+
+		mScheduledForDestruction.clear();
+
 		if(mMainWindow != nullptr)
 			bs_delete(mMainWindow);
 	}

+ 3 - 2
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -225,7 +225,8 @@ namespace BansheeEngine
 				proxy = renderable->_createProxy();
 				renderable->_setActiveProxy(proxy);
 
-				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addRenderableProxy, this, proxy));
+				if (proxy != nullptr)
+					gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addRenderableProxy, this, proxy));
 
 				dirtyRenderables.push_back(renderable);
 				dirtySceneObjects.push_back(renderable->SO());
@@ -240,7 +241,7 @@ namespace BansheeEngine
 				dirtySceneObjects.push_back(renderable->SO());
 			}
 
-			if (!addedNewProxy)
+			if (!addedNewProxy && proxy != nullptr)
 			{
 				for (UINT32 i = 0; i < (UINT32)proxy->renderableElements.size(); i++)
 				{

+ 1 - 0
BansheeUtility/Source/BsThreadPool.cpp

@@ -111,6 +111,7 @@ namespace BansheeEngine
 				mIdle = true;
 				mIdleTime = std::time(nullptr);
 				mThreadReady = false;
+				mWorkerMethod = nullptr; // Make sure to clear as it could have bound shared pointers and similar
 
 				BS_THREAD_NOTIFY_ONE(mWorkerEndedCond);
 			}

+ 2 - 1
MBansheeEngine/GUI/GUIArea.cs

@@ -24,7 +24,8 @@ namespace BansheeEngine
 
             this.parent = parent;
 
-            parent.childAreas.Add(this);
+            if(parent != null)
+                parent.childAreas.Add(this);
         }
 
         internal static GUIArea Create(GUIPanel parent, int x, int y, int width, int height, short depth)