mirror of
https://github.com/1bardesign/batteries.git
synced 2024-11-22 06:04:35 +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
|
return a
|
||||||
end
|
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
|
--replace everything in assert with nop functions that just return their second argument, for near-zero overhead on release
|
||||||
function assert:nop()
|
function assert:nop()
|
||||||
local nop = function(_, a)
|
local nop = function(_, a)
|
||||||
|
34
async.lua
34
async.lua
@ -16,6 +16,7 @@
|
|||||||
]]
|
]]
|
||||||
|
|
||||||
local path = (...):gsub("async", "")
|
local path = (...):gsub("async", "")
|
||||||
|
local assert = require(path .. "assert")
|
||||||
local class = require(path .. "class")
|
local class = require(path .. "class")
|
||||||
|
|
||||||
local async = class({
|
local async = class({
|
||||||
@ -27,16 +28,33 @@ function async:new()
|
|||||||
self.tasks_stalled = {}
|
self.tasks_stalled = {}
|
||||||
end
|
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
|
--add a task to the kernel
|
||||||
function async:call(f, args, callback, error_callback)
|
function async:call(f, args, callback, error_callback)
|
||||||
self:add(coroutine.create(function(...)
|
assert:type_or_nil(args, "table", "async:call - args", 1)
|
||||||
local results = {xpcall(f, debug.traceback, ...)}
|
f = capture_callstacks(f)
|
||||||
local success = table.remove(results, 1)
|
self:add(coroutine.create(f), args, callback, error_callback)
|
||||||
if not success then
|
|
||||||
error(table.remove(results, 1))
|
|
||||||
end
|
|
||||||
return unpack(results)
|
|
||||||
end), args, callback, error_callback)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--add an already-existing coroutine to the kernel
|
--add an already-existing coroutine to the kernel
|
||||||
|
Loading…
Reference in New Issue
Block a user