Browse Source

Scene name and UUID are no longer lost after assembly refresh

BearishSun 10 years ago
parent
commit
952c2e7ca0
2 changed files with 166 additions and 103 deletions
  1. 45 26
      SBansheeEngine/Include/BsScriptScene.h
  2. 121 77
      SBansheeEngine/Source/BsScriptScene.cpp

+ 45 - 26
SBansheeEngine/Include/BsScriptScene.h

@@ -1,27 +1,46 @@
-#pragma once
-
-#include "BsScriptEnginePrerequisites.h"
-#include "BsScriptObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Interop class between C++ & CLR for SceneManager.
-	 */
-	class BS_SCR_BE_EXPORT ScriptScene : public ScriptObject<ScriptScene>
-	{
-	public:
-		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Scene")
-
-	private:
-		ScriptScene(MonoObject* instance);
-
-		/************************************************************************/
-		/* 								CLR HOOKS						   		*/
-		/************************************************************************/
-		static MonoObject* internal_LoadScene(MonoString* path);
-		static MonoObject* internal_GetRoot();
-		static void internal_ClearScene();
-		static MonoObject* internal_GetMainCameraSO();
-	};
+#pragma once
+
+#include "BsScriptEnginePrerequisites.h"
+#include "BsScriptObject.h"
+
+namespace BansheeEngine
+{
+	/** Interop class between C++ & CLR for SceneManager. */
+	class BS_SCR_BE_EXPORT ScriptScene : public ScriptObject<ScriptScene>
+	{
+	public:
+		SCRIPT_OBJ(ENGINE_ASSEMBLY, "BansheeEngine", "Scene")
+
+		/** Registers internal callbacks. Must be called on scripting system load. */
+		static void startUp();
+
+		/** Unregisters internal callbacks. Must be called on scripting system shutdown. */
+		static void shutDown();
+
+	private:
+		ScriptScene(MonoObject* instance);
+
+		/** Triggered when the assembly refresh starts. */
+		static void onRefreshStarted();
+
+		/** Triggered when assembly domain is loaded during assembly refresh. */
+		static void onRefreshDomainLoaded();
+
+		static const char* ActiveSceneNameFieldName;
+		static const char* ActiveSceneUUIDFieldName;
+
+		static HEvent OnRefreshDomainLoadedConn;
+		static HEvent OnRefreshStartedConn;
+
+		static String ActiveSceneUUID;
+		static WString ActiveSceneName;
+
+		/************************************************************************/
+		/* 								CLR HOOKS						   		*/
+		/************************************************************************/
+		static MonoObject* internal_LoadScene(MonoString* path);
+		static MonoObject* internal_GetRoot();
+		static void internal_ClearScene();
+		static MonoObject* internal_GetMainCameraSO();
+	};
 }

+ 121 - 77
SBansheeEngine/Source/BsScriptScene.cpp

@@ -1,78 +1,122 @@
-#include "BsScriptScene.h"
-#include "BsMonoManager.h"
-#include "BsMonoClass.h"
-#include "BsMonoMethod.h"
-#include "BsMonoUtil.h"
-#include "BsSceneManager.h"
-#include "BsResources.h"
-#include "BsPrefab.h"
-#include "BsApplication.h"
-#include "BsSceneObject.h"
-#include "BsScriptGameObjectManager.h"
-#include "BsGameResourceManager.h"
-#include "BsScriptResourceManager.h"
-#include "BsScriptPrefab.h"
-#include "BsScriptSceneObject.h"
-
-namespace BansheeEngine
-{
-	ScriptScene::ScriptScene(MonoObject* instance)
-		:ScriptObject(instance)
-	{ }
-
-	void ScriptScene::initRuntimeData()
-	{
-		metaData.scriptClass->addInternalCall("Internal_LoadScene", &ScriptScene::internal_LoadScene);
-		metaData.scriptClass->addInternalCall("Internal_GetRoot", &ScriptScene::internal_GetRoot);
-		metaData.scriptClass->addInternalCall("Internal_ClearScene", &ScriptScene::internal_ClearScene);
-		metaData.scriptClass->addInternalCall("Internal_GetMainCameraSO", &ScriptScene::internal_GetMainCameraSO);
-	}
-
-	MonoObject* ScriptScene::internal_LoadScene(MonoString* path)
-	{
-		Path nativePath = MonoUtil::monoToWString(path);
-
-		HPrefab prefab = GameResourceManager::instance().load<Prefab>(nativePath, true);
-		if (prefab.isLoaded(false))
-		{
-			HSceneObject root = prefab->instantiate();
-			gSceneManager()._setRootNode(root);
-		}
-
-		if (prefab != nullptr)
-		{
-			ScriptPrefab* scriptPrefab;
-			ScriptResourceManager::instance().getScriptResource(prefab, &scriptPrefab, true);
-
-			return scriptPrefab->getManagedInstance();
-		}
-		else
-		{
-			LOGERR("Failed loading scene at path: \"" + nativePath.toString() + "\"");
-			return nullptr;
-		}
-	}
-
-	MonoObject* ScriptScene::internal_GetRoot()
-	{
-		HSceneObject root = SceneManager::instance().getRootNode();
-
-		ScriptSceneObject* scriptRoot = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(root);
-		return scriptRoot->getManagedInstance();
-	}
-
-	void ScriptScene::internal_ClearScene()
-	{
-		gSceneManager().clearScene();
-	}
-
-	MonoObject* ScriptScene::internal_GetMainCameraSO()
-	{
-		SceneCameraData cameraData = gSceneManager().getMainCamera();
-		if (cameraData.sceneObject == nullptr)
-			return nullptr;
-
-		ScriptSceneObject* cameraSo = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(cameraData.sceneObject);
-		return cameraSo->getManagedInstance();
-	}
+#include "BsScriptScene.h"
+#include "BsMonoManager.h"
+#include "BsMonoClass.h"
+#include "BsMonoField.h"
+#include "BsMonoUtil.h"
+#include "BsSceneManager.h"
+#include "BsResources.h"
+#include "BsPrefab.h"
+#include "BsApplication.h"
+#include "BsSceneObject.h"
+#include "BsScriptGameObjectManager.h"
+#include "BsGameResourceManager.h"
+#include "BsScriptResourceManager.h"
+#include "BsScriptPrefab.h"
+#include "BsScriptSceneObject.h"
+#include "BsScriptObjectManager.h"
+
+namespace BansheeEngine
+{
+	const char* ScriptScene::ActiveSceneNameFieldName = "activeSceneName";
+	const char* ScriptScene::ActiveSceneUUIDFieldName = "activeSceneUUID";
+
+	HEvent ScriptScene::OnRefreshDomainLoadedConn;
+	HEvent ScriptScene::OnRefreshStartedConn;
+
+	String ScriptScene::ActiveSceneUUID;
+	WString ScriptScene::ActiveSceneName;
+
+	ScriptScene::ScriptScene(MonoObject* instance)
+		:ScriptObject(instance)
+	{ }
+
+	void ScriptScene::initRuntimeData()
+	{
+		metaData.scriptClass->addInternalCall("Internal_LoadScene", &ScriptScene::internal_LoadScene);
+		metaData.scriptClass->addInternalCall("Internal_GetRoot", &ScriptScene::internal_GetRoot);
+		metaData.scriptClass->addInternalCall("Internal_ClearScene", &ScriptScene::internal_ClearScene);
+		metaData.scriptClass->addInternalCall("Internal_GetMainCameraSO", &ScriptScene::internal_GetMainCameraSO);
+	}
+
+	void ScriptScene::startUp()
+	{
+		OnRefreshStartedConn = ScriptObjectManager::instance().onRefreshStarted.connect(&onRefreshStarted);
+		OnRefreshDomainLoadedConn = ScriptObjectManager::instance().onRefreshDomainLoaded.connect(&onRefreshDomainLoaded);
+	}
+
+	void ScriptScene::shutDown()
+	{
+		OnRefreshStartedConn.disconnect();
+		OnRefreshDomainLoadedConn.disconnect();
+	}
+
+	MonoObject* ScriptScene::internal_LoadScene(MonoString* path)
+	{
+		Path nativePath = MonoUtil::monoToWString(path);
+
+		HPrefab prefab = GameResourceManager::instance().load<Prefab>(nativePath, true);
+		if (prefab.isLoaded(false))
+		{
+			HSceneObject root = prefab->instantiate();
+			gSceneManager()._setRootNode(root);
+		}
+
+		if (prefab != nullptr)
+		{
+			ScriptPrefab* scriptPrefab;
+			ScriptResourceManager::instance().getScriptResource(prefab, &scriptPrefab, true);
+
+			return scriptPrefab->getManagedInstance();
+		}
+		else
+		{
+			LOGERR("Failed loading scene at path: \"" + nativePath.toString() + "\"");
+			return nullptr;
+		}
+	}
+
+	void ScriptScene::onRefreshStarted()
+	{
+		MonoField* uuidField = metaData.scriptClass->getField(ActiveSceneUUIDFieldName);
+		if (uuidField != nullptr)
+			ActiveSceneUUID = MonoUtil::monoToString((MonoString*)uuidField->getValueBoxed(nullptr));
+
+		MonoField* nameField = metaData.scriptClass->getField(ActiveSceneNameFieldName);
+		if (nameField != nullptr)
+			ActiveSceneName = MonoUtil::monoToWString((MonoString*)nameField->getValueBoxed(nullptr));
+	}
+
+	void ScriptScene::onRefreshDomainLoaded()
+	{
+		MonoField* uuidField = metaData.scriptClass->getField(ActiveSceneUUIDFieldName);
+		if (uuidField != nullptr)
+			uuidField->setValue(nullptr, MonoUtil::stringToMono(ActiveSceneUUID));
+
+		MonoField* nameField = metaData.scriptClass->getField(ActiveSceneNameFieldName);
+		if (nameField != nullptr)
+			nameField->setValue(nullptr, MonoUtil::wstringToMono(ActiveSceneName));
+	}
+
+	MonoObject* ScriptScene::internal_GetRoot()
+	{
+		HSceneObject root = SceneManager::instance().getRootNode();
+
+		ScriptSceneObject* scriptRoot = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(root);
+		return scriptRoot->getManagedInstance();
+	}
+
+	void ScriptScene::internal_ClearScene()
+	{
+		gSceneManager().clearScene();
+	}
+
+	MonoObject* ScriptScene::internal_GetMainCameraSO()
+	{
+		SceneCameraData cameraData = gSceneManager().getMainCamera();
+		if (cameraData.sceneObject == nullptr)
+			return nullptr;
+
+		ScriptSceneObject* cameraSo = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(cameraData.sceneObject);
+		return cameraSo->getManagedInstance();
+	}
 }