1
0
mirror of https://github.com/kepler155c/opus synced 2025-12-17 13:48:05 +00:00

bit of everything

This commit is contained in:
kepler155c@gmail.com
2017-07-23 22:37:07 -04:00
parent 027f386ed1
commit f8bcf90a6b
30 changed files with 866 additions and 502 deletions

View File

@@ -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