diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index d6f2524c7..23ac2a935 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -109,6 +109,45 @@ namespace #if USE_EDITOR bool LastBinariesLoadTriggeredCompilation = false; #endif + + void ReleaseObjects(bool gameOnly) + { + // Flush objects already enqueued objects to delete + ObjectsRemovalService::Flush(); + + // Give GC a try to cleanup old user objects and the other mess + MCore::GC::Collect(); + MCore::GC::WaitForPendingFinalizers(); + + // Destroy objects from game assemblies (eg. not released objects that might crash if persist in memory after reload) + const auto flaxModule = GetBinaryModuleFlaxEngine(); + _objectsLocker.Lock(); + for (auto i = _objectsDictionary.Begin(); i.IsNotEnd(); ++i) + { + auto obj = i->Value; + if (gameOnly && obj->GetTypeHandle().Module == flaxModule) + continue; + +#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING + LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint64)obj.Ptr, String(obj.TypeName)); +#endif + obj->OnScriptingDispose(); + } + _objectsLocker.Unlock(); + + // Release assets sourced from game assemblies + Array assets = Content::GetAssets(); + for (auto asset : assets) + { + if (asset->GetTypeHandle().Module == flaxModule) + { + continue; + } + + asset->DeleteObject(); + } + ObjectsRemovalService::Flush(); + } } Delegate Scripting::BinaryModuleLoaded; @@ -566,36 +605,8 @@ void Scripting::Release() // Fire event ScriptsUnload(); - // Cleanup - ObjectsRemovalService::Flush(); - - // Cleanup some managed objects - MCore::GC::Collect(); - MCore::GC::WaitForPendingFinalizers(); - // Release managed objects instances for persistent objects (assets etc.) - _objectsLocker.Lock(); - { - for (auto i = _objectsDictionary.Begin(); i.IsNotEnd(); ++i) - { - auto obj = i->Value; -#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING - LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint64)obj.Ptr, String(obj.TypeName)); -#endif - obj->OnScriptingDispose(); - } - } - _objectsLocker.Unlock(); - - // Release assets sourced from game assemblies - const auto flaxModule = GetBinaryModuleFlaxEngine(); - for (auto asset : Content::GetAssets()) - { - if (asset->GetTypeHandle().Module == flaxModule) - continue; - - asset->DeleteObjectNow(); - } + ReleaseObjects(false); auto* flaxEngineModule = (NativeBinaryModule*)GetBinaryModuleFlaxEngine(); onEngineUnloading(flaxEngineModule->Assembly); @@ -673,39 +684,8 @@ void Scripting::Reload(bool canTriggerSceneReload) LOG(Info, "Start user scripts reload"); ScriptsReloading(); - // Flush cache (some objects may be deleted after reload start event) - ObjectsRemovalService::Flush(); - - // Give GC a try to cleanup old user objects and the other mess - MCore::GC::Collect(); - MCore::GC::WaitForPendingFinalizers(); - // Destroy objects from game assemblies (eg. not released objects that might crash if persist in memory after reload) - const auto flaxModule = GetBinaryModuleFlaxEngine(); - _objectsLocker.Lock(); - { - for (auto i = _objectsDictionary.Begin(); i.IsNotEnd(); ++i) - { - auto obj = i->Value; - if (obj->GetTypeHandle().Module == flaxModule) - continue; - -#if USE_OBJECTS_DISPOSE_CRASHES_DEBUGGING - LOG(Info, "[OnScriptingDispose] obj = 0x{0:x}, {1}", (uint64)obj.Ptr, String(obj.TypeName)); -#endif - obj->OnScriptingDispose(); - } - } - _objectsLocker.Unlock(); - - // Release assets sourced from game assemblies - for (auto asset : Content::GetAssets()) - { - if (asset->GetTypeHandle().Module == flaxModule) - continue; - - asset->DeleteObjectNow(); - } + ReleaseObjects(true); // Unload all game modules LOG(Info, "Unloading game binary modules");