If you or a loved one has ever struggled with trying to await a signal or a timeout, worry no more!
Here’s a solution:
func with_timeout(sig, timeout):
var dummy_obj = Object.new()
dummy_obj.add_user_signal("result")
var sig_first = func(): dummy_obj.emit_signal("result", [false])
var timeout_first = func(...sig_result): dummy_obj.emit_signal("result", [true, sig_result])
get_tree().create_timer(timeout).timeout.connect(timeout_first)
sig.connect(sig_first)
var dummy_signal = Signal(dummy_obj, "result")
var result = await dummy_signal
return result
What this does is create a temporary, locally scoped signal, and outputs true or false depending on which signal calls the local signal first (and possibly returns the result of that signal, if it’s not the timeout).
I couldn’t find anything like this anywhere else, so I thought I’d post this here in case Godot never implements something like this.