Guest User

Simple coroutine manager

a guest
Jun 24th, 2015
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.24 KB | None | 0 0
  1. --// The coroutine manager | a sample code for DannySMc | by MKlegoman357 \\--
  2.  
  3. -- this table holds all the coroutines in the format:
  4. -- routines = {
  5. --   {
  6. --     name = name of the coroutine;
  7. --     func = the function of the coroutine;
  8. --     co = the coroutine;
  9. --     filter = the event filter for the coroutine;
  10. --   },
  11. --   ...
  12. -- }
  13.  
  14. local routines = {}
  15.  
  16. -- generic function to add a thread, it's not really needed, just here as a 'helper' function
  17. local function addThread (name, func)
  18.   routines[#routines + 1] = {
  19.     name = name;
  20.     func = func;
  21.     co = coroutine.create(func);
  22.     filter = nil;
  23.   }
  24. end
  25.  
  26. -- this functions simply removes the coroutines by their name
  27. local function removeThread (name)
  28.   local toRemove = {}
  29.  
  30.   for i, thread in ipairs(routines) do
  31.     if thread.name == name then
  32.       toRemove[#toRemove + 1] = i
  33.     end
  34.   end
  35.  
  36.   for i = #toRemove, 1, -1 do
  37.     table.remove(routines, toRemove[i])
  38.   end
  39. end
  40.  
  41. local function run ()
  42.   -- e is a table holding all the event data; event is simply the event string (mouse_down, key, terminate, ...)
  43.   local e, event = {}, nil -- we will have to run the coroutines first, so we'll set the event to be empty
  44.  
  45.   while #routines > 0 do -- while there are coroutines to run
  46.     -- this table will hold the index of the coroutines which are dead, so we'll be able to remove them later
  47.     local toRemove = {}
  48.  
  49.     for i, thread in ipairs(routines) do -- for every thread (coroutine, routine - call it whatever)
  50.       -- there are ALWAYS 3 conditions on when to resume a coroutine in ComputerCraft (only one of them has to be true):
  51.       -- 1. the event is 'terminate'
  52.       -- 2. the event filter of the coroutine is nil
  53.       -- 3. the event filter is equal to the coroutine's event filter
  54.       if event == "terminate" or thread.filter == nil or thread.filter == event then
  55.         local ok, filter = coroutine.resume(thread.co, unpack(e)) -- resume the coroutine with the event data
  56.  
  57.         if not ok then -- if the coroutine errored, print the error
  58.           error(filter, 2)
  59.         end
  60.  
  61.         -- if the coroutine ended, add it to remove list
  62.         if coroutine.status(thread.co) == "dead" then
  63.           toRemove[#toRemove + 1] = i
  64.         end
  65.  
  66.         -- don't forget to set the coroutine's filter! It's the same thing that you pass to os.pullEvent( filter )
  67.         thread.filter = filter
  68.       end
  69.     end
  70.  
  71.     for i = #toRemove, 1, -1 do -- remove all the dead coroutines
  72.       table.remove(routines, toRemove[i])
  73.     end
  74.  
  75.     -- if there are no more coroutines then break out of the loop. This if is necessary because otherwise the os.pullEventRaw line would be called
  76.     if #routines == 0 then
  77.       break
  78.     end
  79.  
  80.     -- catch any events and restart the loop to resume the coroutines
  81.     e = {os.pullEventRaw()}
  82.     event = e[1]
  83.   end
  84. end
  85.  
  86. --[[ Test code ]]--
  87.  
  88. local function main ()
  89.   print("main")
  90.   sleep(1)
  91.   print("main done")
  92. end
  93.  
  94. local function bar ()
  95.   print("bar")
  96.  
  97.   for i = 1, 3 do
  98.     sleep(1)
  99.     print("bar ", i)
  100.   end
  101. end
  102.  
  103. local function foo ()
  104.   sleep(1)
  105.   print("foo")
  106.   sleep(1)
  107.   addThread("bar", bar)
  108. end
  109.  
  110. addThread("main", main)
  111. addThread("foo", foo)
  112.  
  113. print("START")
  114.  
  115. run()
  116.  
  117. print("END")
Advertisement
Add Comment
Please, Sign In to add comment