summaryrefslogtreecommitdiffstats
path: root/modules/mono/mono_gd
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp30
-rw-r--r--modules/mono/mono_gd/gd_mono.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp1
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h2
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;