Files
aux-addon-ClassicAPI/control.lua
T
Manuel Simon Hirsig 84dc74b5bc refactoring
2016-08-02 14:41:13 +02:00

135 lines
2.7 KiB
Lua

local m, public, private = Aux.module'control'
private.event_frame = CreateFrame('Frame')
private.event_listeners = {}
private.threads = {}
public.thread_id = nil
function public.LOAD()
m.event_frame:SetScript('OnUpdate', m.on_update)
m.event_frame:SetScript('OnEvent', m.on_event)
end
function private.on_event()
for _, listener in m.event_listeners do
if event == listener.event and not listener.deleted then
listener.action()
end
end
end
function private.on_update()
m.event_listeners = Aux.util.filter(m.event_listeners, function(l) return not l.deleted end)
local threads = {}
for thread_id, thread in m.threads do
if not thread.killed then
threads[thread_id] = thread
end
end
m.threads = threads
for thread_id, thread in m.threads do
if not thread.killed then
local k = thread.k
thread.k = nil
m.thread_id = thread_id
k()
m.thread_id = nil
if not thread.k then
thread.killed = true
end
end
end
end
function public.event_listener(event, action)
local self = {}
local listener = { event=event, action=action }
function self:set_action(action)
listener.action = action
end
function self:start()
tinsert(m.event_listeners, listener)
m.event_frame:RegisterEvent(event)
return self
end
function self:stop()
listener.deleted = true
if not Aux.util.any(m.event_listeners, function(l) return l.event == event end) then
m.event_frame:UnregisterEvent(event)
end
return self
end
return self
end
function public.on_next_event(event, callback)
local listener = m.event_listener(event)
listener:set_action(function()
listener:stop()
return callback()
end)
listener:start()
end
function public.on_next_update(callback)
return m.new_thread(callback)
end
function public.as_soon_as(p, callback)
return m.new_thread(m.when, p, callback)
end
function public.new_thread(k, ...)
local thread_id = Aux.unique()
m.threads[thread_id] = { k = Aux.f(k, unpack(arg)) }
return thread_id
end
function public.kill_thread(thread_id)
if m.threads[thread_id] then
m.threads[thread_id].killed = true
end
end
function public.await(k)
local ret
m.when(function() return ret end, function() return k(unpack(ret)) end)
return setmetatable({}, {
__call = function(self, ...)
ret = arg
end,
__unm = function()
return ret ~= nil
end
})
end
function public.sleep(dt, ...)
local t0 = GetTime()
return m.when(function() return GetTime() - t0 >= dt end, unpack(arg))
end
function public.wait(k, ...)
if type(k) == 'number' then
m.when(function() k = k - 1 return k <= 0 end, unpack(arg))
else
m.threads[m.thread_id].k = Aux.f(k, unpack(arg))
end
end
function public.when(p, k, ...)
if p() then
return k(unpack(arg))
else
return m.wait(m.when, p, Aux.f(k, unpack(arg)))
end
end