-- -- Minetest asyncio: Lua 5.1 workarounds -- local rawequal = rawequal minetest.log('warning', '[asyncio] LuaJIT not installed, asyncio.iter() ' .. 'will be less efficient.') -- Helper functions local function pack_len(...) local res = {...} res.length = select('#', ...) return res end local function unpack_len(t, i) i = i or 1 if i <= t.length then return t[i], unpack_len(t, i + 1) end end -- A workaround for non-LuaJIT Lua 5.1 -- Lua 5.1 does not allow coroutine.yield() inside iterators. function asyncio.iter(func, ...) local iter = asyncio._iter_start(func, ...) -- Fetch all values first local t = {} while true do local msg = pack_len(iter()) if msg[1] == nil then break end table.insert(t, msg) end iter = nil -- Get the values return function() local msg = table.remove(t, 1) if type(msg) == 'table' then return unpack_len(msg) end end end -- A pcall() workaround/hack. local last_error = ... assert(type(last_error) == 'table') local function pcall_hack(func, ...) asyncio.yield(last_error, pack_len(func(...))) end function last_error.cleanup() last_error.msg = nil end local old_pcall = pcall function pcall(func, ...) if not asyncio.running then return old_pcall(func, ...) end local l, msg = asyncio._iter_start(pcall_hack, func, ...)() if l == last_error then return true, unpack_len(msg) elseif l ~= nil then return false, 'asyncio.yield() called outside of async iterator.' end return false, last_error.msg end