MudkipTheEpic

Coroutine Manager Test

Sep 8th, 2013
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.31 KB | None | 0 0
  1.  
  2. --Config:
  3.  
  4. local verbose=false
  5.  
  6.  
  7. --TODO: FIX--
  8.  
  9. --Debug print function--
  10. local debugPrint=function() end
  11. if verbose then
  12.     debugPrint=function(text,time)
  13.         time=time or 2
  14.         print(text)
  15.         sleep(time)
  16.     end
  17. end
  18.  
  19. --Base run class--
  20.  
  21. local function readyToYield(pool)
  22.     for i=1,table.maxn(pool) do
  23.         if pool[i] and #pool[i].events>0 then return false end
  24.     end
  25.     return true
  26. end
  27.  
  28. local function clean(pool)
  29.     for i=1,table.maxn(pool) do
  30.         if pool[i] and pool[i].status=="dead" then
  31.             pool[i]=nil
  32.         end
  33.     end
  34. end
  35.  
  36. local function createCoroutine(_co,...)
  37.     local tEvents={{...}}
  38.     local tFilter=nil
  39.     local isPaused=false
  40.     local hasRun=false
  41.     local co=coroutine.create(_co)
  42.     local resume=function(self,...)
  43.         debugPrint("Resume function initiated")
  44.         if self.status=="dead" then return "dead" end
  45.         local tArgs={...}
  46.         if table.maxn(tArgs)>0 and not isPaused then
  47.             table.insert(tEvents,tArgs)
  48.         end
  49.         if table.maxn(tEvents)>0 then
  50.             debugPrint("tEvents NOT empty",1)
  51.             if not isPaused then
  52.                 debugPrint("Not paused",1)
  53.                 local event=table.remove(tEvents,1) or {}
  54.                 debugPrint("Event is "..textutils.serialize(event),1)
  55.                 debugPrint("tFilter is "..(tostring(tFilter)),1)
  56.                 if (tFilter==nil) or (tFilter==event[1]) or event[1]=="terminate" then
  57.                     hasRun=true
  58.                     debugPrint("Resuming with event "..textutils.serialize(event))
  59.                     tFilter=select(2,coroutine.resume(co,unpack(event))) --Spent day debugging, forgot the first return value o coroutine.resume is the success...
  60.                 end
  61.             end
  62.         end
  63.         if self.status=="dead" then return "dead" end
  64.     end
  65.     return setmetatable({
  66.         resume=function(self,...)
  67.             return resume(self,...)
  68.         end,
  69.         passEvent=function(self,...)
  70.             if not isPaused then
  71.                 table.insert(tEvents,{...})
  72.                 debugPrint("Passing event: "..textutils.serialize({...}),1)
  73.                 debugPrint("Event on top: "..(textutils.serialize(tEvents[#tEvents]) or "nil"))
  74.             end
  75.         end,
  76.         kill=function(self)
  77.             rawset(self,"status","dead")
  78.         end,
  79.     },{
  80.         __index=function(self,k)
  81.             if k=="status" then
  82.                 return coroutine.status(co)
  83.             elseif k=="tEvents" or k=="events" then
  84.                 return --[[setmetatable({},{__index=]]tEvents--[[})]]
  85.             elseif k=="isPaused" then
  86.                 return isPaused
  87.             elseif k=="hasRun" then
  88.                 return hasRun
  89.             end
  90.         end,
  91.         __newindex=function(self,k,v)
  92.             if k=="isPaused" and type(v)=="boolean" then
  93.                 isPaused=v
  94.             end
  95.         end,
  96.         __call=function(self,...)
  97.             return resume(self,...)
  98.         end
  99.     })
  100. end
  101.  
  102. local tManageTemplate = {
  103.     run=function(self,...)
  104.         local tPool=self["tPool"]
  105.         if table.maxn(tPool)==0 then return false end
  106.         for i=1,table.maxn(tPool) do
  107.             if tPool[i] and not tPool[i].hasRun then
  108.                 tPool[i]()
  109.             end
  110.         end
  111.         local tEvents=#{...}>0 and {...} or {coroutine.yield()}
  112.         debugPrint("Got events!",1)
  113.         local firstRun=true
  114.         repeat
  115.             for i=1,table.maxn(tPool) do
  116.                 if (tPool[i] and tPool[i].status~="dead") and (firstRun) then
  117.                     --[[if tPool[i]:resume(unpack(tEvents)) == "dead" then
  118.                         tPool[i]=nil
  119.                     end]]
  120.                     debugPrint("Passing event from run "..textutils.serialize(tEvents))
  121.                     tPool[i]:passEvent(unpack(tEvents))
  122.                 end
  123.                 if tPool[i] and tPool[i].status~="dead" and #tPool[i].events>0 then
  124.                     if tPool[i]:resume() == "dead" then
  125.                         tPool[i]=nil
  126.                     end
  127.                 end
  128.             end
  129.             firstRun=false
  130.         until readyToYield(tPool)
  131.         clean(tPool)
  132.         return table.maxn(tPool)>0
  133.     end,
  134.     run_forever=function(self)
  135.         if not self:run() then return false end
  136.         while self:run() do end
  137.         return true
  138.     end,
  139.     addCo=function(self,co,...)
  140.         self.tPool[table.maxn(self.tPool)+1]=createCoroutine(co,...)
  141.     end,
  142. }
  143.  
  144.  
  145. function new(self,main,...)
  146.     local tResults={pcall( function(main,...)
  147.     main=main or function() pcall(loadfile("rom/programs/shell")) end
  148.     local tPool={createCoroutine(main,...)}
  149.     local tEvents={}
  150.     local tManager={}
  151.     setmetatable(tManager,{
  152.         __index=function(t,k)
  153.             if k=="tPool" or k=="pool" then
  154.                 return tPool
  155.             elseif k=="tEvents" or k=="events" then
  156.                 return tEvents
  157.             elseif tonumber(k) then
  158.                 k=tonumber(k)
  159.                 return tPool[k]
  160.             else
  161.                 return tManageTemplate[k]
  162.             end
  163.         end,
  164.         __call=tManageTemplate["run"],
  165. })
  166.     return tManager
  167.  
  168.     end, main,...)}
  169.     if tResults[1] then
  170.         return select(2,unpack(tResults))
  171.     else
  172.         return false,"Could not create a new manager!"
  173.     end
  174.  
  175. end
Advertisement
Add Comment
Please, Sign In to add comment