3
0
mirror of https://github.com/britzl/monarch.git synced 2025-09-28 02:22:20 +02:00

Make sure that callbacks aren't invoked more than once

This commit is contained in:
Björn Ritzl
2021-08-19 14:35:05 +02:00
parent 76d4ca2927
commit d3799a93ff
3 changed files with 67 additions and 33 deletions

47
monarch/utils/async.lua Normal file
View File

@@ -0,0 +1,47 @@
local M = {}
local NOT_STARTED = "not_started"
local YIELDED = "yielded"
local RESUMED = "resumed"
local RUNNING = "running"
function M.async(fn)
local co = coroutine.running()
local state = NOT_STARTED
local function await(fn, ...)
state = RUNNING
fn(...)
if state ~= RUNNING then
return
end
state = YIELDED
local r = { coroutine.yield() }
return unpack(r)
end
local function resume(...)
if state ~= RUNNING then
state = RUNNING
local ok, err = coroutine.resume(co, ...)
if not ok then
print(err)
print(debug.traceback())
end
end
end
if co then
return fn(await, resume)
else
co = coroutine.create(fn)
return resume(await, resume)
end
end
return setmetatable(M, {
__call = function(t, ...)
return M.async(...)
end
})

View File

@@ -6,13 +6,18 @@ function M.create()
local callback = nil
local callback_count = 0
local all_callbacks_done = false
local function is_done()
return callback_count == 0
end
local function invoke_if_done()
if all_callbacks_done then
print("Warning: The same callback will be invoked twice from the callback tracker!", id or "")
end
if callback_count == 0 and callback then
all_callbacks_done = true
local ok, err = pcall(callback)
if not ok then print(err) end
end
@@ -41,20 +46,6 @@ function M.create()
invoke_if_done()
end
function instance.yield_until_done()
local co = coroutine.running()
callback = function()
local ok, err = coroutine.resume(co)
if not ok then
print(err)
end
end
invoke_if_done()
if not is_done() then
coroutine.yield()
end
end
return instance
end