Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Multitasking API for OpenComputers
- Basic steps:
- create a new tasklist with multitask.createTasklist() (it returns a table, which is the tasklist)
- create tasks using multitask.createTask([tasklist], [string], [string], [environment], [boolean])
- (yes, the function that you give to createTask must be in string form as setfenv() doesn't exist anymore and bytecode loading is forbidden in opencomputers)
- run all the tasks using multitask.runAll([tasklist])
- (NOTE: tasks need to yield, they get killed automatically otherwise)
- (NOTE: currently you NEED the keyboard and event API for it to work)
- Functions that are added or edited for tasks:
- - event.pull [edited]: basically just yields the task so "multitasking" actually works
- - sleep([number]) [added]: lets the task sleep for a certain time (same as os.sleep(), but only for the task)
- How to use:
- - Load the library via require
- - Enjoy
- WARNING: This is a testing build and may cause lag or bad performance
- ~Piorjade
- ]]
- local multitask = {}
- function multitask.createTask(tasklist, name, func, env, disableG)
- if not env then env = _G end
- if type(func) ~= "string" then return false, "table, string, code(string), environment expected" end
- if type(tasklist) ~= "table" then return false, "table, string, code(string), environment expected" end
- local event = require("event")
- tasklist[name] = nil
- f = func
- env.event = {}
- for a, b in pairs(event) do
- env.event[a] = b
- end
- if disableG then env._G = env end
- function env.event.pull(filtr, ...)
- local args = {...}
- local timeout = nil
- if type(args[1]) == "number" then timeout = args[1] else timeout = nil end
- if not timeout then
- local tab = nil
- repeat
- tab = {coroutine.yield()}
- if tab ~= nil and tab[1] == (filtr or tab[1]) then
- local notFound = false
- for a, b in ipairs(args) do
- if b ~= nil and tab[a] ~= b then
- notFound = true
- break
- end
- end
- if not notFound then
- return table.unpack(tab)
- end
- end
- until tab ~= nil
- return tab
- else
- local running = true
- local timer = event.timer(timeout, function() running = false end)
- local tab = nil
- while running do
- tab = coroutine.yield()
- if tab ~= nil and tab[1] == (filtr or tab[1]) then
- local notFound = false
- for a, b in ipairs(args) do
- if b ~= nil and tab[a] ~= b then
- notFound = true
- break
- end
- end
- if not notFound then
- return table.unpack(tab)
- end
- end
- end
- return nil
- end
- end
- function env.programQuit()
- tasklist[name].dead = true
- coroutine.yield()
- end
- function env.sleep(count)
- local running = true
- function stopRunning()
- running = false
- end
- local timer = event.timer(count, stopRunning)
- while running do
- coroutine.yield()
- end
- end
- local func, err = load(f, "="..name, "bt", env)
- if not func then return false, err else
- tasklist[name] = {}
- tasklist[name].task = coroutine.create(func)
- tasklist[name].dead = false
- return true
- end
- end
- function multitask.quit(taskName)
- local computer = require("computer")
- computer.pushSignal("multitask_quit", taskName)
- end
- function multitask.runAll(tasklist)
- local evt = {}
- local event = require("event")
- while true do
- for name, task in pairs(tasklist) do
- if type(task) == "table" and task.task and tasklist[name].dead ~= true and name ~= "log" and name ~= "errorLog" then
- local ok, err = coroutine.resume(task.task, table.unpack(evt))
- if not ok then
- tasklist[name].dead = true
- table.insert(tasklist.errorLog, err)
- end
- if coroutine.status(task.task) == "dead" then
- tasklist[name].dead = true
- table.insert(tasklist.log, "Process died: "..name)
- end
- end
- end
- for a, b in pairs(tasklist) do
- if type(b) == "table" and b.dead then
- tasklist:killTask(a)
- end
- end
- evt = {event.pull(0.1)}
- if evt[1] == "multitask_quit" then
- if evt[2] then
- tasklist[evt[2]] = nil
- else
- break
- end
- end
- local counter = 0
- for each, task in pairs(tasklist) do
- counter = counter + 1
- end
- if counter == 0 then break end
- end
- end
- function multitask.createTasklist()
- local tasklist = {}
- tasklist.log = {}
- tasklist.errorLog = {}
- function tasklist:clearLog()
- self.errorLog = {}
- self.log = {}
- end
- function tasklist:killTask(name)
- if name then
- self[name] = {}
- end
- end
- return tasklist
- end
- return multitask
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement