yield() inside while loop does not work ?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sparks
:warning: Old Version Published before Godot 3 was released.

Hello,

var func_var
var map_finished = false
    
func _ready():
   set_process(true)
   func_var = generate_map()

func _process(delta):
   if not map_finished:
      func_var.resume()

func generate_map():
   while true:
      # map generation code 
      yield()

This causes the following error on my end:

Condition ‘function’ is true. returned: Variant()

The function will not resume. I guess I have not understand entirely how Coroutines work in Godot.

:bust_in_silhouette: Reply From: volzhs

yield() needs 2 parameters.

yield(get_tree(), "idle_frame")

GDFunctionState yield( Object object, String signal )

Stop the function execution and return the current state. Call
GDFunctionState.resume() on the state to resume execution. This
invalidates the state.

Returns anything that was passed to the resume function call. If
passed an object and a signal, the execution is resumed when the
object’s signal is emmited.

I’m confused. In the documentation are also yield() use cases without parameters?

GDScript reference — Godot Engine (stable) documentation in English

sparks | 2017-04-25 13:55

:bust_in_silhouette: Reply From: iron_weasel

Had the same problem today. The thing you are missing is that yield() returns a GDFunctionState and every time resume() is called on the GDFunctionState the state is destroyed.

In your first example the first time yield is called you are saving the state in func_var. But the second time yield is called after the .resume you aren’t saving the result.

My change bellow would fix this I believe.

var func_var
var map_finished = false

func _ready():
   set_process(true)
   func_var = generate_map()

func _process(delta):
   if not map_finished:
      func_var = func_var.resume()

func generate_map():
   while true:
      # map generation code 
      yield()