mirror of
https://github.com/kepler155c/opus
synced 2025-12-17 13:48:05 +00:00
bit of everything
This commit is contained in:
@@ -1,25 +1,17 @@
|
||||
local Util = require('util')
|
||||
local Process = require('process')
|
||||
|
||||
local Event = {
|
||||
uid = 1, -- unique id for handlers
|
||||
routines = { },
|
||||
handlers = { namedTimers = { } },
|
||||
terminate = false,
|
||||
}
|
||||
|
||||
local eventHandlers = {
|
||||
namedTimers = {}
|
||||
}
|
||||
|
||||
-- debug purposes
|
||||
function Event.getHandlers()
|
||||
return eventHandlers
|
||||
end
|
||||
|
||||
function Event.addHandler(type, f)
|
||||
local event = eventHandlers[type]
|
||||
local event = Event.handlers[type]
|
||||
if not event then
|
||||
event = {}
|
||||
event.handlers = {}
|
||||
eventHandlers[type] = event
|
||||
event = { handlers = { } }
|
||||
Event.handlers[type] = event
|
||||
end
|
||||
|
||||
local handler = {
|
||||
@@ -35,7 +27,7 @@ end
|
||||
|
||||
function Event.removeHandler(h)
|
||||
if h and h.event then
|
||||
eventHandlers[h.event].handlers[h.uid] = nil
|
||||
Event.handlers[h.event].handlers[h.uid] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -49,11 +41,11 @@ end
|
||||
|
||||
function Event.addNamedTimer(name, interval, recurring, f)
|
||||
Event.cancelNamedTimer(name)
|
||||
eventHandlers.namedTimers[name] = Event.addTimer(interval, recurring, f)
|
||||
Event.handlers.namedTimers[name] = Event.addTimer(interval, recurring, f)
|
||||
end
|
||||
|
||||
function Event.getNamedTimer(name)
|
||||
return eventHandlers.namedTimers[name]
|
||||
return Event.handlers.namedTimers[name]
|
||||
end
|
||||
|
||||
function Event.cancelNamedTimer(name)
|
||||
@@ -64,11 +56,6 @@ function Event.cancelNamedTimer(name)
|
||||
end
|
||||
end
|
||||
|
||||
function Event.isTimerActive(timer)
|
||||
return timer.enabled and
|
||||
os.clock() < timer.start + timer.interval
|
||||
end
|
||||
|
||||
function Event.addTimer(interval, recurring, f)
|
||||
local timer = Event.addHandler('timer',
|
||||
function(t, id)
|
||||
@@ -81,7 +68,6 @@ function Event.addTimer(interval, recurring, f)
|
||||
end
|
||||
if t.recurring then
|
||||
t.fired = false
|
||||
t.start = os.clock()
|
||||
t.timerId = os.startTimer(t.interval)
|
||||
else
|
||||
Event.removeHandler(t)
|
||||
@@ -91,103 +77,121 @@ function Event.addTimer(interval, recurring, f)
|
||||
timer.cf = f
|
||||
timer.interval = interval
|
||||
timer.recurring = recurring
|
||||
timer.start = os.clock()
|
||||
timer.enabled = true
|
||||
timer.timerId = os.startTimer(interval)
|
||||
|
||||
return timer
|
||||
end
|
||||
|
||||
function Event.removeTimer(h)
|
||||
Event.removeHandler(h)
|
||||
function Event.onInterval(interval, f)
|
||||
return Event.addTimer(interval, true, f)
|
||||
end
|
||||
|
||||
function Event.blockUntilEvent(event, timeout)
|
||||
return Event.waitForEvent(event, timeout, os.pullEvent)
|
||||
function Event.onTimeout(timeout, f)
|
||||
return Event.addTimer(timeout, false, f)
|
||||
end
|
||||
|
||||
function Event.waitForEvent(event, timeout, pullEvent)
|
||||
pullEvent = pullEvent or Event.pullEvent
|
||||
|
||||
function Event.waitForEvent(event, timeout)
|
||||
local timerId = os.startTimer(timeout)
|
||||
repeat
|
||||
local e, p1, p2, p3, p4 = pullEvent()
|
||||
local e, p1, p2, p3, p4 = os.pullEvent()
|
||||
if e == event then
|
||||
return e, p1, p2, p3, p4
|
||||
end
|
||||
until e == 'timer' and p1 == timerId
|
||||
end
|
||||
|
||||
local exitPullEvents = false
|
||||
|
||||
local function _pullEvents()
|
||||
while true do
|
||||
local e = { os.pullEvent() }
|
||||
Event.processEvent(e)
|
||||
function Event.addRoutine(routine)
|
||||
local r = { co = coroutine.create(routine) }
|
||||
local s, m = coroutine.resume(r.co)
|
||||
if not s then
|
||||
error(m or 'Error processing routine')
|
||||
end
|
||||
end
|
||||
|
||||
function Event.sleep(t)
|
||||
local timerId = os.startTimer(t or 0)
|
||||
repeat
|
||||
local event, id = Event.pullEvent()
|
||||
until event == 'timer' and id == timerId
|
||||
end
|
||||
|
||||
function Event.addThread(fn)
|
||||
return Process:addThread(fn)
|
||||
Event.routines[r] = true
|
||||
r.filter = m
|
||||
return r
|
||||
end
|
||||
|
||||
function Event.pullEvents(...)
|
||||
local routines = { ... }
|
||||
if #routines > 0 then
|
||||
Process:addThread(_pullEvents)
|
||||
for _, routine in ipairs(routines) do
|
||||
Process:addThread(routine)
|
||||
end
|
||||
while true do
|
||||
local e = Process:pullEvent()
|
||||
if exitPullEvents or e == 'terminate' then
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
while true do
|
||||
local e = { os.pullEventRaw() }
|
||||
Event.processEvent(e)
|
||||
if exitPullEvents or e[1] == 'terminate' then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for _, r in ipairs({ ... }) do
|
||||
Event.addRoutine(r)
|
||||
end
|
||||
|
||||
repeat
|
||||
local e = Event.pullEvent()
|
||||
until e[1] == 'terminate'
|
||||
end
|
||||
|
||||
function Event.exitPullEvents()
|
||||
exitPullEvents = true
|
||||
Event.terminate = true
|
||||
os.sleep(0)
|
||||
end
|
||||
|
||||
function Event.pullEvent(eventType)
|
||||
local e = { os.pullEventRaw(eventType) }
|
||||
return Event.processEvent(e)
|
||||
|
||||
while true do
|
||||
local e = { os.pullEventRaw() }
|
||||
local routines = Util.keys(Event.routines)
|
||||
for _, r in ipairs(routines) do
|
||||
if not r.filter or r.filter == e[1] then
|
||||
local s, m = coroutine.resume(r.co, table.unpack(e))
|
||||
if not s and e[1] ~= 'terminate' then
|
||||
debug({s, m})
|
||||
debug(r)
|
||||
error(m or 'Error processing event')
|
||||
end
|
||||
if coroutine.status(r.co) == 'dead' then
|
||||
r.co = nil
|
||||
Event.routines[r] = nil
|
||||
else
|
||||
r.filter = m
|
||||
end
|
||||
end
|
||||
end
|
||||
Event.processEvent(e)
|
||||
if Event.terminate or e[1] == 'terminate' then
|
||||
Event.terminate = false
|
||||
return { 'terminate' }
|
||||
end
|
||||
|
||||
if not eventType or e[1] == eventType then
|
||||
return e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Event.processEvent(pe)
|
||||
|
||||
local e, p1, p2, p3, p4, p5 = unpack(pe)
|
||||
|
||||
local event = eventHandlers[e]
|
||||
local event = Event.handlers[e]
|
||||
if event then
|
||||
local keys = Util.keys(event.handlers)
|
||||
for _,key in pairs(keys) do
|
||||
local h = event.handlers[key]
|
||||
if h then
|
||||
h.f(h, p1, p2, p3, p4, p5)
|
||||
if h and not h.co then
|
||||
local co = coroutine.create(function()
|
||||
h.f(h, p1, p2, p3, p4, p5)
|
||||
end)
|
||||
local s, m = coroutine.resume(co)
|
||||
if not s then
|
||||
debug({s, m})
|
||||
debug(h)
|
||||
error(m or 'Error processing ' .. e)
|
||||
elseif coroutine.status(co) ~= 'dead' then
|
||||
h.co = co
|
||||
h.filter = m
|
||||
Event.routines[h] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return e, p1, p2, p3, p4, p5
|
||||
end
|
||||
|
||||
Event.on = Event.addHandler
|
||||
Event.off = Event.removeHandler
|
||||
|
||||
return Event
|
||||
|
||||
Reference in New Issue
Block a user