godotengine / godotengine/godot-docs

Clarify how Callables are compared for equality when disconnecting signals

Open
#8,071 0 comments 16 reactions 0 assignees View on GitHub
enhancement
Dominant language
reStructuredText
Stars
5.7k
Forks
3.8k
Avg merge
1d 20h
Merged PRs (30d)
25

Description

**Your Godot version:**

v4.1.1.stable.official [bd6af8e0e]

**Issue description:**

[Signal.disconnect](https://docs.godotengine.org/en/stable/classes/class_signal.html#class-signal-method-disconnect) has this to say:

> Disconnects this signal from the specified [Callable](https://docs.godotengine.org/en/stable/classes/class_callable.html#class-callable). If the connection does not exist, generates an error. Use [is_connected](https://docs.godotengine.org/en/stable/classes/class_signal.html#class-signal-method-is-connected) to make sure that the connection exists.

Back in Godot 3, this was pretty self-explanatory: A connection was defined as the 2-tuple containing the object we're targeting and the name (as a string) of the method *on* that object.

But now we're in Godot 4. And `Callable`s can be more complex. They can be methods on objects, or lambdas, or bound versions of other callables. And from cursory experimentation, as well as looking at the source code for the current version of Godot, comparison on `Callable`s is nontrivial. For instance, this works:

```
my_signal.connect(foobar.bind(0))
my_signal.disconnect(foobar.bind(1))
```

Despite the bound value being different, `disconnect` still recognizes that the callable we asked it to disconnect compares equal to the callable that actually exists in the signal's connections. I don't consider this a bug in the engine, as (from the looks of the Godot source code) there's some normalization happening before `disconnect` compares the callables for equality, and one of those normalization steps (`get_base_comparator`) removes bindings.

But this doesn't appear to be documented anywhere. The equivalence relation being used should be documented either in `disconnect` or in the description of the [`Callable` class](https://docs.godotengine.org/en/stable/classes/class_callable.html) itself.

Suggested phrasing (please verify this for correctness, as I was not the one to write this function and do not claim to know everything about it):

> Disconnects a signal from a given callable. If the connection does not exist, generates an error. Use is_connected to make sure that the connection exists.
>
> Callables are compared by their target object and target method name. Additional bindings are ignored for the purposes of this comparison. Two lambdas only compare equal if they are the same object by object identity.

**URL to the documentation page (if already existing):**

* https://docs.godotengine.org/en/stable/classes/class_signal.html#class-signal-method-disconnect
* https://docs.godotengine.org/en/stable/classes/class_callable.html

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.