Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function preReq ()
- local col=term.isColour()
- local requiresPocket=false
- if requiresPocket then
- if col and pocket then
- return true
- end
- else
- if col then
- return true
- end
- end
- return false
- end
- -------------------------------------------------------------------------
- --diagnostic stuff
- oldOsVersion=os.version
- os.version = function()
- return oldOsVersion().." & X project"
- end
- ------------------------------------------------------------------------
- function multishells()
- -- Setup process switching
- local parentTerm = term.current()
- local w,h = parentTerm.getSize()
- local tProcesses = {}
- local nCurrentProcess = nil
- local nRunningProcess = nil
- local multishell = {}
- local nLastProcess = 0
- ---------------------------------------------------------------------
- ---Diagnostic stuff
- function freeSpace (space)
- for i=1,space,1 do
- write(" ")
- end
- end
- function multishell.printProcesses()
- multishell.printTable(tProcesses,1,"window","terminal")
- end
- function multishell.printStatus(ID)
- print (coroutine.status(tProcesses[ID].co))
- end
- function multishell.printTable (tab,dep,...)
- local filter={...}
- if dep==nil then
- dep=1
- end
- print ("")
- freeSpace(dep-1)
- print ("{")
- for i,v in pairs (tab) do
- local filMatch=false
- for j,w in pairs (filter) do
- if w==i then
- filMatch=true
- end
- end
- if not filMatch then
- freeSpace(dep)
- write (i.." ")
- if type(v) =="table" then
- dep=dep+1
- multishell.printTable(v,dep,unpack(filter))
- dep=dep-1
- else
- print (v)
- end
- local curX,curY = term.getCursorPos()
- local sizeX,sizeY = term.getSize()
- if curY == sizeY then
- os.pullEvent("key")
- end
- end
- end
- freeSpace(dep-1)
- print ("}")
- end
- ----------------------------------------------------------------------
- local function selectProcess( n )
- if nCurrentProcess ~= n then
- if tProcesses[n] ~= nil then
- if nCurrentProcess then
- local tOldProcess = tProcesses[ nCurrentProcess ]
- tOldProcess.window.setVisible( false )
- end
- nCurrentProcess = n
- if nCurrentProcess then
- local tNewProcess = tProcesses[ nCurrentProcess ]
- tNewProcess.window.setVisible( true )
- tNewProcess.bInteracted = true
- end
- end
- end
- end
- local function setProcessTitle( n, sTitle )
- tProcesses[ n ].sTitle = sTitle
- end
- function resumeProcess( nProcess, sEvent, ... )
- if multishell.isValid(nProcess) then
- local tProcess = tProcesses[ nProcess ]
- --local sFilter = tProcess.sFilter
- -- if sFilter == nil or sFilter == sEvent or sEvent == "terminate" then
- local nPreviousProcess = nRunningProcess
- nRunningProcess = nProcess
- term.redirect( tProcess.terminal )
- local ok, result = coroutine.resume( tProcess.co, sEvent, ... )
- tProcess.terminal = term.current()
- if ok then
- tProcess.sFilter = result
- else
- printError( result )
- end
- nRunningProcess = nPreviousProcess
- --end
- -- else
- -- print ("you failed")
- -- end
- else
- print ("you failed")
- end
- end
- function multishell.killProcess (ID)
- if ID~=1 and multishell.isValid(ID) then
- resumeProcess( ID, "terminate")
- end
- end
- local function launchProcess( tProgramEnv, sProgramPath, ... )
- if not tProgramEnv.multishell then
- tProgramEnv.multishell=multishell
- end
- if not tProgramEnv.shell then
- tProgramEnv.shell=shell
- end
- local tProgramArgs = { ... }
- nLastProcess = nLastProcess + 1
- local nProcess = nLastProcess
- local tProcess = {}
- tProcess.sTitle = fs.getName( sProgramPath )
- tProcess.window = window.create( parentTerm, 1, 1, w, h, false )
- tProcess.co = coroutine.create( function()
- --if nLastProcess~=1 then
- -- parallel.waitForAny(
- -- function() os.run( tProgramEnv, sProgramPath, unpack( tProgramArgs ) ) end,
- -- function() endProcess(nProcess) end
- -- )
- --else
- os.run( tProgramEnv, sProgramPath, unpack( tProgramArgs ) )
- --end
- if not tProcess.bInteracted then
- term.setCursorBlink( false )
- print( "Press any key to continue" )
- os.pullEvent( "char" )
- end
- if nCurrentProcess==nProcess then
- selectProcess (1)
- end
- os.queueEvent("check_Processes")
- end )
- -- tProcess.sFilter = nil
- tProcess.terminal = tProcess.window
- tProcess.bInteracted = false
- tProcesses[ nProcess ] = tProcess
- resumeProcess( nProcess )
- return nProcess
- end
- local function cullProcess( nProcess )
- --if nProcess==nil then
- -- return
- --end
- local tProcess = tProcesses[ nProcess ]
- if tProcess==nil then
- return
- end
- --printTable(tProcess)
- --local cor = tProcess.co
- --print (cor)
- --print (coroutine.status(cor))
- --
- --multishell.printTable(tProcess,1,"window","terminal")
- --print (coroutine.status(tProcess.co))
- --if tProcesses[nProcess].active==false then
- if coroutine.status( tProcess.co ) == "dead" then
- if nCurrentProcess==nProcess then
- selectProcess (1)
- end
- tProcesses[nProcess] = nil
- end
- end
- local function cullProcesses()
- --local culled = false
- --for n=multishell.getCount(),1,-1 do
- --culled = culled or cullProcess( n )
- --end
- --return culled
- for i=1, nLastProcess do
- if multishell.isValid(i) then
- cullProcess( i )
- end
- end
- end
- function multishell.checkProcesses()
- cullProcesses()
- end
- function multishell.isValid(id)
- if tProcesses[id]~=nil then
- return true
- end
- return false
- end
- function multishell.getProcesses()
- local procArray = {}
- local index=1
- for id,proc in pairs(tProcesses) do
- procArray[index]={}
- procArray[index].id=id
- procArray[index].title=proc.sTitle
- index=index+1
- end
- return procArray
- end
- function multishell.getFocus()
- return nCurrentProcess
- end
- function multishell.setFocus( n )
- if multishell.isValid(n) then
- selectProcess( n )
- return true
- end
- return false
- end
- function multishell.getLastID()
- return nLastProcess
- end
- function multishell.getTitle( n )
- if multishell.isValid(n) then
- return tProcesses[n].sTitle
- end
- return nil
- end
- function multishell.setTitle( n, sTitle )
- if multishell.isValid(n) then
- setProcessTitle( n, sTitle )
- end
- end
- function multishell.getCurrent()
- return nRunningProcess
- end
- function multishell.launch( tProgramEnv, sProgramPath, ... )
- local previousTerm = term.current()
- local nResult = launchProcess( tProgramEnv, sProgramPath, ... )
- term.redirect( previousTerm )
- return nResult
- end
- function multishell.getCount()
- local count = 0
- for id, proc in pairs(tProcesses) do
- count = count + 1
- end
- return count
- end
- local jump={false,false}
- -- Begin
- parentTerm.clear()
- selectProcess( launchProcess( {
- ["shell"] = shell,
- ["multishell"] = multishell
- }, "/rom/programs/shell" ) )
- -- Run processes
- while multishell.isValid(1) do
- -- Get the event
- if jump[1] and jump[2] then
- selectProcess(1)
- --print ("jumped")
- end
- local tEventData = { os.pullEventRaw() }
- local sEvent = tEventData[1]
- if sEvent == "check_Processes" then
- cullProcesses()
- elseif sEvent == "terminate" then
- if nCurrentProcess ~= 1 then
- resumeProcess( nCurrentProcess, unpack( tEventData ) )
- cullProcesses()
- end
- elseif sEvent == "tabChangeDisable" then
- jump[1]=false
- jump[2]=false
- elseif sEvent == "key" then
- if jump[1]==false and tEventData[2]==29 then
- jump[1]=true
- os.queueEvent("tabChangeDisable")
- elseif jump[2]==false and tEventData[2]==56 then
- jump[2]=true
- os.queueEvent("tabChangeDisable")
- end
- resumeProcess( nCurrentProcess, unpack( tEventData ) )
- elseif sEvent == "char" or sEvent == "paste" then
- -- Keyboard event
- -- Passthrough to current process
- resumeProcess( nCurrentProcess, unpack( tEventData ) )
- elseif sEvent == "mouse_click" or sEvent == "mouse_drag" or sEvent == "mouse_scroll" then
- -- Click event
- local button, x, y = tEventData[2], tEventData[3], tEventData[4]
- -- Passthrough to current process
- resumeProcess( nCurrentProcess, sEvent, button, x, y )
- elseif sEvent=="send_event" then
- if multishell.isValid(tEventData[2]) then
- local target = tEventData[2]
- tEventData[2] = nRunningProcess
- resumeProcess( target, unpack( tEventData ) )
- end
- else
- -- Other event
- -- Passthrough to all processes
- local nLimit = nLastProcess -- Storing this ensures any new things spawned don't get the event
- for n=1,nLimit do
- if multishell.isValid(n) then
- resumeProcess( n, unpack( tEventData ) )
- end
- end
- end
- end
- -- Shutdown
- term.redirect( parentTerm )
- end
- -----------------------------------------------------------------------------------
- local function run(mainFunc, errFunc)
- local oldOsShutdown, oldCoroutineStatus = os.shutdown, coroutine.status
- if type(mainFunc) ~= "function" then
- error("Nothing to run", 2)
- end
- local function clearScreen()
- term.redirect(type(term.native) == "function" and term.native() or term.native)
- term.setBackgroundColour(colours.black)
- term.setTextColour(colours.white)
- term.setCursorPos(1, 1)
- term.setCursorBlink(false)
- term.clear()
- end
- local function coroutineStatusOverride(...)
- return "dead"
- end
- local function osShutdownOverride()
- clearScreen()
- rednet.close()
- os.unloadAPI("rednet")
- os.loadAPI("/rom/apis/rednet")
- rawset(os, "shutdown", oldOsShutdown)
- rawset(coroutine, "status", oldCoroutineStatus)
- local ok, err = pcall(mainFunc)
- if not ok then
- clearScreen()
- pcall( function()
- if type(errFunc) == "function" then
- errFunc(err)
- else
- printError(err)
- print("Press any key to continue")
- os.pullEvent("key")
- end
- end )
- end
- os.sleep(2)
- os.shutdown()
- end
- rawset(os, "shutdown", osShutdownOverride)
- rawset(coroutine, "status", coroutineStatusOverride)
- end
- if preReq() then
- run(multishells)
- else
- print("You need advanced pocket computer to run X project")
- end
Advertisement
Add Comment
Please, Sign In to add comment