summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <neikeq@users.noreply.github.com>2022-10-02 19:23:44 +0200
committerGitHub <noreply@github.com>2022-10-02 19:23:44 +0200
commitabf473e2d022accdd5b7aa21d3e0b934b6ec0523 (patch)
tree72d3dcc6075b0980bf67c76ae6b5c40b230092dc
parente69b7083d45c5d8698508cce7086d361c4b1f44c (diff)
parent161f295f52d21dea940d7c06e5f83a14beefb4c9 (diff)
Merge pull request #66674 from pkdawson/fix-callable-delegate
Fix C# delegate signal not disconnected when Object is destroyed
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs3
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs2
-rw-r--r--modules/mono/glue/runtime_interop.cpp5
-rw-r--r--modules/mono/managed_callable.cpp6
-rw-r--r--modules/mono/managed_callable.h3
6 files changed, 13 insertions, 8 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
index 1b7f5158fd..bdedd2e87a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Callable.cs
@@ -72,7 +72,7 @@ namespace Godot
/// <param name="delegate">Delegate method that will be called.</param>
public Callable(Delegate @delegate)
{
- _target = null;
+ _target = @delegate?.Target as Object;
_method = null;
_delegate = @delegate;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
index 140fc167ba..76b186cd15 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/Marshaling.cs
@@ -721,8 +721,9 @@ namespace Godot.NativeInterop
if (p_managed_callable.Delegate != null)
{
var gcHandle = CustomGCHandle.AllocStrong(p_managed_callable.Delegate);
+ IntPtr objectPtr = p_managed_callable.Target != null ? Object.GetPtr(p_managed_callable.Target) : IntPtr.Zero;
NativeFuncs.godotsharp_callable_new_with_delegate(
- GCHandle.ToIntPtr(gcHandle), out godot_callable callable);
+ GCHandle.ToIntPtr(gcHandle), objectPtr, out godot_callable callable);
return callable;
}
else
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
index bd00611383..20ede9f0dd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
@@ -141,7 +141,7 @@ namespace Godot.NativeInterop
public static partial void godotsharp_packed_string_array_add(ref godot_packed_string_array r_dest,
in godot_string p_element);
- public static partial void godotsharp_callable_new_with_delegate(IntPtr p_delegate_handle,
+ public static partial void godotsharp_callable_new_with_delegate(IntPtr p_delegate_handle, IntPtr p_object,
out godot_callable r_callable);
internal static partial godot_bool godotsharp_callable_get_data_for_marshalling(in godot_callable p_callable,
diff --git a/modules/mono/glue/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp
index 276701cdaa..2717b945f6 100644
--- a/modules/mono/glue/runtime_interop.cpp
+++ b/modules/mono/glue/runtime_interop.cpp
@@ -447,9 +447,10 @@ void godotsharp_packed_string_array_add(PackedStringArray *r_dest, const String
r_dest->append(*p_element);
}
-void godotsharp_callable_new_with_delegate(GCHandleIntPtr p_delegate_handle, Callable *r_callable) {
+void godotsharp_callable_new_with_delegate(GCHandleIntPtr p_delegate_handle, const Object *p_object, Callable *r_callable) {
// TODO: Use pooling for ManagedCallable instances.
- CallableCustom *managed_callable = memnew(ManagedCallable(p_delegate_handle));
+ ObjectID objid = p_object ? p_object->get_instance_id() : ObjectID();
+ CallableCustom *managed_callable = memnew(ManagedCallable(p_delegate_handle, objid));
memnew_placement(r_callable, Callable(managed_callable));
}
diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp
index 9305dc645a..0c2c533090 100644
--- a/modules/mono/managed_callable.cpp
+++ b/modules/mono/managed_callable.cpp
@@ -79,7 +79,9 @@ CallableCustom::CompareLessFunc ManagedCallable::get_compare_less_func() const {
}
ObjectID ManagedCallable::get_object() const {
- // TODO: If the delegate target extends Godot.Object, use that instead!
+ if (object_id != ObjectID()) {
+ return object_id;
+ }
return CSharpLanguage::get_singleton()->get_managed_callable_middleman()->get_instance_id();
}
@@ -104,7 +106,7 @@ void ManagedCallable::release_delegate_handle() {
// Why you do this clang-format...
/* clang-format off */
-ManagedCallable::ManagedCallable(GCHandleIntPtr p_delegate_handle) : delegate_handle(p_delegate_handle) {
+ManagedCallable::ManagedCallable(GCHandleIntPtr p_delegate_handle, ObjectID p_object_id) : delegate_handle(p_delegate_handle), object_id(p_object_id) {
#ifdef GD_MONO_HOT_RELOAD
{
MutexLock lock(instances_mutex);
diff --git a/modules/mono/managed_callable.h b/modules/mono/managed_callable.h
index aa3344f4d5..26cd164fb6 100644
--- a/modules/mono/managed_callable.h
+++ b/modules/mono/managed_callable.h
@@ -40,6 +40,7 @@
class ManagedCallable : public CallableCustom {
friend class CSharpLanguage;
GCHandleIntPtr delegate_handle;
+ ObjectID object_id;
#ifdef GD_MONO_HOT_RELOAD
SelfList<ManagedCallable> self_instance = this;
@@ -66,7 +67,7 @@ public:
void release_delegate_handle();
- ManagedCallable(GCHandleIntPtr p_delegate_handle);
+ ManagedCallable(GCHandleIntPtr p_delegate_handle, ObjectID p_object_id);
~ManagedCallable();
};