From 8f9a4e8c734f27ff9da592bb3be453a62c1535bb Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 31 Jan 2023 18:09:07 +0800 Subject: [PATCH] Fixed bug where onDestroy() is not called for scripts that are destroyed when leaving play mode in the editor --- .../EditorWindow/MenuBar/SHEditorMenuBar.h | 1 + SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 27 +++++++++++ SHADE_Engine/src/Scripting/SHScriptEngine.h | 10 ++++ .../src/Scripting/SHScriptEngineRoutines.cpp | 2 +- SHADE_Managed/src/Scripts/ScriptStore.cxx | 47 +++++++++++++------ SHADE_Managed/src/Scripts/ScriptStore.hxx | 8 ++++ 6 files changed, 80 insertions(+), 15 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h index 77ebcf55..e265b33e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h @@ -4,6 +4,7 @@ //|| SHADE Includes || //#==============================================================# #include "Editor/EditorWindow/SHEditorWindow.h" +#include "Editor/SHEditor.h" namespace SHADE { diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 6582ecf0..21dea845 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -33,6 +33,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHVSUtilities.h" #include "UI/Events/SHButtonClickEvent.h" #include "UI/SHUIComponent.h" +#include "Editor/EditorWindow/MenuBar/SHEditorMenuBar.h" namespace SHADE { @@ -123,6 +124,11 @@ namespace SHADE csScriptsRemoveAllImmediately(entity, callOnDestroy); } + void SHScriptEngine::RemoveAllScriptsFromAllImmediately(bool callOnDestroy) + { + csScriptRemoveAllForAllNow(callOnDestroy); + } + /*---------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*---------------------------------------------------------------------------------*/ @@ -377,6 +383,13 @@ namespace SHADE return eventData->handle; } + SHEventHandle SHScriptEngine::onSceneDestroyed(SHEventPtr eventPtr) + { + auto eventData = reinterpret_cast*>(eventPtr.get()); + csScriptRemoveAllForAllNow(true); + return eventData->handle; + } + /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------------*/ @@ -477,6 +490,12 @@ namespace SHADE DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", "RemoveAllScriptsImmediately" ); + csScriptRemoveAllForAllNow = dotNet.GetFunctionPtr + ( + DEFAULT_CSHARP_LIB_NAME, + DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", + "RemoveAllScriptsFromAllImmediately" + ); csScriptsSerialiseYaml = dotNet.GetFunctionPtr ( DEFAULT_CSHARP_LIB_NAME, @@ -549,6 +568,14 @@ namespace SHADE }; SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast(destroyedEventReceiver)); + /* Editor */ + // Register for editor state change event + std::shared_ptr> destroyedSceneEventReceiver + { + std::make_shared>(this, &SHScriptEngine::onSceneDestroyed) + }; + SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, std::dynamic_pointer_cast(destroyedSceneEventReceiver)); + /* Colliders */ // Register for collider added event std::shared_ptr> addedColliderEventReceiver diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 5f104482..fd88a283 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -148,6 +148,13 @@ namespace SHADE /// play mode. /// void RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy); + /// + /// Removes all Scripts attached to all entities immediately. The + /// + /// + /// Whether or not to call OnDestroy on the scripts. + /// + void RemoveAllScriptsFromAllImmediately(bool callOnDestroy); /*-----------------------------------------------------------------------------*/ /* Script Serialisation Functions */ @@ -235,6 +242,7 @@ namespace SHADE using CsScriptManipFuncPtr = bool(*)(EntityID, const char*); using CsScriptBasicFuncPtr = void(*)(EntityID); using CsScriptOptionalFuncPtr = void(*)(EntityID, bool); + using CsScriptBoolFuncPtr = void(*)(bool); using CsScriptSerialiseYamlFuncPtr = bool(*)(EntityID, void*); using CsScriptDeserialiseYamlFuncPtr = bool(*)(EntityID, const void*); using CsScriptEditorFuncPtr = void(*)(EntityID); @@ -271,6 +279,7 @@ namespace SHADE CsScriptManipFuncPtr csScriptsAdd = nullptr; CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; + CsScriptBoolFuncPtr csScriptRemoveAllForAllNow = nullptr; CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; CsScriptDeserialiseYamlFuncPtr csScriptsDeserialiseYaml = nullptr; // - Events @@ -295,6 +304,7 @@ namespace SHADE SHEventHandle onUIElementClicked(SHEventPtr eventPtr); SHEventHandle onSceneNodeChildrenAdded(SHEventPtr eventPtr); SHEventHandle onSceneNodeChildrenRemoved(SHEventPtr eventPtr); + SHEventHandle onSceneDestroyed(SHEventPtr eventPtr); /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp index 699776ca..9f5b2818 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp @@ -65,7 +65,7 @@ namespace SHADE /* System Routine Functions - FrameCleanUpRoutine */ /*-----------------------------------------------------------------------------------*/ SHScriptEngine::FrameCleanUpRoutine::FrameCleanUpRoutine() - : SHSystemRoutine("Script Engine Frame Clean Up", true) + : SHSystemRoutine("Script Engine Frame Clean Up", true) {} void SHScriptEngine::FrameCleanUpRoutine::Execute(double) noexcept { diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index a5a0ebc7..c1747852 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -400,24 +400,24 @@ namespace SHADE return; // Clear all - System::Collections::Generic::List^ scriptList = scripts[entity]; - for each (Script ^ script in scriptList) + removeAllScriptsImmediately(entity, callOnDestroy && Application::IsPlaying || Application::IsPaused); + SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") + } + + void ScriptStore::RemoveAllScriptsFromAllImmediately(bool callOnDestroy) + { + SAFE_NATIVE_CALL_BEGIN + // Clear all + for each (System::Collections::Generic::KeyValuePair^ pair in scripts) { - // Call OnDestroy only if indicated and also if the game has run - if (callOnDestroy && Application::IsPlaying || Application::IsPaused) - { - script->OnDestroy(); - } - script->OnDetached(); - - // Remove scripts from awakening if they were not woken up to begin with - awakeList.Remove(script); - startList.Remove(script); + removeAllScriptsImmediately(pair->Key, callOnDestroy); } - scriptList->Clear(); + awakeList.Clear(); + startList.Clear(); + disposalQueue.Clear(); SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") } - + /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ /*---------------------------------------------------------------------------------*/ @@ -798,6 +798,25 @@ namespace SHADE script->OnDetached(); } + void ScriptStore::removeAllScriptsImmediately(Entity entity, bool callOnDestroy) + { + System::Collections::Generic::List^ scriptList = scripts[entity]; + for each (Script ^ script in scriptList) + { + // Call OnDestroy only if indicated and also if the game has run + if (callOnDestroy) + { + script->OnDestroy(); + } + script->OnDetached(); + + // Remove scripts from awakening if they were not woken up to begin with + awakeList.Remove(script); + startList.Remove(script); + } + scriptList->Clear(); + } + namespace { /* Select Many */ diff --git a/SHADE_Managed/src/Scripts/ScriptStore.hxx b/SHADE_Managed/src/Scripts/ScriptStore.hxx index 77924203..bac58a77 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.hxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.hxx @@ -228,6 +228,13 @@ namespace SHADE /// play mode. /// static void RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy); + /// + /// Removes all Scripts attached to all entities immediately. The + /// + /// + /// Whether or not to call OnDestroy on the scripts. + /// + static void RemoveAllScriptsFromAllImmediately(bool callOnDestroy); internal: /*-----------------------------------------------------------------------------*/ @@ -343,6 +350,7 @@ namespace SHADE /* Helper Functions */ /*-----------------------------------------------------------------------------*/ static void removeScript(Script^ script); + static void removeAllScriptsImmediately(Entity script, bool callOnDestroy); static void refreshScriptTypeList(); static void getGenericMethods(); static System::Type^ getScriptType(System::String^ scriptName);