Advertisement
einsteinK

Roblox Custom Thread Scheduler

Nov 5th, 2014
349
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.02 KB | None | 0 0
  1.  
  2. local function Tuple(...)
  3.     local r,n = {...},select("#",...)
  4.     return function()
  5.         return unpack(r,1,n)
  6.     end
  7. end
  8.  
  9. local Scheduler = {
  10.     Threads = {
  11.         Running = {};
  12.         Waiting = {};
  13.     }; Fire = {};
  14.     Events = {};
  15. }
  16.  
  17. local Task do
  18.     local function start(...) Scheduler:Start(...) end
  19.     local function stop(...) Scheduler:Stop(...) end
  20.     local taskMeta = {__tostring = function(s) return s.name end,__index=function(s,k)
  21.         if k:lower() == "start" then return start end
  22.         if k:lower() == "stop" then return stop end return rawget(s,k:lower())
  23.     end}
  24.     function Task(name,func,...)
  25.         local task = setmetatable({
  26.             name = name; c = false;
  27.             status="new",args=Tuple(...),
  28.             thread = coroutine.create(func)
  29.         },taskMeta)
  30.         local function w(t)
  31.             local start,y = tick()
  32.             Scheduler.Threads.Waiting[task] = true
  33.             task.status = "waiting"
  34.             repeat local c = coroutine.yield()
  35.                 y = tick()-start
  36.             until not c and (t or 0) < y
  37.             task.status = "running"
  38.             Scheduler.Threads.Waiting[task] = nil
  39.             return t,elapsedTime()
  40.         end
  41.         setfenv(func,setmetatable({wait=w,Wait=w},{__index=getfenv(func)}))
  42.         return task
  43.     end
  44. end
  45.  
  46. function Scheduler:AddEvent(ev)
  47.     local be = Instance.new("BindableEvent")
  48.     self.Events[ev] = be.Event
  49.     self.Fire[ev] = function(...) be:Fire(...) end
  50. end
  51. function Scheduler:FireEvent(ev,...)
  52.     self.Fire[ev](...)
  53. end
  54. function Scheduler:Start(task,...)
  55.     if Scheduler.Threads.Running[task] then return end
  56.     Scheduler.Threads.Running[task] = Tuple(...)
  57.     Scheduler:FireEvent("Started",task)
  58. end
  59. function Scheduler:Stop(task)
  60.     Scheduler.Threads.Running[task] = nil
  61.     Scheduler:FireEvent("Stopped",task,false)
  62. end
  63.  
  64. Scheduler:AddEvent("Started") -- Started(task) (Fired whenever someone starts a task)
  65. Scheduler:AddEvent("Stopped") -- Stopped(task,ended) (Fired when stopped, or ended == true when end of thread)
  66. --NOTE: If you start an already ended thread, it'll fire Stopped(task,true) the next tick (because it's dead)
  67. Scheduler:AddEvent("Ran") -- Ran(task,...) (Task runs for first time, also returns the passed args)
  68.  
  69. local REPORTED = false
  70. spawn(function()
  71.     while true do
  72.         for k,v in pairs(Scheduler.Threads.Running) do
  73.             if coroutine.status(k.thread) == "dead" then
  74.                 Scheduler:FireEvent("Stopped",k,true)
  75.                 Scheduler.Running[k] = nil
  76.             elseif k.status == "running" then
  77.                 if not k.c then k.c = true
  78.                     print(tick(),"~Thread",k,"is yielding C-sided")
  79.                 end
  80.             else
  81.                 if k.status == "new" then
  82.                     k.status = "running"
  83.                     coroutine.resume(k.thread,v())
  84.                 else
  85.                     coroutine.resume(k.thread)
  86.                 end k.c = false
  87.             end
  88.         end wait(0)
  89.     end
  90. end)
  91.  
  92. local task = Task("Test",function(...) print("args:",...) while wait(1) do print("hi") end end)
  93. -- Properties: Name,Status   (also Args,C and Thread, but those should only be used internally)
  94.  
  95. -- ... being extra arguments
  96. Scheduler:Start(task,"lol",nil)
  97. --OR     (Starting a task multiple times has no effect)
  98. task:Start(...)
  99.  
  100. wait(2)
  101.  
  102. Scheduler:Stop(task)
  103. --OR     (Stopping a task multiple times has no effect)
  104. task:Stop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement