Browse Source

Properly clean up Renderable/Camera/Light on assembly refresh
Managed component OnDestroyed now gets called regardless of play mode in order to clean everything up properly
When switching play modes clear selection to avoid invalid selection of a destroyed object
Managed selection manager can now handle null selection

BearishSun 10 years ago
parent
commit
7ce45604fb

+ 2 - 0
BansheeEditor/Source/BsEditorUtility.cpp

@@ -42,6 +42,8 @@ namespace BansheeEngine
 	bool EditorUtility::calculateMeshBounds(const HSceneObject& object, AABox& bounds)
 	bool EditorUtility::calculateMeshBounds(const HSceneObject& object, AABox& bounds)
 	{
 	{
 		bounds = AABox(Vector3::ZERO, Vector3::ZERO);
 		bounds = AABox(Vector3::ZERO, Vector3::ZERO);
+		if (object.isDestroyed())
+			return false;
 
 
 		bool foundOne = false;
 		bool foundOne = false;
 		const Vector<HComponent>& components = object->getComponents();
 		const Vector<HComponent>& components = object->getComponents();

+ 4 - 0
MBansheeEditor/EditorApplication.cs

@@ -101,6 +101,10 @@ namespace BansheeEditor
             {
             {
                 ToggleToolbarItem("Play", value);
                 ToggleToolbarItem("Play", value);
                 ToggleToolbarItem("Pause", false);
                 ToggleToolbarItem("Pause", false);
+
+                if (!value)
+                    Selection.SceneObject = null;
+
                 Internal_SetIsPlaying(value);
                 Internal_SetIsPlaying(value);
             }
             }
         }
         }

+ 2 - 4
MBansheeEngine/Component.cs

@@ -16,11 +16,9 @@ namespace BansheeEngine
     /// void OnDisable() - Called whenever a component is disabled. This includes destruction where it is called before 
     /// void OnDisable() - Called whenever a component is disabled. This includes destruction where it is called before 
     ///                    OnDestroy. Only called when the game is playing or paused.
     ///                    OnDestroy. Only called when the game is playing or paused.
     /// void OnDestroy() - Called before the component is destroyed. Destruction is usually delayed until the end of the 
     /// void OnDestroy() - Called before the component is destroyed. Destruction is usually delayed until the end of the 
-    ///                    current frame unless specified otherwise in a call to Destroy. Only called when the game is 
-    ///                    playing or paused.
+    ///                    current frame unless specified otherwise in a call to Destroy. 
     /// void OnReset() - Called when script assemblies have been refreshed or when the component is initialized. During
     /// void OnReset() - Called when script assemblies have been refreshed or when the component is initialized. During
-    ///                  initialization it is called after OnInitialize but before OnEnable. Only relevant in editor. Only 
-    ///                  called when the game is playing or paused.
+    ///                  initialization it is called after OnInitialize but before OnEnable. Only relevant in editor.
     ///
     ///
     /// You can also make these callbacks trigger when the game is stopped/paused by using the <see cref="RunInEditor"/>
     /// You can also make these callbacks trigger when the game is stopped/paused by using the <see cref="RunInEditor"/>
     /// attribute on the component.
     /// attribute on the component.

+ 1 - 1
MBansheeEngine/Math/MathEx.cs

@@ -18,7 +18,7 @@ namespace BansheeEngine
     /// <summary>
     /// <summary>
     /// Utility class providing common scalar math operations.
     /// Utility class providing common scalar math operations.
     /// </summary>
     /// </summary>
-    class MathEx
+    public class MathEx
     {
     {
         /// <summary>
         /// <summary>
         /// Pi constant.
         /// Pi constant.

+ 13 - 7
SBansheeEditor/Source/BsScriptSelection.cpp

@@ -63,14 +63,20 @@ namespace BansheeEngine
 	{
 	{
 		Vector<HSceneObject> sceneObjects;
 		Vector<HSceneObject> sceneObjects;
 
 
-		UINT32 arrayLen = (UINT32)mono_array_length(selection);
-		for (UINT32 i = 0; i < arrayLen; i++)
+		if (selection != nullptr)
 		{
 		{
-			MonoObject* monoSO = mono_array_get(selection, MonoObject*, i);
-			ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(monoSO);
-			HSceneObject so = static_object_cast<SceneObject>(scriptSO->getNativeHandle());
-
-			sceneObjects.push_back(so);
+			UINT32 arrayLen = (UINT32)mono_array_length(selection);
+			for (UINT32 i = 0; i < arrayLen; i++)
+			{
+				MonoObject* monoSO = mono_array_get(selection, MonoObject*, i);
+				ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(monoSO);
+
+				if (scriptSO == nullptr)
+					continue;
+
+				HSceneObject so = static_object_cast<SceneObject>(scriptSO->getNativeHandle());
+				sceneObjects.push_back(so);
+			}
 		}
 		}
 
 
 		Selection::instance().setSceneObjects(sceneObjects);
 		Selection::instance().setSceneObjects(sceneObjects);

+ 10 - 0
SBansheeEngine/Include/BsScriptCamera.h

@@ -36,6 +36,16 @@ namespace BansheeEngine
 		 */
 		 */
 		void updateView(const HSceneObject& parent);
 		void updateView(const HSceneObject& parent);
 
 
+		/**
+		 * @brief	Destroys the internal camera handler object.
+		 */
+		void destroy();
+
+		/**
+		 * @copydoc	ScriptObject::_onManagedInstanceDeleted
+		 */
+		void _onManagedInstanceDeleted() override;
+
 		SPtr<Camera> mCamera;
 		SPtr<Camera> mCamera;
 		UINT32 mLastUpdateHash;
 		UINT32 mLastUpdateHash;
 
 

+ 10 - 0
SBansheeEngine/Include/BsScriptLight.h

@@ -27,6 +27,16 @@ namespace BansheeEngine
 		ScriptLight(MonoObject* managedInstance, const HSceneObject& parentSO);
 		ScriptLight(MonoObject* managedInstance, const HSceneObject& parentSO);
 		~ScriptLight();
 		~ScriptLight();
 
 
+		/**
+		 * @brief	Destroys the internal light handler object.
+		 */
+		void destroy();
+
+		/**
+		 * @copydoc	ScriptObject::_onManagedInstanceDeleted
+		 */
+		void _onManagedInstanceDeleted() override;
+
 		SPtr<Light> mLight;
 		SPtr<Light> mLight;
 		UINT32 mLastUpdateHash;
 		UINT32 mLastUpdateHash;
 
 

+ 5 - 0
SBansheeEngine/Include/BsScriptRenderable.h

@@ -33,6 +33,11 @@ namespace BansheeEngine
 		 */
 		 */
 		void destroy();
 		void destroy();
 
 
+		/**
+		 * @copydoc	ScriptObject::_onManagedInstanceDeleted
+		 */
+		void _onManagedInstanceDeleted() override;
+
 		SPtr<Renderable> mRenderable;
 		SPtr<Renderable> mRenderable;
 		UINT32 mLastUpdateHash;
 		UINT32 mLastUpdateHash;
 
 

+ 8 - 14
SBansheeEngine/Source/BsManagedComponent.cpp

@@ -256,14 +256,11 @@ namespace BansheeEngine
 	{
 	{
 		assert(mManagedInstance != nullptr);
 		assert(mManagedInstance != nullptr);
 
 
-		if (PlayInEditorManager::instance().getState() != PlayInEditorState::Stopped || mRunInEditor)
+		if (mRequiresReset && mOnResetThunk != nullptr)
 		{
 		{
-			if (mRequiresReset && mOnResetThunk != nullptr)
-			{
-				// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
-				// for some extra speed.
-				MonoUtil::invokeThunk(mOnResetThunk, mManagedInstance);
-			}
+			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
+			// for some extra speed.
+			MonoUtil::invokeThunk(mOnResetThunk, mManagedInstance);
 		}
 		}
 
 
 		mRequiresReset = false;
 		mRequiresReset = false;
@@ -324,14 +321,11 @@ namespace BansheeEngine
 	{
 	{
 		assert(mManagedInstance != nullptr);
 		assert(mManagedInstance != nullptr);
 
 
-		if (PlayInEditorManager::instance().getState() == PlayInEditorState::Stopped || mRunInEditor)
+		if (mOnDestroyThunk != nullptr)
 		{
 		{
-			if (mOnDestroyThunk != nullptr)
-			{
-				// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
-				// for some extra speed.
-				MonoUtil::invokeThunk(mOnDestroyThunk, mManagedInstance);
-			}
+			// Note: Not calling virtual methods. Can be easily done if needed but for now doing this
+			// for some extra speed.
+			MonoUtil::invokeThunk(mOnDestroyThunk, mManagedInstance);
 		}
 		}
 
 
 		mManagedInstance = nullptr;
 		mManagedInstance = nullptr;

+ 17 - 2
SBansheeEngine/Source/BsScriptCamera.cpp

@@ -416,7 +416,22 @@ namespace BansheeEngine
 
 
 	void ScriptCamera::internal_OnDestroy(ScriptCamera* instance)
 	void ScriptCamera::internal_OnDestroy(ScriptCamera* instance)
 	{
 	{
-		gSceneManager()._unregisterCamera(instance->getInternal());
-		instance->getInternal()->destroy();
+		instance->destroy();
+	}
+
+	void ScriptCamera::destroy()
+	{
+		if (mCamera->isDestroyed())
+			return;
+
+		gSceneManager()._unregisterCamera(mCamera);
+		mCamera->destroy();
+	}
+
+	void ScriptCamera::_onManagedInstanceDeleted()
+	{
+		destroy();
+
+		ScriptObject::_onManagedInstanceDeleted();
 	}
 	}
 }
 }

+ 17 - 2
SBansheeEngine/Source/BsScriptLight.cpp

@@ -135,7 +135,22 @@ namespace BansheeEngine
 
 
 	void ScriptLight::internal_onDestroy(ScriptLight* instance)
 	void ScriptLight::internal_onDestroy(ScriptLight* instance)
 	{
 	{
-		gSceneManager()._unregisterLight(instance->getInternal());
-		instance->getInternal()->destroy();
+		instance->destroy();
+	}
+
+	void ScriptLight::destroy()
+	{
+		if (mLight->isDestroyed())
+			return;
+
+		gSceneManager()._unregisterLight(mLight);
+		mLight->destroy();
+	}
+
+	void ScriptLight::_onManagedInstanceDeleted()
+	{
+		destroy();
+
+		ScriptObject::_onManagedInstanceDeleted();
 	}
 	}
 }
 }

+ 10 - 0
SBansheeEngine/Source/BsScriptRenderable.cpp

@@ -140,7 +140,17 @@ namespace BansheeEngine
 
 
 	void ScriptRenderable::destroy()
 	void ScriptRenderable::destroy()
 	{
 	{
+		if (mRenderable->isDestroyed())
+			return;
+
 		gSceneManager()._unregisterRenderable(mRenderable);
 		gSceneManager()._unregisterRenderable(mRenderable);
 		mRenderable->destroy();
 		mRenderable->destroy();
 	}
 	}
+
+	void ScriptRenderable::_onManagedInstanceDeleted()
+	{
+		destroy();
+
+		ScriptObject::_onManagedInstanceDeleted();
+	}
 }
 }