|
|
|
 |
Reply From: |
avencherus |
They should be disconnected automatically.
What is probably happening in your case is that the signal is firing before the Node is finished being freed. queue_free()
is deferred and usually happens a frame later or at least after everything has processed in the current frame.
This allows it to safely finish some things, but if you have a signal firing before the Node is gone, you’ll have some timing issues.
I’ve had a lot of timing issues with the core Node events, notifications, and signals. There are usually ways to account for them with extra care, but they’re not immediately obvious, and can take a lot of debugging.
That said, I’ve found that code to be too difficult to maintain in practice, and generally use the entry and exit points of Godot in very few things. I’ve resorted to my own methods for initialization and cleaning up nodes. When doing this I can quickly review when and what exactly happens.
With queue_free()
I would have the game invoke a custom clean up method to have more control. For an enemy it would play all its death effects, then hide itself and do all the immediate work needed to get the Node in the right state. It may even involve delays or timers. Lastly, it would kick off something like queue_free()
when it is truly being disregarded.
In many cases its nothing more than queue_free()
, but I have at least the option to go back and expand that when issues like these get introduced if changes are made later.
You may also still have to be dealing with disconnecting a lot of signals. If this is the case, and you have a common set of signals you can usually loop through lists and disconnect things using the information found in get_signal_list()
and get_signal_connection_list()
. It’s generally a lot less code, and in many cases very re-usable.
Thanks!
The problem was (as you deduced!) due to a signal firing in the same frame after queue_free()
. I wonder if I could have fixed my original bug with appropriate use of call_deferred()
to delay the offending signal? I.e.,…
signaling_node.connect("signal", responding_node, "bug_function")
responding_node.queue_free()
signaling_node.call_deferred("emit_signal", "signal")
…is it guaranteed in such code that bug_function will never be called?
If not, then I’ll take your advice and make a general solution using signal lists.
Charlie | 2019-01-02 21:04
They should be disconnected automatically.
Is this mentioned in the documentation or elsewhere? I could not find a reference for it.