Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- kazagistars emulator
- Do whatever you want with it, no rights reserved, as per WTFPL
- (http://sam.zoy.org/wtfpl/COPYING)
- Sometimes you just want to run something as if you didn't have a reactor
- churning away below doing cool things. So, you can use the emulator!
- Just call emulator:run(program) with a file name or function to run, and it
- will be run in parallel with everything else running in the reactor,
- including other emulated programs.
- --]]
- if not emulator then
- if not reactor then error 'emulator: missing dependancy "reactor"' end
- emulator = {}
- emulator.threads = {} -- List of threads
- emulator.waiting = {} -- List of events they are waiting for
- emulator.nextid = 1
- emulator.count = 0
- emulator.run = function(e, program)
- local func
- if type(program) == "string" then
- func = function() shell.run(program) end
- elseif type(program) == "function" then
- func = program
- else
- error("Emulator param must be a program")
- end
- local new = e.nextid
- e.nextid = new + 1
- e.count = e.count + 1
- e.threads[new] = coroutine.create(func)
- e.waiting[new] = "emulator.init"
- reactor:register(nil, "emulator", emulator)
- os.queueEvent("emulator.init")
- end
- emulator.mt = {__call = function(e, event, name, ...)
- local dead = {}
- for id, thread in pairs(e.threads) do
- if (not e.waiting[id]) or (e.waiting[id] == event) then
- success, filter = coroutine.resume(thread, event, ...)
- if not success then
- print("Emulated thread error: "..filter)
- end
- if coroutine.status(thread) == "dead" then
- dead[#dead+1] = id
- end
- e.waiting[id] = filter
- end
- end
- for _,id in ipairs(dead) do
- e.threads[id] = nil
- e.waiting[id] = nil
- e.count = e.count - 1
- end
- if e.count == 0 then reactor:unregister(nil, "emulator") end
- end}
- setmetatable(emulator, emulator.mt)
- end
Advertisement
Add Comment
Please, Sign In to add comment