diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index 79f9d5518..dd39b7d58 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -1248,7 +1248,7 @@ namespace FlaxEngine.Interop } [UnmanagedCallersOnly] - internal static void LoadScriptingAssemblyLoadContext() + internal static void ReloadScriptingAssemblyLoadContext() { #if FLAX_EDITOR // Clear all caches which might hold references to assemblies in collectible ALC @@ -1272,18 +1272,16 @@ namespace FlaxEngine.Interop FlaxEngine.Json.JsonSerializer.ResetCache(); // Unload the ALC - if (scriptingAssemblyLoadContext != null) - { - bool unloading = true; - scriptingAssemblyLoadContext.Unloading += (alc) => { unloading = false; }; - scriptingAssemblyLoadContext.Unload(); + bool unloading = true; + scriptingAssemblyLoadContext.Unloading += (alc) => { unloading = false; }; + scriptingAssemblyLoadContext.Unload(); + + while (unloading) + System.Threading.Thread.Sleep(1); - while (unloading) - System.Threading.Thread.Sleep(1); - } -#endif InitScriptingAssemblyLoadContext(); DelegateHelpers.InitMethods(); +#endif } [UnmanagedCallersOnly] diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 5c7ebdb6f..2e0750332 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -92,6 +92,8 @@ namespace FlaxEngine.Interop System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + InitScriptingAssemblyLoadContext(); + DelegateHelpers.InitMethods(); } #if FLAX_EDITOR diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp index 77193c462..8b97bc1d5 100644 --- a/Source/Engine/Renderer/Renderer.cpp +++ b/Source/Engine/Renderer/Renderer.cpp @@ -110,9 +110,6 @@ bool RendererService::Init() } } - // TODO: move it somewhere to game instance class or similar - MainRenderTask::Instance = New(); - return false; } diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.h b/Source/Engine/Scripting/ManagedCLR/MCore.h index d69ce104f..5352a4b29 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.h +++ b/Source/Engine/Scripting/ManagedCLR/MCore.h @@ -45,8 +45,10 @@ public: /// static void UnloadEngine(); - // Called by Scripting during initialization or in a middle of hot-reload (after unloading modules but before loading them again). - static void LoadScriptingAssemblyLoadContext(); +#if USE_EDITOR + // Called by Scripting in a middle of hot-reload (after unloading modules but before loading them again). + static void ReloadScriptingAssemblyLoadContext(); +#endif public: /// diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 8487fc1f0..1267b09d4 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -278,8 +278,6 @@ bool MCore::LoadEngine() // Prepare managed side CallStaticMethod(GetStaticMethodPointer(TEXT("Init"))); - MCore::LoadScriptingAssemblyLoadContext(); - #ifdef MCORE_MAIN_MODULE_NAME // MCORE_MAIN_MODULE_NAME define is injected by Scripting.Build.cs on platforms that use separate shared library for engine symbols ::String flaxLibraryPath(Platform::GetMainDirectory() / TEXT(MACRO_TO_STR(MCORE_MAIN_MODULE_NAME))); @@ -322,16 +320,20 @@ void MCore::UnloadEngine() ShutdownHostfxr(); } -void MCore::LoadScriptingAssemblyLoadContext() +#if USE_EDITOR + +void MCore::ReloadScriptingAssemblyLoadContext() { // Clear any cached class attributes (see https://github.com/FlaxEngine/FlaxEngine/issues/1108) for (auto e : CachedClassHandles) e.Value->_attributes.Clear(); - static void* LoadScriptingAssemblyLoadContextPtr = GetStaticMethodPointer(TEXT("LoadScriptingAssemblyLoadContext")); - CallStaticMethod(LoadScriptingAssemblyLoadContextPtr); + static void* ReloadScriptingAssemblyLoadContextPtr = GetStaticMethodPointer(TEXT("ReloadScriptingAssemblyLoadContext")); + CallStaticMethod(ReloadScriptingAssemblyLoadContextPtr); } +#endif + MObject* MCore::Object::Box(void* value, const MClass* klass) { static void* BoxValuePtr = GetStaticMethodPointer(TEXT("BoxValue")); diff --git a/Source/Engine/Scripting/Runtime/Mono.cpp b/Source/Engine/Scripting/Runtime/Mono.cpp index 9fc8a70f2..2e507a44a 100644 --- a/Source/Engine/Scripting/Runtime/Mono.cpp +++ b/Source/Engine/Scripting/Runtime/Mono.cpp @@ -717,7 +717,7 @@ void MCore::UnloadEngine() #if USE_EDITOR -void MCore::LoadScriptingAssemblyLoadContext() +void MCore::ReloadScriptingAssemblyLoadContext() { } diff --git a/Source/Engine/Scripting/Runtime/None.cpp b/Source/Engine/Scripting/Runtime/None.cpp index 8e0285cc7..1fb0e6d1f 100644 --- a/Source/Engine/Scripting/Runtime/None.cpp +++ b/Source/Engine/Scripting/Runtime/None.cpp @@ -60,7 +60,7 @@ void MCore::UnloadEngine() #if USE_EDITOR -void MCore::LoadScriptingAssemblyLoadContext() +void MCore::ReloadScriptingAssemblyLoadContext() { } diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 67e646807..35b90a9ad 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -39,7 +39,7 @@ class ScriptingService : public EngineService { public: ScriptingService() - : EngineService(TEXT("Scripting"), -999) + : EngineService(TEXT("Scripting"), -20) { } @@ -703,7 +703,7 @@ void Scripting::Reload(bool canTriggerSceneReload) _hasGameModulesLoaded = false; // Release and create a new assembly load context for user assemblies - MCore::LoadScriptingAssemblyLoadContext(); + MCore::ReloadScriptingAssemblyLoadContext(); // Give GC a try to cleanup old user objects and the other mess MCore::GC::Collect(); @@ -1091,6 +1091,9 @@ bool initFlaxEngine() } #endif + // TODO: move it somewhere to game instance class or similar + MainRenderTask::Instance = New(); + return false; }