godotengine / godotengine/godot-docs
Clarify how Callables are compared for equality when disconnecting signals
- 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.