diff options
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 30 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.h | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 1 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 2 |
4 files changed, 31 insertions, 4 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 92fa30e5e8..4337478370 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -488,15 +488,31 @@ bool GDMono::_load_project_assembly() { #endif #ifdef GD_MONO_HOT_RELOAD +void GDMono::reload_failure() { + if (++project_load_failure_count >= (int)GLOBAL_GET("dotnet/project/assembly_reload_attempts")) { + // After reloading a project has failed n times in a row, update the path and modification time + // to stop any further attempts at loading this assembly, which probably is never going to work anyways. + project_load_failure_count = 0; + + ERR_PRINT_ED(".NET: Giving up on assembly reloading. Please restart the editor if unloading was failing."); + + String assembly_name = path::get_csharp_project_name(); + String assembly_path = GodotSharpDirs::get_res_temp_assemblies_dir().path_join(assembly_name + ".dll"); + assembly_path = ProjectSettings::get_singleton()->globalize_path(assembly_path); + project_assembly_path = assembly_path.simplify_path(); + project_assembly_modified_time = FileAccess::get_modified_time(assembly_path); + } +} + Error GDMono::reload_project_assemblies() { ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG); finalizing_scripts_domain = true; - CSharpLanguage::get_singleton()->_on_scripts_domain_about_to_unload(); - if (!get_plugin_callbacks().UnloadProjectPluginCallback()) { - ERR_FAIL_V_MSG(Error::FAILED, ".NET: Failed to unload assemblies."); + ERR_PRINT_ED(".NET: Failed to unload assemblies. Please check https://github.com/godotengine/godot/issues/78513 for more information."); + reload_failure(); + return FAILED; } finalizing_scripts_domain = false; @@ -504,10 +520,16 @@ Error GDMono::reload_project_assemblies() { // Load the project's main assembly. Here, during hot-reloading, we do // consider failing to load the project's main assembly to be an error. if (!_load_project_assembly()) { - print_error(".NET: Failed to load project assembly."); + ERR_PRINT_ED(".NET: Failed to load project assembly."); + reload_failure(); return ERR_CANT_OPEN; } + if (project_load_failure_count > 0) { + project_load_failure_count = 0; + ERR_PRINT_ED(".NET: Assembly reloading succeeded after failures."); + } + return OK; } #endif diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 398f94d924..c629ab2eff 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -68,6 +68,7 @@ class GDMono { String project_assembly_path; uint64_t project_assembly_modified_time = 0; + int project_load_failure_count = 0; #ifdef TOOLS_ENABLED bool _load_project_assembly(); @@ -144,6 +145,7 @@ public: #endif #ifdef GD_MONO_HOT_RELOAD + void reload_failure(); Error reload_project_assemblies(); #endif diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index e254484df9..8fdf163b26 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -79,6 +79,7 @@ void update_godot_api_cache(const ManagedCallbacks &p_managed_callbacks) { CHECK_CALLBACK_NOT_NULL(CSharpInstanceBridge, SerializeState); CHECK_CALLBACK_NOT_NULL(CSharpInstanceBridge, DeserializeState); CHECK_CALLBACK_NOT_NULL(GCHandleBridge, FreeGCHandle); + CHECK_CALLBACK_NOT_NULL(GCHandleBridge, GCHandleIsTargetCollectible); CHECK_CALLBACK_NOT_NULL(DebuggingUtils, GetCurrentStackInfo); CHECK_CALLBACK_NOT_NULL(DisposablesTracker, OnGodotShuttingDown); CHECK_CALLBACK_NOT_NULL(GD, OnCoreApiAssemblyLoaded); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 9201da7cae..f604e4d681 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -104,6 +104,7 @@ struct ManagedCallbacks { using FuncCSharpInstanceBridge_SerializeState = void(GD_CLR_STDCALL *)(GCHandleIntPtr, const Dictionary *, const Dictionary *); using FuncCSharpInstanceBridge_DeserializeState = void(GD_CLR_STDCALL *)(GCHandleIntPtr, const Dictionary *, const Dictionary *); using FuncGCHandleBridge_FreeGCHandle = void(GD_CLR_STDCALL *)(GCHandleIntPtr); + using FuncGCHandleBridge_GCHandleIsTargetCollectible = bool(GD_CLR_STDCALL *)(GCHandleIntPtr); using FuncDebuggingUtils_GetCurrentStackInfo = void(GD_CLR_STDCALL *)(Vector<ScriptLanguage::StackInfo> *); using FuncDisposablesTracker_OnGodotShuttingDown = void(GD_CLR_STDCALL *)(); using FuncGD_OnCoreApiAssemblyLoaded = void(GD_CLR_STDCALL *)(bool); @@ -138,6 +139,7 @@ struct ManagedCallbacks { FuncCSharpInstanceBridge_SerializeState CSharpInstanceBridge_SerializeState; FuncCSharpInstanceBridge_DeserializeState CSharpInstanceBridge_DeserializeState; FuncGCHandleBridge_FreeGCHandle GCHandleBridge_FreeGCHandle; + FuncGCHandleBridge_GCHandleIsTargetCollectible GCHandleBridge_GCHandleIsTargetCollectible; FuncDebuggingUtils_GetCurrentStackInfo DebuggingUtils_GetCurrentStackInfo; FuncDisposablesTracker_OnGodotShuttingDown DisposablesTracker_OnGodotShuttingDown; FuncGD_OnCoreApiAssemblyLoaded GD_OnCoreApiAssemblyLoaded; |