KaoSDlanor

custom parallel API

Jun 15th, 2013
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.23 KB | None | 0 0
  1. local function safePairs(_t)
  2.     local tKeys={}
  3.     for k,_ in pairs(_t) do
  4.         table.insert(tKeys,k)
  5.     end
  6.     local nAt=0
  7.     return function()
  8.         nAt=nAt+1
  9.         return tKeys[nAt]
  10.     end
  11. end
  12.  
  13. local function create(...)
  14.     local tThreads={}
  15.     for k,_thread in pairs({...}) do
  16.         if type(_thread)~="function" then
  17.             error("Invalid param #"..k.." function expected, got "..type(_thread),2)
  18.         end
  19.         tThreads[k]={thread=coroutine.create(_thread),func=_thread,living=true,env=getfenv(_thread)}
  20.     end
  21.     return tThreads
  22. end
  23.  
  24. local function runUntilLimit(tRoutines,nLimit)
  25.     local running
  26.     local tUtils_mt={}
  27.     local tUtils=setmetatable({},tUtils_mt)
  28.     tUtils.addRoutines=function(...)
  29.         for _,tThread in ipairs(create(...)) do
  30.             table.insert(tRoutines,tThread)
  31.         end
  32.     end
  33.     tUtils.getRunning=function()
  34.         return running
  35.     end
  36.     tUtils.getRoutines=function(sName,...)
  37.         if sName==nil then
  38.             return nil
  39.         end
  40.         return tRoutines[sName or running],tUtils.getRoutines(...)
  41.     end
  42.     tUtils.killRoutines=function(sName,...)
  43.         if sName==nil then
  44.             return nil
  45.         elseif tRoutines[sName] and tRoutines[sName].living then
  46.             tRoutines[sName].living=false
  47.             tRoutines[sName].error="killed"
  48.             return true,tUtils.killRoutines(...)
  49.         else
  50.             return false,tUtils.killRoutines(...)
  51.         end
  52.     end
  53.     tUtils.runningRoutines=function()
  54.         local count=0
  55.         for i=1,#tRoutines do
  56.             if tRoutines[i].living then
  57.                 count=count+1
  58.             end
  59.         end
  60.         return count
  61.     end
  62.     local tEvts={}
  63.     while true do
  64.         local nRunning=0
  65.         for k,v in pairs(tRoutines) do
  66.             if type(v.thread)=="thread" and type(v.func)=="function" and v.living then
  67.                 running=k
  68.                 tUtils_mt.__index=v.env
  69.                 setfenv(v.func,tUtils)
  70.                 local ok,err=coroutine.resume(v.thread,unpack(tEvts))
  71.                 setfenv(v.func,v.env)
  72.                 running=nil
  73.                 if not ok or coroutine.status(v.thread)=="dead" then
  74.                     v.living=false
  75.                     v.error=err
  76.                 elseif living then
  77.                     nRunning=nRunning+1
  78.                 end
  79.                 if tUtils.runningRoutines()<=nLimit then
  80.                     return tRoutines
  81.                 end
  82.             end
  83.         end
  84.         tEvts={os.pullEventRaw()}
  85.     end
  86. end
  87.  
  88. function waitForAny(...)
  89.     local routines=create(...)
  90.     return runUntilLimit(routines,#routines-1)
  91. end
  92.  
  93. function waitForAll(...)
  94.     local routines=create(...)
  95.     runUntilLimit(routines,0)
  96. end
Advertisement
Add Comment
Please, Sign In to add comment