Просмотр исходного кода

Added a callback to DbgWidget::close so that the owner container knows when the widget is removed

Marko Pintera 12 лет назад
Родитель
Сommit
82f56090d3

+ 2 - 0
CamelotClient/Include/BsEditorWidget.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "BsEditorPrerequisites.h"
+#include "boost/signal.hpp"
 
 namespace BansheeEditor
 {
@@ -20,6 +21,7 @@ namespace BansheeEditor
 
 		static void destroy(EditorWidget* widget);
 
+		boost::signal<void(EditorWidget*)> onClosed;
 	protected:
 		EditorWidget(const CM::WString& name);
 

+ 12 - 1
CamelotClient/Include/BsEditorWidgetContainer.h

@@ -7,6 +7,16 @@ namespace BansheeEditor
 {
 	class EditorWidgetContainer
 	{
+		struct WidgetInfo
+		{
+			WidgetInfo(EditorWidget* _widget, const boost::signals::connection& _conn)
+				:widget(_widget), conn(_conn)
+			{ }
+
+			EditorWidget* widget;
+			boost::signals::connection conn;
+		};
+
 	public:
 		EditorWidgetContainer(BS::GUIWidget* parent);
 		virtual ~EditorWidgetContainer();
@@ -26,7 +36,7 @@ namespace BansheeEditor
 		BS::GUIWidget* mParent;
 		CM::INT32 mX, mY;
 		CM::UINT32 mWidth, mHeight;
-		CM::Vector<EditorWidget*>::type mWidgets;
+		CM::Vector<WidgetInfo>::type mWidgets;
 		CM::INT32 mActiveWidget;
 
 		static const CM::UINT32 TitleBarHeight;
@@ -34,5 +44,6 @@ namespace BansheeEditor
 		void setActiveWidget(CM::UINT32 idx);
 		void tabActivated(CM::UINT32 idx);
 		void tabClosed(CM::UINT32 idx);
+		void widgetDestroyed(EditorWidget* widget);
 	};
 }

+ 31 - 11
CamelotClient/Source/BsEditorWidgetContainer.cpp

@@ -23,19 +23,22 @@ namespace BansheeEditor
 
 		for(auto& widget : mWidgets)
 		{
-			EditorWidget::destroy(widget);
+			EditorWidget::destroy(widget.widget);
 		}
 	}
 
 	void EditorWidgetContainer::add(EditorWidget& widget)
 	{
-		auto iterFind = std::find(begin(mWidgets), end(mWidgets), &widget);
+		for(auto& curWidget : mWidgets)
+		{
+			if(curWidget.widget == &widget)
+				return;
+		}
 
-		if(iterFind != end(mWidgets))
-			return;
+		auto conn = widget.onClosed.connect(boost::bind(&EditorWidgetContainer::widgetDestroyed, this, _1));
 
 		mTitleBar->addTab(widget.getName());
-		mWidgets.push_back(&widget);
+		mWidgets.push_back(WidgetInfo(&widget, conn));
 		widget._changeParent(*mParent);
 
 		if(mActiveWidget == -1)
@@ -52,7 +55,7 @@ namespace BansheeEditor
 		UINT32 curIdx = 0;
 		for(auto& curWidget : mWidgets)
 		{
-			if(curWidget == &widget)
+			if(curWidget.widget == &widget)
 			{
 				widgetIdx = curIdx;
 				break;
@@ -64,6 +67,7 @@ namespace BansheeEditor
 		if(widgetIdx == -1)
 			return;
 
+		mWidgets[widgetIdx].conn.disconnect();
 		mWidgets.erase(mWidgets.begin() + widgetIdx);
 		mTitleBar->removeTab((UINT32)widgetIdx);
 
@@ -88,7 +92,7 @@ namespace BansheeEditor
 
 		if(mActiveWidget >= 0)
 		{
-			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget];
+			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget].widget;
 			UINT32 contentHeight = (UINT32)std::max(0, (INT32)height - (INT32)TitleBarHeight);
 
 			activeWidgetPtr->_setSize(width, contentHeight);
@@ -104,7 +108,7 @@ namespace BansheeEditor
 
 		if(mActiveWidget >= 0)
 		{
-			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget];
+			EditorWidget* activeWidgetPtr = mWidgets[mActiveWidget].widget;
 
 			activeWidgetPtr->_setPosition(x, y + TitleBarHeight);
 		}
@@ -124,9 +128,9 @@ namespace BansheeEditor
 		for(auto& curWidget : mWidgets)
 		{
 			if(curIdx != (UINT32)mActiveWidget)
-				curWidget->_disable();
+				curWidget.widget->_disable();
 			else
-				curWidget->_enable();
+				curWidget.widget->_enable();
 
 			curIdx++;
 		}
@@ -142,11 +146,27 @@ namespace BansheeEditor
 
 	void EditorWidgetContainer::tabClosed(UINT32 idx)
 	{
-		EditorWidget* widget = mWidgets[idx];
+		EditorWidget* widget = mWidgets[idx].widget;
 		remove(*widget);
 		EditorWidget::destroy(widget);
 
 		if(!onWidgetClosed.empty())
 			onWidgetClosed();
 	}
+
+	void EditorWidgetContainer::widgetDestroyed(EditorWidget* widget)
+	{
+		for(auto& curWidget : mWidgets)
+		{
+			if(curWidget.widget == widget)
+			{
+				remove(*widget);
+
+				if(!onWidgetClosed.empty())
+					onWidgetClosed();
+
+				return;
+			}
+		}		
+	}
 }

+ 8 - 4
CamelotClient/Source/DbgEditorWidget1.cpp

@@ -106,10 +106,14 @@ namespace BansheeEditor
 
 	void DbgEditorWidget1::close()
 	{
-		// TODO - Unregister widget from EditorWidgetContainer
-		// TODO - Unregister widget from DockManager
-		// TODO - Release widget resources
+		if(Instance != nullptr)
+		{
+			if(!Instance->onClosed.empty()) // TODO - This is very hackish
+				Instance->onClosed(Instance);
+
+			EditorWidget::destroy(Instance);
+		}
 		
-		Instance = nullptr; // TODO - What happens when something ends up keeping the reference to the widget?
+		Instance = nullptr; 
 	}
 }

+ 0 - 1
EditorWindowDock.txt

@@ -57,7 +57,6 @@ Implementation plan:
  - Continue with DockManager (flesh it out later)
 
  GUIManager holds a ptr to GUIElements, and when elements are destroyed, GUIManager holds an invalid ptr
-Shutdown of the game should destroy all EditorWindows (and all their children)
 Tabs need toggle groups
 Hook up DbgEditorWidget1::close()
 Test tab switch/tab close/window close