You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add ability to suspend threads until a signal is called
For GDScript users that run code on threads, it often happens they want to `await` until something happens,
the continue the thread execution.
Unfortunately, signals will most likely execute on the main thread, hence this means that the code being run on
the thread will continue running on the main thread by default.
It has been discussed whether await should be smart about this and simply suspend the
thread if running on one. The problem with this is, that users may also be willing to
emit the signal that will resume from the thread itself and, at the time of awaiting,
there is **no way for the interpreter to know on which thread the function will be resumed**.
Additionally, suspending the thread is a very different operation than awaiting. Awaiting saves the local
function stack and returns immediately, while suspending stops the whole thread until another resumes it.
Mixing and matching both seems, ultimately, undesired as they are not the same.
To solve this, a new utility function is added by this pull request, which
suspends a thread until a signal is emitted (no matter in which other thread).
It works like this.
```GDScript
# Suspends a thread until a button is pressed.
Thread.suspend( button.pressed )
```
If code must do this and can run on both the main thread or a dedicated thread,
it can do as follows:
```GDScript
# Suspends a thread until a button is pressed.
if (Thread.is_main_thread()):
await button.pressed
else:
Thread.suspend( button.pressed )
```
For this, the `Thread.is_main_thread()` function (already existing in the internal Thread object)
has been exposed to the engine API.
**Q**: Are you sure this can't be done with await transparently?
**A**: No, please read again. There is no way for await to know beforehand how the function will be resumed. Only the user knows.
**Q**: Does it not make more sense to have an `await_thread` or something where the user will pass the argument?
**A**: I think its better to have a dedicated utility function for this. Not only the intention is more explicit, but additionally, as this makes it non exclusive to GDScript. It can be used from other languages that use the engine.
if (warn_on_cross_thread_await && await_id != Thread::get_caller_id()) {
196
+
WARN_PRINT("Function " + function->get_name() + " was resumed on a different thread than it was awaited. If you really intend to do this, Use Thread.suspend() for cross thread suspension or disable the 'warn_on_cross_thread_await' warning on project settings.");
0 commit comments