Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --// The coroutine manager | a sample code for DannySMc | by MKlegoman357 \\--
- -- this table holds all the coroutines in the format:
- -- routines = {
- -- {
- -- name = name of the coroutine;
- -- func = the function of the coroutine;
- -- co = the coroutine;
- -- filter = the event filter for the coroutine;
- -- },
- -- ...
- -- }
- local routines = {}
- -- generic function to add a thread, it's not really needed, just here as a 'helper' function
- local function addThread (name, func)
- routines[#routines + 1] = {
- name = name;
- func = func;
- co = coroutine.create(func);
- filter = nil;
- }
- end
- -- this functions simply removes the coroutines by their name
- local function removeThread (name)
- local toRemove = {}
- for i, thread in ipairs(routines) do
- if thread.name == name then
- toRemove[#toRemove + 1] = i
- end
- end
- for i = #toRemove, 1, -1 do
- table.remove(routines, toRemove[i])
- end
- end
- local function run ()
- -- e is a table holding all the event data; event is simply the event string (mouse_down, key, terminate, ...)
- local e, event = {}, nil -- we will have to run the coroutines first, so we'll set the event to be empty
- while #routines > 0 do -- while there are coroutines to run
- -- this table will hold the index of the coroutines which are dead, so we'll be able to remove them later
- local toRemove = {}
- for i, thread in ipairs(routines) do -- for every thread (coroutine, routine - call it whatever)
- -- there are ALWAYS 3 conditions on when to resume a coroutine in ComputerCraft (only one of them has to be true):
- -- 1. the event is 'terminate'
- -- 2. the event filter of the coroutine is nil
- -- 3. the event filter is equal to the coroutine's event filter
- if event == "terminate" or thread.filter == nil or thread.filter == event then
- local ok, filter = coroutine.resume(thread.co, unpack(e)) -- resume the coroutine with the event data
- if not ok then -- if the coroutine errored, print the error
- error(filter, 2)
- end
- -- if the coroutine ended, add it to remove list
- if coroutine.status(thread.co) == "dead" then
- toRemove[#toRemove + 1] = i
- end
- -- don't forget to set the coroutine's filter! It's the same thing that you pass to os.pullEvent( filter )
- thread.filter = filter
- end
- end
- for i = #toRemove, 1, -1 do -- remove all the dead coroutines
- table.remove(routines, toRemove[i])
- end
- -- 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
- if #routines == 0 then
- break
- end
- -- catch any events and restart the loop to resume the coroutines
- e = {os.pullEventRaw()}
- event = e[1]
- end
- end
- --[[ Test code ]]--
- local function main ()
- print("main")
- sleep(1)
- print("main done")
- end
- local function bar ()
- print("bar")
- for i = 1, 3 do
- sleep(1)
- print("bar ", i)
- end
- end
- local function foo ()
- sleep(1)
- print("foo")
- sleep(1)
- addThread("bar", bar)
- end
- addThread("main", main)
- addThread("foo", foo)
- print("START")
- run()
- print("END")
Advertisement
Add Comment
Please, Sign In to add comment