ManagedCallable: use delegate target instead of middleman when possible
If the delegate target is an Object, the connected signal will be registered in that object instead of the middleman. So when that object is destroyed, the signal will be properly disconnected.
This commit is contained in:
parent
e69b7083d4
commit
161f295f52
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