From 585ba82e57919bca8a521ae57c77ad76c8c0e36a Mon Sep 17 00:00:00 2001 From: David Briscoe Date: Wed, 2 Mar 2022 08:10:56 -0800 Subject: [PATCH] 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) --- async.lua | 59 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/async.lua b/async.lua index 4ebc376..779b3b6 100644 --- a/async.lua +++ b/async.lua @@ -49,6 +49,35 @@ function async:add(co, args, callback, error_callback) }) 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 function async:update() --grab task definition @@ -65,34 +94,8 @@ function async:update() end --run a step --(using unpack because coroutine is also nyi and it's core to this async model) - local co, args, cb, error_cb = unpack(td) - --(8 temps rather than table churn capturing varargs) - 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 + local co, args = unpack(td) + process_resume(self, td, coroutine.resume(co, unpack(args))) return true end