Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Config:
- local verbose=false
- --TODO: FIX--
- --Debug print function--
- local debugPrint=function() end
- if verbose then
- debugPrint=function(text,time)
- time=time or 2
- print(text)
- sleep(time)
- end
- end
- --Base run class--
- local function readyToYield(pool)
- for i=1,table.maxn(pool) do
- if pool[i] and #pool[i].events>0 then return false end
- end
- return true
- end
- local function clean(pool)
- for i=1,table.maxn(pool) do
- if pool[i] and pool[i].status=="dead" then
- pool[i]=nil
- end
- end
- end
- local function createCoroutine(_co,...)
- local tEvents={{...}}
- local tFilter=nil
- local isPaused=false
- local hasRun=false
- local co=coroutine.create(_co)
- local resume=function(self,...)
- debugPrint("Resume function initiated")
- if self.status=="dead" then return "dead" end
- local tArgs={...}
- if table.maxn(tArgs)>0 and not isPaused then
- table.insert(tEvents,tArgs)
- end
- if table.maxn(tEvents)>0 then
- debugPrint("tEvents NOT empty",1)
- if not isPaused then
- debugPrint("Not paused",1)
- local event=table.remove(tEvents,1) or {}
- debugPrint("Event is "..textutils.serialize(event),1)
- debugPrint("tFilter is "..(tostring(tFilter)),1)
- if (tFilter==nil) or (tFilter==event[1]) or event[1]=="terminate" then
- hasRun=true
- debugPrint("Resuming with event "..textutils.serialize(event))
- tFilter=select(2,coroutine.resume(co,unpack(event))) --Spent day debugging, forgot the first return value o coroutine.resume is the success...
- end
- end
- end
- if self.status=="dead" then return "dead" end
- end
- return setmetatable({
- resume=function(self,...)
- return resume(self,...)
- end,
- passEvent=function(self,...)
- if not isPaused then
- table.insert(tEvents,{...})
- debugPrint("Passing event: "..textutils.serialize({...}),1)
- debugPrint("Event on top: "..(textutils.serialize(tEvents[#tEvents]) or "nil"))
- end
- end,
- kill=function(self)
- rawset(self,"status","dead")
- end,
- },{
- __index=function(self,k)
- if k=="status" then
- return coroutine.status(co)
- elseif k=="tEvents" or k=="events" then
- return --[[setmetatable({},{__index=]]tEvents--[[})]]
- elseif k=="isPaused" then
- return isPaused
- elseif k=="hasRun" then
- return hasRun
- end
- end,
- __newindex=function(self,k,v)
- if k=="isPaused" and type(v)=="boolean" then
- isPaused=v
- end
- end,
- __call=function(self,...)
- return resume(self,...)
- end
- })
- end
- local tManageTemplate = {
- run=function(self,...)
- local tPool=self["tPool"]
- if table.maxn(tPool)==0 then return false end
- for i=1,table.maxn(tPool) do
- if tPool[i] and not tPool[i].hasRun then
- tPool[i]()
- end
- end
- local tEvents=#{...}>0 and {...} or {coroutine.yield()}
- debugPrint("Got events!",1)
- local firstRun=true
- repeat
- for i=1,table.maxn(tPool) do
- if (tPool[i] and tPool[i].status~="dead") and (firstRun) then
- --[[if tPool[i]:resume(unpack(tEvents)) == "dead" then
- tPool[i]=nil
- end]]
- debugPrint("Passing event from run "..textutils.serialize(tEvents))
- tPool[i]:passEvent(unpack(tEvents))
- end
- if tPool[i] and tPool[i].status~="dead" and #tPool[i].events>0 then
- if tPool[i]:resume() == "dead" then
- tPool[i]=nil
- end
- end
- end
- firstRun=false
- until readyToYield(tPool)
- clean(tPool)
- return table.maxn(tPool)>0
- end,
- run_forever=function(self)
- if not self:run() then return false end
- while self:run() do end
- return true
- end,
- addCo=function(self,co,...)
- self.tPool[table.maxn(self.tPool)+1]=createCoroutine(co,...)
- end,
- }
- function new(self,main,...)
- local tResults={pcall( function(main,...)
- main=main or function() pcall(loadfile("rom/programs/shell")) end
- local tPool={createCoroutine(main,...)}
- local tEvents={}
- local tManager={}
- setmetatable(tManager,{
- __index=function(t,k)
- if k=="tPool" or k=="pool" then
- return tPool
- elseif k=="tEvents" or k=="events" then
- return tEvents
- elseif tonumber(k) then
- k=tonumber(k)
- return tPool[k]
- else
- return tManageTemplate[k]
- end
- end,
- __call=tManageTemplate["run"],
- })
- return tManager
- end, main,...)}
- if tResults[1] then
- return select(2,unpack(tResults))
- else
- return false,"Could not create a new manager!"
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment