Skip to content

[Feature] Add signal connection handle #765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
chippmann opened this issue Mar 7, 2025 · 1 comment · Fixed by #803
Open

[Feature] Add signal connection handle #765

chippmann opened this issue Mar 7, 2025 · 1 comment · Fixed by #803

Comments

@chippmann
Copy link
Contributor

chippmann commented Mar 7, 2025

When one connects to a signal using a lambda:

mySignal.connect { arg1, arg2 ->
    // do stuff
}

one receives a godot Error object as a return type from the connect function.

While this allows to check if the connection was successful, one can never disconnect that lambda again from the signal.

After some discussions on discord, we settled on a design which returns a handle for that connect function call. The handle will look something like this:

Note: names not final and subject to change. Probably they will be called Connector or similar

class SignalHandle(
    private val signal: Signal,
    private val callable: Callable,
) {
    fun connect(flags: Int = 0): Error = signal.connect(callable, flags)
    fun disconnect(): Unit = signal.disconnect(callable)
    fun isConnected(): Boolean = signal.isConnected(callable)
    fun isNull(): Boolean = signal.isNull()
}

The connect call taking in the lambda will then return such a handle which allows to later disconnect and reconnect the lambda at will while still retaining the fire and forget (or better setup and forget) way of working which we have today and is quite easy to use:

// setup and forget:
mySignal.connect { arg1, arg2 -> }

// ---

// using handle:
val handle = mySignal.connect { arg1, arg2 -> }

// later
if (handle.isConnected()) {
    handle.disconnect()
}

// later
handle.connect()

// later
handle.disconnect()

The generated code would look like something this:

public inline fun <reified P0> Signal1<P0>.connect(flags: Int = 0, noinline method: (p0: P0) -> Unit): SignalHandle = SignalHandle(
    signal = this,
    callable = method.asCallable(),
).also { it.connect(flags) }

This would ideally be implemented after #760 to take advantage of the api gen's new design.

@chippmann
Copy link
Contributor Author

This also requires proper memory management to be implemented for custom callables, as currently we create a new wrapper each time we send a callable to gdscript. So from the cpp point of view, the callable is a different one when we call disconnect

@CedNaru CedNaru changed the title [Feature] Add singal connection handle [Feature] Add signal connection handle Mar 28, 2025
@CedNaru CedNaru linked a pull request Apr 29, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants