Support the yielding pattern without tons of setup

There exists a common flow control pattern that can’t be performed with pure roblox lua/luau right now: yielding the current thread and resuming it from another thread. The only way to perform this is with an Instance, typically a BindableEvent.

For example:

-- 1st
local value = bindableEvent.Event:Wait() -- yield to firer
-- 3rd
-- 2nd
bindableEvent:Fire(value) -- spawn waiter
-- 4th

You could also wrap every thread in a coroutine, but that is kind of insane because you’d have to do that everywhere you spawn a thread.

I see two possible changes that could make this doable without ridiculous formatting rules or roblox instances.

  1. Every thread is a coroutine by default - coroutine.running() returns it. Users can accomplish this yielding pattern by storing the thread’s coroutine, yielding, and then simply resuming it later.
  2. A native event type that doesn’t require BindableEvents to function. Essentially just a subtype of RBXScriptSignal with a Fire method. This is a direct replacement for the BindableEvent solution.
8 Likes

I am a little confused about what exactly it is you are trying to accomplish. You can already retrieve a reference to any thread by calling coroutine.running and resume it later with coroutine.resume, task.spawn, task.defer or task.delay.

The example you gave can be replaced with the following:

-- 1st
thread = coroutine.running()
coroutine.yield()
-- 3rd
-- 2nd
coroutine.resume(thread)
-- 4th
5 Likes

Is this guaranteed? In vanilla Lua coroutine.running can return nil. If this is not the case it should be specified in documentation.

The documentation in 5.1 for coroutine.yield states:

Returns the running coroutine, or nil when called by the main thread.

It only returns nil when called by the main thread. This doesn’t matter in Roblox because the main thread is not exposed to scripts.

The main thread can also never yield in any case, so if coroutine.running returns nil then coroutine.yield will always error. Calling Wait will also yield, so it will always error when called from the main thread.

1 Like

In stock Lua you can’t get a reference to the main thread with coroutine.running but since we don’t expose the main thread you are essentially guaranteed to always get a reference.

1 Like

Luau docs have a special note on this in coroutine.running documentation: Library - Luau

Luau (being an embeddable language) doesn’t guarantee that the main thread will never be used to run code, but both in Roblox and in Luau Repl main thread is never used to execute code (e.g. try print(coroutine.running()) on Demo - Luau – so in practice you can rely on coroutine.running.

4 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.