Pinkishu

events.lua v0.7.5

Jul 2nd, 2012
351
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.64 KB | None | 0 0
  1. local ev = {}
  2. rawset(_G,"events",ev)
  3.  
  4. local coParallelCoHandler
  5. local parallelCos = {}
  6. local programStack = {}
  7. local eventTable = {}
  8. setmetatable(eventTable,{ __mode="v" })
  9. setmetatable(programStack,{ __mode="v" })
  10. --setmetatable(parallelCos, { __mode="v" })
  11. local deletionQueue = {}
  12. local osPullEvent = os.pullEvent
  13. local osPullEventRaw = os.pullEventRaw
  14.  
  15.  
  16.  
  17. local function getTableID(tabl)
  18.   return string.sub(tostring(tabl),8)
  19. end
  20.  
  21. function isProgramRegistered( co, pID )
  22.   if programStack[ co ] == nil then return false end
  23.   for i,v in ipairs( programStack[co] ) do
  24.     if v == pID then return true end
  25.   end
  26.   return false
  27. end
  28.  
  29. local function getTablePos(checkTable,element)
  30.   for k,v in pairs(checkTable) do
  31.     if v == element then return k end
  32.   end
  33.   return false
  34. end
  35.  
  36. local function queueDeletion(delTable,element)
  37.   if deletionQueue[delTable] == nil then deletionQueue[delTable] = {} end
  38.   local pos = getTablePos(deletionQueue[delTable],element)
  39.   if not pos then table.insert(deletionQueue[delTable],element) end
  40. end
  41.  
  42. local function executeDeletion()
  43.   for k,v in pairs(deletionQueue) do
  44.     for _,v2 in pairs(v) do
  45.       local pos = getTablePos(k,v2)
  46.       if pos then table.remove(k,pos) end
  47.       if #k == 0 then k = nil  break end
  48.     end
  49.   end
  50.  
  51.   deletionQueue = {}
  52. end
  53.  
  54.  
  55. local function injectParallelCo(co)
  56.   table.insert(parallelCos,co)
  57. end
  58.  
  59. local function removeParallelCo(co)
  60.   queueDeletion(parallelCos,co)
  61.   executeDeletion()
  62. end
  63.  
  64. local function removeParallelCoByReg(regTable)
  65.   for k,v in pairs(parallelCos) do
  66.     if v.regTable == regTable then
  67.       queueDeletion(parallelCos,v)
  68.       break
  69.     end
  70.   end
  71.   executeDeletion()
  72. end
  73.  
  74. local function parallelCoHandler(ev,p1,p2,p3,p4,p5,p6)
  75.   while true do
  76.     for k,v in pairs(parallelCos) do
  77.       if v == nil or v.co == nil or coroutine.status(v.co) == "dead" then
  78.         queueDeletion(parallelCos,v)
  79.       else
  80.         coroutine.resume(v.co,ev,p1,p2,p3,p4,p5,p6)
  81.       end
  82.     end
  83.     executeDeletion()
  84.     coroutine.yield()
  85.   end
  86. end
  87.  
  88. local function handleEvent(ev,...)
  89.   if eventTable[ev] == nil or #eventTable[ev] == 0 then return false end
  90.   local callTable = {}
  91.  
  92.   for _,v in pairs( eventTable[ev] ) do
  93.     if v[2] ~= nil then
  94.       table.insert(callTable,v)
  95.     else
  96.       queueDeletion(eventTable[ev],v)
  97.     end
  98.   end
  99.   executeDeletion()
  100.   if #callTable > 0 then
  101.     for k,v in pairs(callTable) do
  102.       injectParallelCo({co=coroutine.create( function() v[2](ev,unpack(arg)) end ), regTable=v})
  103.     end
  104.     return true
  105.   else
  106.     return false
  107.   end
  108. end
  109.  
  110. local function insertEvent(co, event, regTable)
  111.   if programStack[co] == nil then
  112.     programStack[co] = {}
  113.     --error("Trying to insert event for unregistered coroutine")
  114.   end
  115.   if eventTable[event] == nil then
  116.     eventTable[event] = {}
  117.   end
  118.   setmetatable(regTable, { __mode = "v" } )
  119.   table.insert(eventTable[event],regTable)
  120.   table.insert(programStack[co][#programStack[co]],regTable)
  121. end
  122.  
  123. function _G.events.registerEvent(event, callback)
  124.   if callback == nil then error("No callback specified") end
  125.   local regTable = {event,callback}
  126.   insertEvent(coroutine.running(), event, regTable)
  127.   return regTable
  128. end
  129.  
  130. function _G.events.unregisterEvent(regID,holdDeletion)
  131.   holdDeletion = holdDeletion or false
  132.   local event = regID[1]
  133.  
  134.   if eventTable[event] == nil or #eventTable[event] == 0 then return end
  135.  
  136.   queueDeletion(eventTable[event],regID)
  137.   if not holdDeletion then
  138.     executeDeletion()
  139.   end
  140.  
  141.   if #eventTable[event] == 0 then eventTable[event] = nil end
  142. end
  143.  
  144. function clearProgramEvents( co, pID )
  145.   if programStack[co] == nil then return end
  146.   for _,v in ipairs( programStack[co] ) do
  147.     if v == pID then
  148.       for _,v2 in ipairs(v) do
  149.         events.unregisterEvent(v2,true)
  150.       end
  151.     end
  152.   end
  153.   executeDeletion()
  154. end
  155.  
  156. function registerProgram( co, pID )
  157.   if programStack[ co ] == nil then
  158.     programStack[ co ] = {}
  159.   end
  160.   table.insert(programStack[co],pID)
  161. end
  162.  
  163. function unregisterProgram( co, pID )
  164.   if not isProgramRegistered( co, pID ) then return end
  165.   clearProgramEvents( co, pID )
  166.   queueDeletion(programStack[co],pID)
  167.   executeDeletion()
  168.  
  169. end
  170.  
  171. local orgrun = os.run
  172. function os.run( _tEnv, _sPath, ... )
  173.   local pID = {}
  174.   registerProgram( coroutine.running(), pID )
  175.   orgrun( _tEnv, _sPath, unpack({...}) )
  176.   unregisterProgram( coroutine.running(), pID)
  177. end
  178.  
  179. coParallelCoHandler = coroutine.create(parallelCoHandler)
  180.  
  181. while true do
  182.   local ev,p1,p2,p3,p4,p5,p6 = os.pullEvent()
  183.   handleEvent(ev,p1,p2,p3,p4,p5,p6)
  184.   coroutine.resume(coParallelCoHandler,ev,p1,p2,p3,p4,p5,p6)
  185. end
Advertisement
Add Comment
Please, Sign In to add comment