Topic was automatically imported from the old Question2Answer platform.
Asked By
newbie2356
I am reading the docs, specifically GDScript basics and there is this section about coroutines I am struggling to understand:
If you’re unsure whether a function may yield or not, or whether it may yield multiple times, you can yield to the completed signal conditionally:
I was having a tough time understanding the code so I ran it in godot to see what happened. Because of the pseduorandom nature I modified the code slightly (but I don’t think it changes the example). Here is my code I used:
extends Node
func generate():
var result = rand_range(-1.0, 1.0)
if result < 0.0:
yield(get_tree(), "idle_frame")
return result
func make():
var result = generate()
if result is GDScriptFunctionState: # Still working.
result = yield(result, "completed")
return result
func _ready():
randomize()
print(make())
Here’s what I am struggling to understand:
It’s my understanding that this code is supposed to always return a random number (above 0?). But sometimes I get a random number, sometimes I get a function state.
With this example, I’m not sure how yielding to the completed signal conditionally works.
This is particularly difficult, because I’m not even sure what this part of the documentation is trying to teach.
Sorry for the bad question, but thanks for reading and I hope you can help.
yield is shorthand for connect method. yielddoes not make your code asynchronous and does not stop execution of your function until it is resolved.
Your code will be executed as next code:
extends Node
func generate():
var result = rand_range(-1.0, 1.0)
if result < 0.0:
connect("idle_frame", get_tree(), "generate")
return GDScriptFunctionState
else:
return result
func make():
var result = generate()
if result is GDScriptFunctionState: # Still working.
connect("completed", self, "_on_completed")
return result
func _on_completed():
pass
func _ready():
randomize()
print(make())
Hopefully you will understand why you misunderstand yield usage. If not, here’s example of how your code can be modified to work as expected:
extends Node
func generate(callback):
var result = rand_range(-1.0, 1.0)
while result < 0.0:
yield(get_tree(), "idle_frame")
result = rand_range(-1.0, 1.0)
call(callback, result)
func make():
var result = generate("_on_generated")
func _on_generated(result):
print(result)
func _ready():
randomize()
make()
Unfortunately, you can’t print result in _ready() function, because yield does not return values from coroutines.
Thank you for this explanation. yield being shorthand for connect (and the separate return GDScriptFunctionState) is very enlightening.