Skip to content

Instantly share code, notes, and snippets.

@CapsAdmin
Created December 28, 2018 23:45
Show Gist options
  • Save CapsAdmin/d931d9b062ea90087a93ae6719817423 to your computer and use it in GitHub Desktop.
Save CapsAdmin/d931d9b062ea90087a93ae6719817423 to your computer and use it in GitHub Desktop.
local callback = {}
do
local meta = {}
meta.__index = meta
meta.Type = "callback"
function meta:__tostring()
return string.format("callback: %p", self)
end
function meta:Start()
self:on_start()
return self
end
function meta:Resolve(...)
for _, cb in ipairs(self.resolved) do
local ok, err = pcall(cb, ...)
if not ok then
return self:Reject(err)
end
end
self.is_resolved = true
return self
end
function meta:Reject(...)
if not self.rejected[1] then
logn(self, " unhandled promise reject: ", ...)
end
for _, cb in ipairs(self.rejected) do
cb(...)
end
return self
end
function meta:Resolved(callback)
table.insert(self.resolved, callback)
return self
end
function meta:Rejected(callback)
table.insert(self.rejected, callback)
return self
end
function meta:Subscribe(what, callback)
self.other[what] = self.other[what] or {}
table.insert(self.other[what], callback)
return self
end
local function on_index(t, key)
local self = t.self
return function(...)
if key == "resolve" then
return self:Resolve(...)
elseif key == "reject" then
return self:Reject(...)
elseif self.other[key] then
for _, cb in ipairs(self.other[key]) do
local ok, err = pcall(cb, ...)
if not ok then
return self:Reject(err)
end
end
end
end
end
function callback.Create(on_start)
local self = setmetatable({}, meta)
self.on_start = on_start
self.resolved = {}
self.rejected = {}
self.other = {}
self.callbacks = setmetatable({self = self}, {__index = on_index})
return self
end
end
function callback.WrapKeyedTask(create_callback)
local callbacks = {}
return function(key, ...)
local args = {...}
if not callbacks[key] or callbacks[key].is_resolved then
callbacks[key] = callback.Create(function(self)
create_callback(self, key, unpack(args))
end)
callbacks[key]:Start()
end
return callbacks[key]
end
end
function callback.WrapTask(create_callback)
return function(...)
local args = {...}
local cb = callback.Create(function(self)
create_callback(self, unpack(args))
end)
cb:Start()
return cb
end
end
return callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment