godotengine / godot-headers

Headers for the Godot API supplied by the GDNative module.
MIT License
381 stars 91 forks source link

Missing yield. #78

Closed ghost closed 3 years ago

ghost commented 4 years ago

yield is Missing.

Calinou commented 4 years ago

yield() is a GDScript concept. It can't be used as-is in Godot's C++ code nor in GDNative C/C++.

(Also, yield() will be removed in favor of the await keyword in Godot 4.0.)

ghost commented 4 years ago

So, what can we do to tell godot to ignore us for one frame and then comeback to finish the function?

fire commented 4 years ago

Timers can be used for that but the time might not exactly be the next frame. There's also call deferred.

ghost commented 4 years ago

not as efficient as yieldor await. and call deferredcan't be done in a function.

bojidar-bg commented 4 years ago

C does not have the concept of "coroutine" necessary to implement await or yield. The closest thing you can do is subscribe a method to a signal manually.

Example GDScript code (as I haven't used GDNative enough to suggest proper GDNative code):

## Original code:
func test():
    var a = 4
    print(a)
    yield(get_tree().create_timer(50), "timeout") # This example is with create_timer, but it can be trivially modified to use yield(get_tree(), "idle_frame") instead.
    print(a + 1)

## Becomes:
func test():
    var a = 4
    print(a)
    var timer = get_tree().create_timer(50)
    timer.connect("timeout", self, "_test_cont", [a, timer]) # It is important to pass the timer as a parameter to the other method, as otherwise exiting the test() function will get its reference count down to 0

func _test_cont(a, _timer):
    print(a + 1)

(Note that Godot 4.0 mightly allow for connecting to a function pointer directly instead of having to bind an extra function for each resumption point)

C++20 does have coroutines, as do D and Rust. Requests for supporting yielding/awaiting to a signal in those languages should be opened on the respective bindings repository.

vnen commented 3 years ago

yield is a language-specific concept and this repository is language-agnostic (it's only a partial copy of Godot source to be easily used as a submodule).