Coroutine

From ComputerCraft
Jump to: navigation, search

A coroutine (referred to in code as a thread) is a representation of a function paused in the middle of execution. Coroutines contain everything needed to pause and subsequently resume execution of a function, including the statement being executed, the complete call stack, and the values of local variables.

Unlike threads in other languages, coroutines are never scheduled implicitly—they must be handled explicitly, for instance, by using the Parallel API.

Basic Usage

Unlike all other Lua types, there are no coroutine literals: they must be created and manipulated using functions of the Coroutine API. A coroutine can be created from a function by using coroutine.create.

local c = coroutine.create(function()
  print("foo")
  coroutine.yield()
  print("bar")
end)

After creation, a coroutine may be resumed several times, as long as its status is not dead (see coroutine.status). Note that a coroutine does not start executing until it is resumed for the first time!

print(coroutine.status(c)) -- suspended
coroutine.resume(c) -- prints "foo"

The function coroutine.resume transfers control to a coroutine, and only returns when the coroutine chooses to transfer control back by calling coroutine.yield.

After the function returns, it may not be resumed again, and there is no way to restart it.

coroutine.resume(c) -- prints "bar"
print(coroutine.status(c)) -- dead
assert(coroutine.resume(c))
-- errors with "cannot resume dead coroutine"

Communicating with Coroutines

The coroutine.yield and coroutine.resume functions can be used to transfer values back-and-forth between a running coroutine and its parent, by yielding and resuming with values.

The arguments given to coroutine.resume will be returned from coroutine.yield, and vice-versa. Since the first resume corresponds to starting the function, the first set of values passed to coroutine.resume are used for the function's arguments.

local c = coroutine.create(function(x)
  print(x)
  local y = coroutine.yield(123)
  print(y)
end)

local ok, value = coroutine.resume(c, "foo") -- prints "foo"
print(value) -- 123
coroutine.resume(c, "bar") -- prints "bar"

If execution of the coroutine was aborted due to the error function being called, coroutine.resume will return false along with the error message.

local c = coroutine.create(function(x)
  error("no coroutine for you!")
end
local ok, err = coroutine.resume(c)
print(ok) -- false