Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local ev = {}
- rawset(_G,"events",ev)
- local coParallelCoHandler
- local parallelCos = {}
- local programStack = {}
- local eventTable = {}
- setmetatable(eventTable,{ __mode="v" })
- setmetatable(programStack,{ __mode="v" })
- --setmetatable(parallelCos, { __mode="v" })
- local deletionQueue = {}
- local osPullEvent = os.pullEvent
- local osPullEventRaw = os.pullEventRaw
- local function getTableID(tabl)
- return string.sub(tostring(tabl),8)
- end
- function isProgramRegistered( co, pID )
- if programStack[ co ] == nil then return false end
- for i,v in ipairs( programStack[co] ) do
- if v == pID then return true end
- end
- return false
- end
- local function getTablePos(checkTable,element)
- for k,v in pairs(checkTable) do
- if v == element then return k end
- end
- return false
- end
- local function queueDeletion(delTable,element)
- if deletionQueue[delTable] == nil then deletionQueue[delTable] = {} end
- local pos = getTablePos(deletionQueue[delTable],element)
- if not pos then table.insert(deletionQueue[delTable],element) end
- end
- local function executeDeletion()
- for k,v in pairs(deletionQueue) do
- for _,v2 in pairs(v) do
- local pos = getTablePos(k,v2)
- if pos then table.remove(k,pos) end
- if #k == 0 then k = nil break end
- end
- end
- deletionQueue = {}
- end
- local function injectParallelCo(co)
- table.insert(parallelCos,co)
- end
- local function removeParallelCo(co)
- queueDeletion(parallelCos,co)
- executeDeletion()
- end
- local function removeParallelCoByReg(regTable)
- for k,v in pairs(parallelCos) do
- if v.regTable == regTable then
- queueDeletion(parallelCos,v)
- break
- end
- end
- executeDeletion()
- end
- local function parallelCoHandler(ev,p1,p2,p3,p4,p5,p6)
- while true do
- for k,v in pairs(parallelCos) do
- if v == nil or v.co == nil or coroutine.status(v.co) == "dead" then
- queueDeletion(parallelCos,v)
- else
- coroutine.resume(v.co,ev,p1,p2,p3,p4,p5,p6)
- end
- end
- executeDeletion()
- coroutine.yield()
- end
- end
- local function handleEvent(ev,...)
- if eventTable[ev] == nil or #eventTable[ev] == 0 then return false end
- local callTable = {}
- for _,v in pairs( eventTable[ev] ) do
- if v[2] ~= nil then
- table.insert(callTable,v)
- else
- queueDeletion(eventTable[ev],v)
- end
- end
- executeDeletion()
- if #callTable > 0 then
- for k,v in pairs(callTable) do
- injectParallelCo({co=coroutine.create( function() v[2](ev,unpack(arg)) end ), regTable=v})
- end
- return true
- else
- return false
- end
- end
- local function insertEvent(co, event, regTable)
- if programStack[co] == nil then
- programStack[co] = {}
- --error("Trying to insert event for unregistered coroutine")
- end
- if eventTable[event] == nil then
- eventTable[event] = {}
- end
- setmetatable(regTable, { __mode = "v" } )
- table.insert(eventTable[event],regTable)
- table.insert(programStack[co][#programStack[co]],regTable)
- end
- function _G.events.registerEvent(event, callback)
- if callback == nil then error("No callback specified") end
- local regTable = {event,callback}
- insertEvent(coroutine.running(), event, regTable)
- return regTable
- end
- function _G.events.unregisterEvent(regID,holdDeletion)
- holdDeletion = holdDeletion or false
- local event = regID[1]
- if eventTable[event] == nil or #eventTable[event] == 0 then return end
- queueDeletion(eventTable[event],regID)
- if not holdDeletion then
- executeDeletion()
- end
- if #eventTable[event] == 0 then eventTable[event] = nil end
- end
- function clearProgramEvents( co, pID )
- if programStack[co] == nil then return end
- for _,v in ipairs( programStack[co] ) do
- if v == pID then
- for _,v2 in ipairs(v) do
- events.unregisterEvent(v2,true)
- end
- end
- end
- executeDeletion()
- end
- function registerProgram( co, pID )
- if programStack[ co ] == nil then
- programStack[ co ] = {}
- end
- table.insert(programStack[co],pID)
- end
- function unregisterProgram( co, pID )
- if not isProgramRegistered( co, pID ) then return end
- clearProgramEvents( co, pID )
- queueDeletion(programStack[co],pID)
- executeDeletion()
- end
- local orgrun = os.run
- function os.run( _tEnv, _sPath, ... )
- local pID = {}
- registerProgram( coroutine.running(), pID )
- orgrun( _tEnv, _sPath, unpack({...}) )
- unregisterProgram( coroutine.running(), pID)
- end
- coParallelCoHandler = coroutine.create(parallelCoHandler)
- while true do
- local ev,p1,p2,p3,p4,p5,p6 = os.pullEvent()
- handleEvent(ev,p1,p2,p3,p4,p5,p6)
- coroutine.resume(coParallelCoHandler,ev,p1,p2,p3,p4,p5,p6)
- end
Advertisement
Add Comment
Please, Sign In to add comment