Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
lua-nucleo/lua-nucleo/coro.lua
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
62 lines (51 sloc)
1.62 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -------------------------------------------------------------------------------- | |
| --- Coroutine module extensions | |
| -- @module lua-nucleo.coro | |
| -- This file is a part of lua-nucleo library | |
| -- @copyright lua-nucleo authors (see file `COPYRIGHT` for the license) | |
| -------------------------------------------------------------------------------- | |
| -- Supports yielding from inner to outer coroutine across nested coroutines. | |
| -- Depends on built-in Lua coroutine module. | |
| -- Also provides yield_outer-compliant pcall function. | |
| -- See basic test for example. | |
| -- TODO: Try to provide xpcall as well. | |
| local setmetatable = setmetatable | |
| local coroutine = coroutine | |
| local coroutine_create, coroutine_resume, coroutine_yield = | |
| coroutine.create, coroutine.resume, coroutine.yield | |
| -- Should be newproxy() | |
| local outer_yield_tag = function() end | |
| local function maybe_forward_yield(co, status, tag, ...) | |
| if status == true and tag == outer_yield_tag then | |
| return maybe_forward_yield( | |
| co, | |
| coroutine_resume( | |
| co, | |
| coroutine_yield(tag, ...) | |
| ) | |
| ) | |
| end | |
| return status, tag, ... | |
| end | |
| local resume_inner = function(co, ...) | |
| return maybe_forward_yield(co, coroutine_resume(co, ...)) | |
| end | |
| local yield_outer = function(...) | |
| return coroutine_yield(outer_yield_tag, ...) | |
| end | |
| local is_outer_yield_tag = function(v) | |
| return v == outer_yield_tag | |
| end | |
| local eat_tag = function(status, v, ...) | |
| if v == outer_yield_tag then | |
| return status, ... | |
| end | |
| return status, v, ... | |
| end | |
| return | |
| { | |
| resume_inner = resume_inner; | |
| yield_outer = yield_outer; | |
| is_outer_yield_tag = is_outer_yield_tag; | |
| eat_tag = eat_tag; | |
| } |