Merge pull request #66674 from pkdawson/fix-callable-delegate
Fix C# delegate signal not disconnected when Object is destroyed
This commit is contained in:
commit
abf473e2d0
6 changed files with 13 additions and 8 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue