Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Setup process switching
- local parentTerm = term.current()
- local w,h = parentTerm.getSize()
- local tProcesses = {}
- local nCurrentProcess = nil
- local nRunningProcess = nil
- local multishell = {}
- function freeSpace (space)
- for i=1,space,1 do
- write(" ")
- end
- 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 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
- local function setProcessTitle( n, sTitle )
- tProcesses[ n ].sTitle = sTitle
- end
- function resumeProcess( nProcess, sEvent, ... )
- 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
- end
- function multishell.killProcess (ID)
- if ID~=1 then
- resumeProcess( ID, "terminate")
- end
- end
- local nLastProcess = 0
- local function launchProcess( tProgramEnv, sProgramPath, ... )
- 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
- end )
- tProcess.sFilter = nil
- tProcess.terminal = tProcess.window
- tProcess.bInteracted = false
- tProcesses[ nProcess ] = tProcess
- resumeProcess( nProcess )
- return nProcess
- end
- local function cullProcess( nProcess )
- local tProcess = tProcesses[ nProcess ]
- --printTable(tProcess)
- --local cor = tProcess.co
- --print (cor)
- --print (coroutine.status(cor))
- if coroutine.status( tProcess.co ) == "dead" then
- multishell.printTable(tProcess,1,"window","terminal")
- if nCurrentProcess~=1 then
- if nCurrentProcess == nProcess then
- selectProcess( 1 )
- end
- if nCurrentProcess~= 1 then
- tProcesses[ nProcess ] = nil
- end
- end
- end
- end
- local function cullProcesses()
- local culled = false
- for n=multishell.getCount(),1,-1 do
- culled = culled or cullProcess( n )
- end
- return culled
- end
- function multishell.getFocus()
- return nCurrentProcess
- end
- function multishell.setFocus( n )
- if n >= 1 and n <= multishell.getCount() then
- selectProcess( n )
- return true
- end
- return false
- end
- function multishell.getTitle( n )
- if n >= 1 and n <= multishell.getCount() then
- return tProcesses[n].sTitle
- end
- return nil
- end
- function multishell.setTitle( n, sTitle )
- if n >= 1 and n <= multishell.getCount() 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
- -- Begin
- --parentTerm.clear()
- selectProcess( launchProcess( {
- ["shell"] = shell,
- ["multishell"] = multishell,
- }, "/rom/programs/shell" ) )
- -- Run processes
- while multishell.getCount() > 0 do
- -- Get the event
- local tEventData = { os.pullEventRaw() }
- local sEvent = tEventData[1]
- if sEvent == "char" or sEvent == "key" or sEvent == "paste" or sEvent == "terminate" then
- -- Keyboard event
- -- Passthrough to current process
- resumeProcess( nCurrentProcess, unpack( tEventData ) )
- cullProcess( nCurrentProcess )
- 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 )
- -- cullProcess( nCurrentProcess )
- elseif sEvent == "process_kill" then
- resumeProcess( tEventData[2], unpack( tEventData ) )
- else
- -- Other event
- -- Passthrough to all processes
- print (sEvent)
- local nLimit = multishell.getCount() -- Storing this ensures any new things spawned don't get the event
- for n=2,nLimit do
- resumeProcess( n, unpack( tEventData ) )
- end
- -- cullProcesses()
- end
- end
- -- Shutdown
- term.redirect( parentTerm )
Advertisement
Add Comment
Please, Sign In to add comment