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

Fixing managed GUIWidgets (WIP)

BearishSun 10 лет назад
Родитель
Сommit
e9f6e3fac3

+ 5 - 0
BansheeEngine.sln

@@ -183,6 +183,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeD3D9RenderAPI", "Ban
 		{CC7F9445-71C9-4559-9976-FF0A64DCB582} = {CC7F9445-71C9-4559-9976-FF0A64DCB582}
 	EndProjectSection
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9CE570FB-D0C7-4B8A-80B6-51E890B28589}"
+	ProjectSection(SolutionItems) = preProject
+		Scripts\VSVisualizations.natvis = Scripts\VSVisualizations.natvis
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU

+ 13 - 4
BansheeEngine/Source/BsGUIWidget.cpp

@@ -13,13 +13,15 @@
 namespace BansheeEngine
 {
 	GUIWidget::GUIWidget(const CameraPtr& camera)
-		:mWidgetIsDirty(false), mCamera(camera), mDepth(0), mPanel(nullptr), mIsActive(true)
+		:mWidgetIsDirty(false), mCamera(camera), mDepth(0), mPanel(nullptr), mIsActive(true), 
+		mTransform(Matrix4::IDENTITY)
 	{
 		construct(camera);
 	}
 
 	GUIWidget::GUIWidget(const HCamera& camera)
-		:mWidgetIsDirty(false), mCamera(camera->_getCamera()), mDepth(0), mPanel(nullptr), mIsActive(true)
+		:mWidgetIsDirty(false), mCamera(camera->_getCamera()), mDepth(0), mPanel(nullptr), 
+		mIsActive(true), mTransform(Matrix4::IDENTITY)
 	{
 		construct(mCamera);
 	}
@@ -278,14 +280,21 @@ namespace BansheeEngine
 
 	void GUIWidget::setCamera(const CameraPtr& camera)
 	{
-		if (mCamera == camera)
+		CameraPtr newCamera = camera;
+		if(newCamera != nullptr)
+		{
+			if (newCamera->getViewport()->getTarget() == nullptr)
+				newCamera = nullptr;
+		}
+
+		if (mCamera == newCamera)
 			return;
 
 		GUIManager::instance().unregisterWidget(this);
 
 		mOwnerTargetResizedConn.disconnect();
 
-		mCamera = camera;
+		mCamera = newCamera;
 
 		Viewport* viewport = getTarget();
 		if (viewport != nullptr && viewport->getTarget() != nullptr)

+ 12 - 4
MBansheeEngine/GUI/GUI.cs

@@ -11,6 +11,7 @@ namespace BansheeEngine
     public static class GUI
     {
         private static GUISkin skin;
+        private static GUIPanel panel; // Populated by runtime
 
         /// <summary>
         /// Skin used for rendering all the GUI elements.
@@ -35,13 +36,20 @@ namespace BansheeEngine
         /// </summary>
         public static GUIPanel Panel
         {
-            get { return Internal_GetPanel(); }
+            get { return panel; }
         }
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_SetSkin(IntPtr skin);
+        /// <summary>
+        /// Used by the runtime to set the primary panel.
+        /// </summary>
+        /// <param name="panel">Primary panel of the widget.</param>
+        private static void SetPanel(GUIPanel panel)
+        {
+            // We can't set this directly through the field because there is an issue with Mono and static fields
+            GUI.panel = panel;
+        }
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern GUIPanel Internal_GetPanel();
+        private static extern void Internal_SetSkin(IntPtr skin);
     }
 }

+ 3 - 4
MBansheeEngine/NativeGUIWidget.cs

@@ -9,6 +9,8 @@ namespace BansheeEngine
     /// </summary>
     internal class NativeGUIWidget : ScriptObject
     {
+        private GUIPanel panel; // Populated by runtime
+
         /// <summary>
         /// Skin used for rendering all the GUI elements belonging to this widget.
         /// </summary>
@@ -45,7 +47,7 @@ namespace BansheeEngine
         /// </summary>
         internal GUIPanel Panel
         {
-            get { return Internal_GetPanel(mCachedPtr); }
+            get { return panel; }
         }
 
         /// <summary>
@@ -103,9 +105,6 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetCamera(IntPtr instance, IntPtr camera);
 
-        [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern GUIPanel Internal_GetPanel(IntPtr instance);
-
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_Destroy(IntPtr instance);
     }

+ 3 - 1
SBansheeEngine/Include/BsScriptGUI.h

@@ -26,11 +26,13 @@ namespace BansheeEngine
 
 		static SPtr<GUIWidget> sGUIWidget;
 		static ScriptGUILayout* sPanel;
+		static MonoMethod* sGUIPanelMethod;
+		static HEvent sDomainUnloadConn;
+		static HEvent sDomainLoadConn;
 
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
 		static void internal_SetSkin(ScriptGUISkin* skin);
-		static MonoObject* internal_GetPanel();
 	};
 }

+ 2 - 1
SBansheeEngine/Include/BsScriptGUIWidget.h

@@ -28,6 +28,8 @@ namespace BansheeEngine
 		ScriptGUILayout* mPanel;
 		UINT32 mLastUpdateHash;
 
+		static MonoField* sGUIPanelField;
+
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
@@ -36,7 +38,6 @@ namespace BansheeEngine
 		static void internal_UpdateMainCamera(ScriptGUIWidget* instance, ScriptCamera* camera);
 		static void internal_SetSkin(ScriptGUIWidget* instance, ScriptGUISkin* skin);
 		static void internal_SetCamera(ScriptGUIWidget* instance, ScriptCamera* camera);
-		static MonoObject* internal_GetPanel(ScriptGUIWidget* instance);
 		static void internal_Destroy(ScriptGUIWidget* instance);
 	};
 }

+ 37 - 11
SBansheeEngine/Source/BsScriptGUI.cpp

@@ -3,11 +3,17 @@
 #include "BsScriptGUILayout.h"
 #include "BsGUIWidget.h"
 #include "BsSceneManager.h"
+#include "BsScriptObjectManager.h"
+#include "BsBuiltinResources.h"
+#include "BsMonoMethod.h"
 
 namespace BansheeEngine
 {
 	SPtr<GUIWidget> ScriptGUI::sGUIWidget;
 	ScriptGUILayout* ScriptGUI::sPanel = nullptr;
+	HEvent ScriptGUI::sDomainUnloadConn;
+	HEvent ScriptGUI::sDomainLoadConn;
+	MonoMethod* ScriptGUI::sGUIPanelMethod = nullptr;
 
 	ScriptGUI::ScriptGUI(MonoObject* managedInstance)
 		:ScriptObject(managedInstance)
@@ -20,9 +26,30 @@ namespace BansheeEngine
 	{
 		CameraPtr mainCamera = gSceneManager().getMainCamera().camera;
 		sGUIWidget = GUIWidget::create(mainCamera);
+		sGUIWidget->setSkin(BuiltinResources::instance().getGUISkin());
 
-		MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(sGUIWidget->getPanel());
-		sPanel = ScriptGUILayout::toNative(guiPanel);
+		auto createPanel = [] ()
+		{
+			assert(sPanel == nullptr);
+
+			MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(sGUIWidget->getPanel());
+			sPanel = ScriptGUILayout::toNative(guiPanel);
+
+			void* params[1];
+			params[0] = guiPanel;
+
+			sGUIPanelMethod->invoke(nullptr, params);
+		};
+
+		auto clearPanel = [] ()
+		{
+			sPanel = nullptr;
+		};
+
+		createPanel();
+
+		sDomainLoadConn = ScriptObjectManager::instance().onRefreshDomainLoaded.connect(createPanel);
+		sDomainUnloadConn = MonoManager::instance().onDomainUnload.connect(clearPanel);
 	}
 
 	void ScriptGUI::update()
@@ -37,6 +64,9 @@ namespace BansheeEngine
 
 	void ScriptGUI::shutDown()
 	{
+		sDomainLoadConn.disconnect();
+		sDomainUnloadConn.disconnect();
+
 		if (sPanel != nullptr)
 		{
 			sPanel->destroy();
@@ -52,8 +82,9 @@ namespace BansheeEngine
 
 	void ScriptGUI::initRuntimeData()
 	{
+		sGUIPanelMethod = metaData.scriptClass->getMethod("SetPanel", 1);
+
 		metaData.scriptClass->addInternalCall("Internal_SetSkin", &ScriptGUI::internal_SetSkin);
-		metaData.scriptClass->addInternalCall("Internal_GetPanel", &ScriptGUI::internal_GetPanel);
 	}
 
 	void ScriptGUI::internal_SetSkin(ScriptGUISkin* skin)
@@ -62,15 +93,10 @@ namespace BansheeEngine
 		if (skin != nullptr)
 			guiSkin = skin->getHandle();
 
+		if (!guiSkin.isLoaded())
+			guiSkin = BuiltinResources::instance().getGUISkin();
+
 		if(sGUIWidget != nullptr)
 			sGUIWidget->setSkin(guiSkin);
 	}
-
-	MonoObject* ScriptGUI::internal_GetPanel()
-	{
-		if (sPanel != nullptr)
-			return sPanel->getManagedInstance();
-
-		return nullptr;
-	}
 }

+ 1 - 3
SBansheeEngine/Source/BsScriptGUILayout.cpp

@@ -14,9 +14,7 @@ namespace BansheeEngine
 {
 	ScriptGUILayout::ScriptGUILayout(MonoObject* instance, GUILayout* layout, bool ownsNative)
 		:TScriptGUIElementBase(instance, layout), mLayout(layout), mIsDestroyed(false), mOwnsNative(ownsNative)
-	{
-
-	}
+	{ }
 
 	void ScriptGUILayout::initRuntimeData()
 	{

+ 11 - 9
SBansheeEngine/Source/BsScriptGUIWidget.cpp

@@ -6,18 +6,24 @@
 #include "BsGUIWidget.h"
 #include "BsSceneObject.h"
 #include "BsSceneManager.h"
+#include "BsBuiltinResources.h"
 
 namespace BansheeEngine
 {
+	MonoField* ScriptGUIWidget::sGUIPanelField = nullptr;
+
 	ScriptGUIWidget::ScriptGUIWidget(MonoObject* managedInstance)
 		:ScriptObject(managedInstance), mGUIWidget(nullptr), mLastUpdateHash((UINT32)-1)
 	{
 		CameraPtr mainCamera = gSceneManager().getMainCamera().camera;
 
 		mGUIWidget = GUIWidget::create(mainCamera);
+		mGUIWidget->setSkin(BuiltinResources::instance().getGUISkin());
 
 		MonoObject* guiPanel = ScriptGUIPanel::createFromExisting(mGUIWidget->getPanel());
 		mPanel = ScriptGUILayout::toNative(guiPanel);
+
+		sGUIPanelField->setValue(nullptr, guiPanel);
 	}
 
 	ScriptGUIWidget::~ScriptGUIWidget()
@@ -25,12 +31,13 @@ namespace BansheeEngine
 
 	void ScriptGUIWidget::initRuntimeData()
 	{
+		sGUIPanelField = metaData.scriptClass->getField("panel");
+
 		metaData.scriptClass->addInternalCall("Internal_Create", &ScriptGUIWidget::internal_Create);
 		metaData.scriptClass->addInternalCall("Internal_UpdateTransform", &ScriptGUIWidget::internal_UpdateTransform);
 		metaData.scriptClass->addInternalCall("Internal_UpdateMainCamera", &ScriptGUIWidget::internal_UpdateMainCamera);
 		metaData.scriptClass->addInternalCall("Internal_SetSkin", &ScriptGUIWidget::internal_SetSkin);
 		metaData.scriptClass->addInternalCall("Internal_SetCamera", &ScriptGUIWidget::internal_SetCamera);
-		metaData.scriptClass->addInternalCall("Internal_GetPanel", &ScriptGUIWidget::internal_GetPanel);
 		metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptGUIWidget::internal_Destroy);
 	}
 
@@ -73,6 +80,9 @@ namespace BansheeEngine
 		if (skin != nullptr)
 			guiSkin = skin->getHandle();
 
+		if (!guiSkin.isLoaded())
+			guiSkin = BuiltinResources::instance().getGUISkin();
+
 		SPtr<GUIWidget> widget = instance->getInternal();
 		if (widget != nullptr)
 			widget->setSkin(guiSkin);
@@ -92,14 +102,6 @@ namespace BansheeEngine
 			widget->setCamera(nativeCamera);
 	}
 
-	MonoObject* ScriptGUIWidget::internal_GetPanel(ScriptGUIWidget* instance)
-	{
-		if (instance->mPanel != nullptr)
-			return instance->mPanel->getManagedInstance();
-
-		return nullptr;
-	}
-
 	void ScriptGUIWidget::internal_Destroy(ScriptGUIWidget* instance)
 	{
 		instance->destroy();

+ 20 - 0
Scripts/VSVisualizations.natvis

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+  <Type Name="BansheeEngine::GameObjectHandle&lt;*&gt;">
+	<DisplayString Condition="mData._Ptr->mPtr._Ptr == 0 || mData._Ptr->mPtr._Ptr->object._Ptr == 0">Empty</DisplayString>
+    <DisplayString>Name = {mData._Ptr->mPtr._Ptr->object._Ptr->mName}, InstanceId = {mData._Ptr->mPtr._Ptr->mInstanceId}</DisplayString>
+	<Expand>	
+		<ExpandedItem Condition="mData._Ptr->mPtr._Ptr != 0 &amp;&amp; mData._Ptr->mPtr._Ptr->object._Ptr != 0">($T1*)mData._Ptr->mPtr._Ptr->object._Ptr</ExpandedItem>
+	</Expand>
+  </Type>
+  
+  <Type Name="BansheeEngine::ResourceHandle&lt;*&gt;">
+	<DisplayString Condition="mData._Ptr == 0 || mData._Ptr->mPtr._Ptr == 0">Empty</DisplayString>
+    <DisplayString>Name = {mData._Ptr->mPtr._Ptr->mMetaData._Ptr->displayName}, UUID = {mData._Ptr->mUUID}</DisplayString>
+	<Expand>	
+		<ExpandedItem Condition="mData._Ptr != 0 &amp;&amp; mData._Ptr->mPtr._Ptr != 0">($T1*)mData._Ptr->mPtr._Ptr</ExpandedItem>
+	</Expand>
+  </Type> 
+
+</AutoVisualizer>