Browse Source

Debug log events can no longer be triggered from arbitrary threads, which was messing with GUIStatusBar that was subscribing to them
Exceptions on non-main threads now get properly reported

BearishSun 10 years ago
parent
commit
2932956d12

+ 1 - 0
BansheeCore/Source/BsCoreApplication.cpp

@@ -177,6 +177,7 @@ namespace BansheeEngine
 			// checking if a window is in focus, so it has to be up to date)
 			RenderWindowManager::instance()._update(); 
 			gInput()._triggerCallbacks();
+			gDebug()._triggerCallbacks();
 
 			preUpdate();
 

+ 0 - 2
BansheeEditor/Source/BsEditorApplication.cpp

@@ -148,8 +148,6 @@ namespace BansheeEngine
 		MainEditorWindow* mainWindow = MainEditorWindow::create(getPrimaryWindow());
 		ScriptManager::instance().initialize();
 
-		BS_EXCEPT(InternalErrorException, "Forced crash");
-		
 #if BS_DEBUG
 		/************************************************************************/
 		/* 								DEBUG CODE                      		*/

+ 1 - 1
BansheeEditor/Source/BsGUIStatusBar.cpp

@@ -42,7 +42,7 @@ namespace BansheeEngine
 
 		mBgPanel->addElement(mBackground);
 
-		mLogEntryAddedConn = gDebug().getLog().onEntryAdded.connect(std::bind(&GUIStatusBar::logEntryAdded, this, _1));
+		mLogEntryAddedConn = gDebug().onLogEntryAdded.connect(std::bind(&GUIStatusBar::logEntryAdded, this, _1));
 		mMessageBtnPressedConn = mMessage->onClick.connect(std::bind(&GUIStatusBar::messageBtnClicked, this));
 	}
 

+ 14 - 0
BansheeUtility/Include/BsDebug.h

@@ -57,6 +57,20 @@ namespace BansheeEngine
 		 * @param	path	Absolute path to the log filename.
 		 */
 		void saveLog(const Path& path);
+
+		/**
+		 * @brief	Triggers callbacks that notify external code that a log entry was added.
+		 * 			
+		 * @note	Internal method. Sim thread only.
+		 */
+		void _triggerCallbacks();
+
+		/**
+		 * @brief	Triggered when a new entry in the log is added.
+		 * 			
+		 * @note	Sim thread only.
+		 */
+		Event<void(const LogEntry&)> onLogEntryAdded;
 	private:
 		Log mLog;
 	};

+ 12 - 16
BansheeUtility/Include/BsLog.h

@@ -12,6 +12,7 @@ namespace BansheeEngine
 	class BS_UTILITY_EXPORT LogEntry
 	{
 	public:
+		LogEntry() { }
 		LogEntry(const String& msg, UINT32 channel);
 
 		UINT32 getChannel() const { return mChannel; }
@@ -47,26 +48,21 @@ namespace BansheeEngine
 		 */
 		void clear();
 
+		/**
+		 * @brief	Returns the latest unread entry from the log queue, and removes the entry from the unread entries
+		 * 			list.
+		 * 			
+		 * @param	entry	Entry that was read, or undefined if no entries exist.
+		 * 					
+		 * @returns	True if an unread entry was retrieved, false otherwise.
+		 */
+		bool getUnreadEntry(LogEntry& entry);
+
 	private:
 		friend class Debug;
 
 		Vector<LogEntry*> mEntries;
+		Queue<LogEntry*> mUnreadEntries;
 		BS_RECURSIVE_MUTEX(mMutex);
-
-		/**
-		 * @brief	Called whenever a new entry is added.
-		 */
-		void doOnEntryAdded(const LogEntry& entry);
-
-		/************************************************************************/
-		/* 								SIGNALS		                     		*/
-		/************************************************************************/
-	public:
-		/**
-		 * @brief	Triggered when a new entry in the log is added.
-		 * 			
-		 * @note	
-		 */
-		Event<void(const LogEntry&)> onEntryAdded;
 	};
 }

+ 9 - 0
BansheeUtility/Source/BsDebug.cpp

@@ -73,6 +73,15 @@ namespace BansheeEngine
 		bs_deleteN(bmpBuffer, bmpDataSize);
 	}
 
+	void Debug::_triggerCallbacks()
+	{
+		LogEntry entry;
+		while (mLog.getUnreadEntry(entry))
+		{
+			onLogEntryAdded(entry);
+		}
+	}
+
 	void Debug::saveLog(const Path& path)
 	{
 		static const char* style =

+ 14 - 4
BansheeUtility/Source/BsLog.cpp

@@ -25,8 +25,7 @@ namespace BansheeEngine
 
 		LogEntry* newEntry = bs_new<LogEntry>(message, channel);
 		mEntries.push_back(newEntry);
-
-		doOnEntryAdded(*newEntry);
+		mUnreadEntries.push(newEntry);
 	}
 
 	void Log::clear()
@@ -37,10 +36,21 @@ namespace BansheeEngine
 			bs_delete(*iter);
 
 		mEntries.clear();
+
+		while (!mUnreadEntries.empty())
+			mUnreadEntries.pop();
 	}
 
-	void Log::doOnEntryAdded(const LogEntry& entry)
+	bool Log::getUnreadEntry(LogEntry& entry)
 	{
-		onEntryAdded(entry);
+		BS_LOCK_RECURSIVE_MUTEX(mMutex);
+
+		if (mUnreadEntries.empty())
+			return false;
+
+		entry = *mUnreadEntries.front();
+		mUnreadEntries.pop();
+
+		return true;
 	}
 }

+ 23 - 0
BansheeUtility/Source/BsThreadPool.cpp

@@ -1,5 +1,16 @@
 #include "BsThreadPool.h"
 
+#if BS_PLATFORM == BS_PLATFORM_WIN32
+#include "windows.h"
+
+#if BS_COMPILER == BS_COMPILER_MSVC
+// disable: nonstandard extension used: 'X' uses SEH and 'Y' has destructor
+// We don't care about this as any exception is meant to crash the program.
+#pragma warning(disable: 4509)
+#endif // BS_COMPILER == BS_COMPILER_MSVC
+
+#endif // BS_PLATFORM == BS_PLATFORM_WIN32
+
 namespace BansheeEngine
 {
 	HThread::HThread()
@@ -105,7 +116,19 @@ namespace BansheeEngine
 				}
 			}
 
+#if BS_PLATFORM == BS_PLATFORM_WIN32
+			__try
+			{
+				worker();
+			}
+			__except (gCrashHandler().reportCrash(GetExceptionInformation()))
+			{
+				PlatformUtility::terminate(true);
+			}
+#else
 			worker();
+			LOGWRN("Starting a thread with no error handling.");
+#endif
 
 			{
 				BS_LOCK_MUTEX(mMutex);

+ 5 - 5
BansheeUtility/Source/Win32/BsWin32CrashHandler.cpp

@@ -531,11 +531,11 @@ namespace BansheeEngine
 		GetLocalTime(&systemTime);
 
 		WString timeStamp = L"{0}{1}{2}_{3}{4}";
-		WString strYear = toWString(systemTime.wYear, 4);
-		WString strMonth = toWString(systemTime.wMonth, 2);
-		WString strDay = toWString(systemTime.wDay, 2);
-		WString strHour = toWString(systemTime.wHour, 2);
-		WString strMinute = toWString(systemTime.wMinute, 2);
+		WString strYear = toWString(systemTime.wYear, 4, '0');
+		WString strMonth = toWString(systemTime.wMonth, 2, '0');
+		WString strDay = toWString(systemTime.wDay, 2, '0');
+		WString strHour = toWString(systemTime.wHour, 2, '0');
+		WString strMinute = toWString(systemTime.wMinute, 2, '0');
 
 		timeStamp = StringUtil::format(timeStamp, strYear, strMonth, strDay, strHour, strMinute);