godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.14k stars 93 forks source link

Consider Callables unique when bound with different parameters #4922

Open nathanfranke opened 2 years ago

nathanfranke commented 2 years ago

Describe the project you are working on

https://github.com/godotengine/godot/issues/63038

Describe the problem or limitation you are having in your project

I am binding some signals to the same method with my internal helper class

func _my_setter(value: Variant, object: Object, property: StringName) -> void:
    object.set(property, value)

value is from the emitted changed signal, object and property are passed as binds.

Some signals may be connected to this multiple times, e.g. game_changed may be used in a lot of places. However, trying to connect to the same method with different binds will give an error.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Allowing the same signal to be bound to the same method as long as the method has different binds.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

This should be valid:

func _ready():
    game_changed.connect(_my_setter.bind(one_object, "game"))
    game_changed.connect(_my_setter.bind(another_object, "game"))

If this enhancement will not be used often, can it be worked around with a few lines of script?

Can be worked around by using lambdas. You'll need a dictionary of them if you want to disconnect them later.

Is there a reason why this should be core and not an add-on in the asset library?

Callables are core

koyae commented 8 months ago

The other approach for disconnections would be to use Object's get_signal_connection_list(), and simply disconnect by signal where ["callable"].get_object() == self or similar. This likely has more performance overhead but would save on custom bookkeeping.

koyae commented 8 months ago

If the implementation for differentiating between bind()'d methods would be especially tortured, I'm wondering whether a simpler (alternate) proposal might just be to just introduce a connect_raw() method that skips the duplicate check currently performed in object.cpp, but otherwise behaves the same way?