mirror of
https://github.com/1bardesign/batteries.git
synced 2024-11-10 02:31:48 +00:00
Merge pull request #53 from idbrii/fix-async-lovejs
async: Skip wrapping with xpcall under lovejs
This commit is contained in:
commit
b6ca4c7740
@ -73,6 +73,15 @@ function assert:type(a, t, msg, stack_level)
|
||||
return a
|
||||
end
|
||||
|
||||
--assert a value is nil or a certain type.
|
||||
-- useful for optional parameters.
|
||||
function assert:type_or_nil(a, t, msg, stack_level)
|
||||
if a ~= nil then
|
||||
assert:type(a, t, msg, stack_level + 1)
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
--replace everything in assert with nop functions that just return their second argument, for near-zero overhead on release
|
||||
function assert:nop()
|
||||
local nop = function(_, a)
|
||||
|
34
async.lua
34
async.lua
@ -16,6 +16,7 @@
|
||||
]]
|
||||
|
||||
local path = (...):gsub("async", "")
|
||||
local assert = require(path .. "assert")
|
||||
local class = require(path .. "class")
|
||||
|
||||
local async = class({
|
||||
@ -27,16 +28,33 @@ function async:new()
|
||||
self.tasks_stalled = {}
|
||||
end
|
||||
|
||||
local capture_callstacks
|
||||
if love.system.getOS() == 'Web' then
|
||||
-- Do no extra wrapping under lovejs because using xpcall causes "attempt
|
||||
-- to yield across metamethod/C-call boundary"
|
||||
capture_callstacks = function(f)
|
||||
return f
|
||||
end
|
||||
else
|
||||
capture_callstacks = function(f)
|
||||
-- Report errors with the coroutine's callstack instead of one coming
|
||||
-- from async:update.
|
||||
return function(...)
|
||||
local results = {xpcall(f, debug.traceback, ...)}
|
||||
local success = table.remove(results, 1)
|
||||
if not success then
|
||||
error(table.remove(results, 1))
|
||||
end
|
||||
return unpack(results)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--add a task to the kernel
|
||||
function async:call(f, args, callback, error_callback)
|
||||
self:add(coroutine.create(function(...)
|
||||
local results = {xpcall(f, debug.traceback, ...)}
|
||||
local success = table.remove(results, 1)
|
||||
if not success then
|
||||
error(table.remove(results, 1))
|
||||
end
|
||||
return unpack(results)
|
||||
end), args, callback, error_callback)
|
||||
assert:type_or_nil(args, "table", "async:call - args", 1)
|
||||
f = capture_callstacks(f)
|
||||
self:add(coroutine.create(f), args, callback, error_callback)
|
||||
end
|
||||
|
||||
--add an already-existing coroutine to the kernel
|
||||
|
Loading…
Reference in New Issue
Block a user