214 posts
Location
/home/marcus/
Posted 14 May 2015 - 10:34 PM
I'm having technical difficulties with coroutines. Somehow ddm ends without errors (the while-true broke somehow, or idk)
Le' code:
ddm -
http://pastebin.com/BLnEZa8Jsand(box) -
http://pastebin.com/KFLmtidqtest
Spoiler
os.loadAPI("sand")
local sandenv = {}
sandenv.env = sandenv
sandenv.k = function(t) for k,v in pairs(t) do write(k..", ") print(v) end end
local deskman, err = loadfile("ddm")
if not deskman then error(err) end
local sandbox = sand.new(deskman, sandenv)
sandenv.box = sandbox
sandbox.run()
local ok, ejj
while sandbox.running() do
ok, ejj = sandbox.unyield()
if not ok then error(ejj) end
end
if not ok then error(ejj) end
print(tostring(ok) .. ", " .. tostring(ejj))
error(ejj)
Usage:
Spoiler
run test, click the bottom-right corner of the gray bar until the cursor pops up (hart to notice), type in "rom/programs/lua" (without quotes of course), and see the weirdness happen.Also, running "test" in a pcall returns "false, nil" :blink:/>
Edited on 14 May 2015 - 08:44 PM
2427 posts
Location
UK
Posted 14 May 2015 - 10:59 PM
Liking this tutorial is the best I can do:
https://docs.google.com/document/d/1UU-bSCgLqwAQixldXmDzvEFPACaieph3qs08WreQlZs/editMy only other suggestion is to dig into the parallel API's code.
Mentioning the
parallel API, in most cases it can do what people need when using multiple coroutines, have a look if it will do what you want to do.
3057 posts
Location
United States of America
Posted 14 May 2015 - 11:11 PM
You're not passing anything to sandbox.unyield(), which in turn passes nothing to coroutine.yield, dropping any filters the code you're running gives you.
For example,
os.pullEvent( "char" )
Will not only pull char events (running in your coroutine), but anything else (such as mouse_click).
I'm not sure this is the cause, but you may want to check it out.
7083 posts
Location
Tasmania (AU)
Posted 15 May 2015 - 02:03 AM
A while back I scribbled out an example of the process KoGY describes; here's an attempt to make it more clear:
local function myFunc(myArg)
for i = 1, myArg do
print(i)
sleep(1)
end
end
-- From bios.lua, we have the source of sleep:
-- function sleep( nTime )
-- local timer = os.startTimer( nTime or 0 )
-- repeat
-- local sEvent, param = os.pullEvent( "timer" )
-- until param == timer
-- end
-- ... and the source of os.pullEvent():
-- function os.pullEvent( sFilter )
-- local eventData = { os.pullEventRaw( sFilter ) }
-- if eventData[1] == "terminate" then
-- error( "Terminated", 0 )
-- end
-- return table.unpack( eventData )
-- end
-- ... and the source of os.pullEventRaw():
-- function os.pullEventRaw( sFilter )
-- return coroutine.yield( sFilter )
-- end
-- So, os.pullEvent( "timer" ) == coroutine.yield( "timer" ), but errors if a terminate event is returned instead.
-- Now let's run myFunc as a coroutine:
-- Initialise coroutine:
print("Starting coroutine!")
local myCoroutine = coroutine.create(myFunc)
local ok, requestedEvent = coroutine.resume(myCoroutine, 10) -- Being the first resume, 10 gets pushed to myArg.
-- Run coroutine to completion:
while coroutine.status(myCoroutine) ~= "dead" do
print("Coroutine seems ok, and is asking for a \"" .. requestedEvent .. "\" event.") -- With the example myFunc, "requestedEvent" will always be "timer".
local myEvent = {os.pullEvent(requestedEvent)}
ok, requestedEvent = coroutine.resume(myCoroutine, unpack(myEvent)) -- Parameters of later resumes are returned by coroutine.yield() (and hence os.pullEvent()) within the coroutine itself.
end
-- Coroutine has finished execution.
if ok then
print("Coroutine has completed in a natural manner.")
else
print("Coroutine errored!: " .. requestedEvent)
end