mirror of
https://github.com/1bardesign/batteries.git
synced 2024-11-22 22:24:35 +00:00
async: Use function to capture ...
Instead of only capturing 8 temps, pass resume to a function so we can capture all returned values as ... I might be missing a reason why you wouldn't do it like this. Test -- coro is an async() updated in love.update coro:call( function() coro.wait(1) print("jump") self.gravity.y = -900 coro.wait(1) print("fall") self.gravity.y = 900 coroutine.yield "hello" return "done" end, nil, function(...) print("complete", ...) end)
This commit is contained in:
parent
f6a18380d4
commit
585ba82e57
59
async.lua
59
async.lua
@ -49,6 +49,35 @@ function async:add(co, args, callback, error_callback)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function process_resume(self, td, success, msg, ...)
|
||||||
|
local co, args, cb, error_cb = unpack(td)
|
||||||
|
--error?
|
||||||
|
if not success then
|
||||||
|
if error_cb then
|
||||||
|
error_cb(msg)
|
||||||
|
else
|
||||||
|
local err = ("failure in async task:\n\n\t%s\n")
|
||||||
|
:format(tostring(msg))
|
||||||
|
error(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--check done
|
||||||
|
if coroutine.status(co) == "dead" then
|
||||||
|
--done? run callback with result
|
||||||
|
if cb then
|
||||||
|
cb(msg, ...)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--if not completed, re-add to the appropriate queue
|
||||||
|
if msg == "stall" then
|
||||||
|
--add to stalled queue as signalled stall
|
||||||
|
table.insert(self.tasks_stalled, td)
|
||||||
|
else
|
||||||
|
table.insert(self.tasks, td)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--update some task in the kernel
|
--update some task in the kernel
|
||||||
function async:update()
|
function async:update()
|
||||||
--grab task definition
|
--grab task definition
|
||||||
@ -65,34 +94,8 @@ function async:update()
|
|||||||
end
|
end
|
||||||
--run a step
|
--run a step
|
||||||
--(using unpack because coroutine is also nyi and it's core to this async model)
|
--(using unpack because coroutine is also nyi and it's core to this async model)
|
||||||
local co, args, cb, error_cb = unpack(td)
|
local co, args = unpack(td)
|
||||||
--(8 temps rather than table churn capturing varargs)
|
process_resume(self, td, coroutine.resume(co, unpack(args)))
|
||||||
local success, a, b, c, d, e, f, g, h = coroutine.resume(co, unpack(args))
|
|
||||||
--error?
|
|
||||||
if not success then
|
|
||||||
if error_cb then
|
|
||||||
error_cb(a)
|
|
||||||
else
|
|
||||||
local err = ("failure in async task:\n\n\t%s\n")
|
|
||||||
:format(tostring(a))
|
|
||||||
error(err)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--check done
|
|
||||||
if coroutine.status(co) == "dead" then
|
|
||||||
--done? run callback with result
|
|
||||||
if cb then
|
|
||||||
cb(a, b, c, d, e, f, g, h)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
--if not completed, re-add to the appropriate queue
|
|
||||||
if a == "stall" then
|
|
||||||
--add to stalled queue as signalled stall
|
|
||||||
table.insert(self.tasks_stalled, td)
|
|
||||||
else
|
|
||||||
table.insert(self.tasks, td)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user