I am playing with the lua vm in the browser [1]. Both browser and lua have a collaborative multitasking design, so I would like to use coroutine for the interaction.
The whole lua script is wrapped in a coroutine, and the browser resume it until it goes to the 'dead' state. Ideally I can wrap browser actions in some lua function that yields. On the _javascript_ side there will be something that parses the yielded values.
This does not works when the "Browser interaction api" is called from a sub-coroutine created in the lua code. Or, at least, I need to propagate the "Yielding" to the parent coroutine, and the "Resuming" to the child one [2].
Obviously, to make this 'Deep yielding/resuming' as much transparent as possible, I have to replace coroutine.resume and friends. So I ask:
Am I missing something? Is there some simpler solution?
It seems to me a quite natural scenario for a coroutine, also in a non-browser environment...
pocomane
[2] I.e. I need something like the follolwing prototype code :
```
-- Nested Coroutine
local THREAD = 1
local SUCCESS = 2
local TARGET = 3
local PARENT = 4
local nccurrent = nil
local function nccreate(f)
local nc = {0,0,0,0}
nc[THREAD] = coroutine.create(f)
return nc
end
local function ncyield(nc, ...)
nc[TARGET] = nc[THREAD]
return coroutine.yield(nc, ...)
end
local function ncresume(nc, ...)
nc[PARENT] = nccurrent
nccurrent = nc
return (function(a, b, ...)
nc[SUCCESS] = a
if coroutine.status(nc[THREAD]) ~= 'suspended' then
return b, ...
end
if nc == b then
b = nil
end
nc[TARGET] = b
if nc[PARENT] == nil then
return b, ...
else
return coroutine.yield(b, ...)
end
end)(coroutine.resume(nc[THREAD], ...))
end
``
Usage example:
```
local top, middle, bottom
local out = ''
out = out .. 'a'
top = nccreate(function()
out = out .. 'b'
middle = nccreate(function()
out = out .. 'c'
bottom = nccreate(function()
out = out .. 'd'
ncyield(middle)
out = out .. '-UNREACHED-'
end)
ncresume(bottom)
out = out .. '-UNREACHED-'
end)
ncresume(middle)
out = out .. 'f'
end)
ncresume(top)
out = out .. 'e'
ncresume(top)
assert(out=='abcdef')
```
A production code should handle several cases (e.g. errors) and I am a bit unsure about its performance.