lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




Il gio 9 mag 2019, 11:33 pocomane <pocomane_7a@pocomane.com> ha scritto:

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].

...

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 :


My previous example was wrong, so I attach a new simpler one. I hope that it is more readable. The question is still:

Is there some other solution that I can not think of?

I just want to fully stop the lua VM, to process some data outside lua, and then to restart the VM exactly where it did stop. To do this transparently with the proposed code, a lot of auxiliary code is required, e.g. to decide if perform a `nestresume` or a normal one, to handle errors, to wrap the standard coroutine functions, and so on.

```

local function nestresume(nc, ...)

      local res = table.pack(coroutine.resume(nc, ...))

      -- Skip the yield/resume propagation as needed
      if not coroutine.isyieldable() or coroutine.status(nc) ~= 'suspended' then
        return table.unpack(res)
      end

      -- Propagate the yielding upstream
      local res = table.pack(coroutine.yield(table.unpack(res)))

      -- Propagate the resuming downstream
      return nestresume(nc, table.unpack(res)) 
end

-- Usage example:

local outer, inner
local out = ''

outer = coroutine.create(function()
  
  inner = coroutine.create(function()
    out = out .. 'c'
    coroutine.yield()
    out = out .. 'e' -- with std resume, this whould have been skipped
  end)

  out = out .. 'b'
  nestresume(inner)
  out = out .. 'f'
end)

out = out .. 'a'
nestresume(outer)
out = out .. 'd' -- with std resume, this would have been run after 'f'
nestresume(outer) -- with std resume, this was not required

print(out)
assert(out=='abcdef')
```