summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-10-27 08:07:33 +0100
committerGitHub <noreply@github.com>2020-10-27 08:07:33 +0100
commitf594f31823f31396b363386558fb62571fc7c7c5 (patch)
treeffc7c072070f64f02eccefffec1a70bed64e7ebb
parent0e3b011dee1ec9c44aa8a9315382bae521de7633 (diff)
parent34960cb9360ec68d23afdde5b9519630183a31b4 (diff)
Merge pull request #43088 from neikeq/fix-custom-event-signal-hot-reload
C#: Fix custom event signals crash on hot-reload
-rw-r--r--modules/mono/csharp_script.cpp15
-rw-r--r--modules/mono/csharp_script.h2
-rw-r--r--modules/mono/editor/bindings_generator.cpp4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs13
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp2
5 files changed, 19 insertions, 17 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 70b731d611..8928b6e5e3 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -940,8 +940,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
// Use a placeholder for now to avoid losing the state when saving a scene
- obj->set_script(scr);
-
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
obj->set_script_instance(placeholder);
@@ -968,12 +966,12 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
for (List<Ref<CSharpScript>>::Element *E = to_reload.front(); E; E = E->next()) {
Ref<CSharpScript> script = E->get();
- if (!script->get_path().empty()) {
#ifdef TOOLS_ENABLED
- script->exports_invalidated = true;
+ script->exports_invalidated = true;
#endif
- script->signals_invalidated = true;
+ script->signals_invalidated = true;
+ if (!script->get_path().empty()) {
script->reload(p_soft_reload);
if (!script->valid) {
@@ -1949,6 +1947,7 @@ MonoObject *CSharpInstance::_internal_new_managed() {
}
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
+ // Must make sure event signals are not left dangling
disconnect_event_signals();
#ifdef DEBUG_ENABLED
@@ -1964,6 +1963,9 @@ void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_f
CRASH_COND(gchandle.is_released());
#endif
+ // Must make sure event signals are not left dangling
+ disconnect_event_signals();
+
r_remove_script_instance = false;
if (_unreference_owner_unsafe()) {
@@ -2223,6 +2225,9 @@ CSharpInstance::~CSharpInstance() {
destructing_script_instance = true;
+ // Must make sure event signals are not left dangling
+ disconnect_event_signals();
+
if (!gchandle.is_released()) {
if (!predelete_notified && !ref_dying) {
// This destructor is not called from the owners destructor.
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index cfe070a371..316fd78f2a 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -288,7 +288,7 @@ public:
void mono_object_disposed(MonoObject *p_obj);
/*
- * If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, ifevent_signal
+ * If 'r_delete_owner' is set to true, the caller must memdelete the script instance's owner. Otherwise, if
* 'r_remove_script_instance' is set to true, the caller must destroy the script instance by removing it from its owner.
*/
void mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_delete_owner, bool &r_remove_script_instance);
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index a17c371117..4c137a2ba4 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -97,7 +97,7 @@
#define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
#define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
-#define BINDINGS_GENERATOR_VERSION UINT32_C(11)
+#define BINDINGS_GENERATOR_VERSION UINT32_C(12)
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
@@ -1368,7 +1368,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(")\n" OPEN_BLOCK_L2 "if (" BINDINGS_PTR_FIELD " == IntPtr.Zero)\n" INDENT4 BINDINGS_PTR_FIELD " = ");
output.append(itype.api_type == ClassDB::API_EDITOR ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS);
output.append("." + ctor_method);
- output.append("(this);\n" CLOSE_BLOCK_L2);
+ output.append("(this);\n" INDENT3 "_InitializeGodotScriptInstanceInternals();\n" CLOSE_BLOCK_L2);
} else {
// Hide the constructor
output.append(MEMBER_BEGIN "internal ");
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
index 42610c5ef7..48582d5ad8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Object.base.cs
@@ -15,14 +15,13 @@ namespace Godot
public Object() : this(false)
{
if (ptr == IntPtr.Zero)
- {
ptr = godot_icall_Object_Ctor(this);
- }
- else
- {
- // This is called inside godot_icall_Object_Ctor, so we must call it as well in this case.
- godot_icall_Object_ConnectEventSignals(ptr);
- }
+ _InitializeGodotScriptInstanceInternals();
+ }
+
+ internal void _InitializeGodotScriptInstanceInternals()
+ {
+ godot_icall_Object_ConnectEventSignals(ptr);
}
internal Object(bool memoryOwn)
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index fe1c2d28dd..0ed9e441ef 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -109,8 +109,6 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle);
unmanaged->set_script_and_instance(script, csharp_instance);
-
- csharp_instance->connect_event_signals();
}
void unhandled_exception(MonoException *p_exc) {