bakpakin / corope

Lua threading utility using coroutines.
MIT License
29 stars 2 forks source link

'rope function called outside of dispatch function or inside coroutine' when using rope:parallel #2

Open propapanda opened 6 years ago

propapanda commented 6 years ago

I can't seem to get the rope:parallel function to work. Everything I've tried results in the following error:

Error: corope.lua:328: rope function called outside of dispatch function or inside coroutine
stack traceback:
  [C]: in function 'error'
  tests/utils/corope.lua:157: in function 'checkCorrectCoroutine'
  tests/utils/corope.lua:296: in function 'signal'
  tests/utils/corope.lua:328: in function 'errhand'
  tests/utils/corope.lua:106: in function 'update'
  tests/coropetest.lua:6: in function 'update'
  [string "boot.lua"]:464: in function <[string "boot.lua"]:436>
  [C]: in function 'xpcall'

My simple function call for testing looks like this:

bundle(function(rope)
    rope:parallel(
        function()
            print "First"
            rope:wait(0.5)
        end,
        function()
            print "Second"
            rope:wait(1.5)
        end
    )
    print "Last"
end)

Going by the documentation, I would expect it to output:

First
Second
Last

Instead it throws the error message shown above.

Would it be possible to get an example showing how the Parallel function is meant to be used?

bakpakin commented 6 years ago

I have taken a look at your code and added an example in the examples folder. There was a slight problem with the parallel function which I have fixed.

In parallel, each of the functions that runs gets its own new rope, which use should use to control the timing.

bundle(function(rope)
    rope:parallel(
        function(ropea)
            print "First"
            -- Don't do rope:wait(0.5)
            ropea:wait(0.5)
        end,
        function(ropeb)
            print "Second"
            -- Don't do rope:wait(1.5)
            ropeb:wait(1.5)
        end
    )
    print "Last"
end)

While Lua coroutines are powerful, there are some limitations in jumping between them. One can only manipulate a rope within a single coroutine (there is a 1 to 1 correspondence with coroutines and ropes). When trying to wait on the original rope inside the parallel function, you are in a different coroutine (the one corresponds to ropea or ropeb). Fortunately, we can create as many ropes as we want and wait on those ropes.