Hiranus

multishell under construction

Oct 6th, 2014
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.31 KB | None | 0 0
  1.  
  2. -- Setup process switching
  3. local parentTerm = term.current()
  4. local w,h = parentTerm.getSize()
  5.  
  6. local tProcesses = {}
  7. local nCurrentProcess = nil
  8. local nRunningProcess = nil
  9. local multishell = {}
  10.  
  11.  
  12.  
  13. function freeSpace (space)
  14.     for i=1,space,1 do
  15.         write(" ")
  16.     end
  17. end
  18.  
  19. function multishell.printTable (tab,dep,...)
  20.     local filter={...}
  21.  
  22.     if dep==nil then
  23.     dep=1
  24.     end
  25.     print ("")
  26.     freeSpace(dep-1)
  27.     print ("{")
  28.     for i,v in pairs (tab) do
  29.         local filMatch=false
  30.         for j,w in pairs (filter) do
  31.             if w==i then
  32.                 filMatch=true
  33.             end
  34.         end
  35.         if not filMatch then
  36.             freeSpace(dep)
  37.             write (i.."    ")
  38.             if type(v) =="table" then
  39.                 dep=dep+1
  40.                 multishell.printTable(v,dep,unpack(filter))
  41.                 dep=dep-1
  42.             else
  43.                 print (v)
  44.             end
  45.             local curX,curY = term.getCursorPos()
  46.             local sizeX,sizeY = term.getSize()
  47.             if curY == sizeY then
  48.                 os.pullEvent("key")
  49.             end
  50.         end
  51.     end
  52.     freeSpace(dep-1)
  53.     print ("}")
  54. end
  55.  
  56. local function selectProcess( n )
  57.     if nCurrentProcess ~= n then
  58.         if nCurrentProcess then
  59.             local tOldProcess = tProcesses[ nCurrentProcess ]
  60.             tOldProcess.window.setVisible( false )
  61.         end
  62.         nCurrentProcess = n
  63.         if nCurrentProcess then
  64.             local tNewProcess = tProcesses[ nCurrentProcess ]
  65.             tNewProcess.window.setVisible( true )
  66.             tNewProcess.bInteracted = true
  67.         end
  68.     end
  69. end
  70.  
  71. local function setProcessTitle( n, sTitle )
  72.     tProcesses[ n ].sTitle = sTitle
  73. end
  74.  
  75. function resumeProcess( nProcess, sEvent, ... )
  76.     local tProcess = tProcesses[ nProcess ]
  77.     local sFilter = tProcess.sFilter
  78.     if sFilter == nil or sFilter == sEvent or sEvent == "terminate" then
  79.         local nPreviousProcess = nRunningProcess
  80.         nRunningProcess = nProcess
  81.         term.redirect( tProcess.terminal )
  82.         local ok, result = coroutine.resume( tProcess.co, sEvent, ... )
  83.         tProcess.terminal = term.current()
  84.         if ok then
  85.             tProcess.sFilter = result
  86.         else
  87.             printError( result )
  88.         end
  89.         nRunningProcess = nPreviousProcess
  90.     end
  91. end
  92.  
  93. function multishell.killProcess (ID)
  94.     if ID~=1 then
  95.         resumeProcess( ID, "terminate")
  96.     end
  97. end
  98. local nLastProcess = 0
  99. local function launchProcess( tProgramEnv, sProgramPath, ... )
  100.     local tProgramArgs = { ... }
  101.     nLastProcess = nLastProcess + 1
  102.     local nProcess = nLastProcess
  103.     local tProcess = {}
  104.     tProcess.sTitle = fs.getName( sProgramPath )
  105.     tProcess.window = window.create( parentTerm, 1, 1, w, h, false )
  106.     tProcess.co = coroutine.create( function()
  107.         --if nLastProcess~=1 then
  108.     --      parallel.waitForAny(
  109.     --      function() os.run( tProgramEnv, sProgramPath, unpack( tProgramArgs ) ) end,
  110.     --      function() endProcess(nProcess) end
  111.     --      )
  112.         --else
  113.             os.run( tProgramEnv, sProgramPath, unpack( tProgramArgs ) )
  114.         --end
  115.         if not tProcess.bInteracted then
  116.             term.setCursorBlink( false )
  117.             print( "Press any key to continue" )
  118.             os.pullEvent( "char" )
  119.         end
  120.         if nCurrentProcess==nProcess then
  121.             selectProcess (1)
  122.         end
  123.     end )
  124.    
  125.     tProcess.sFilter = nil
  126.     tProcess.terminal = tProcess.window
  127.     tProcess.bInteracted = false
  128.     tProcesses[ nProcess ] = tProcess
  129.     resumeProcess( nProcess )
  130.     return nProcess
  131. end
  132.  
  133. local function cullProcess( nProcess )
  134.    
  135.     local tProcess = tProcesses[ nProcess ]
  136.     --printTable(tProcess)
  137.     --local cor = tProcess.co
  138.     --print (cor)
  139.     --print (coroutine.status(cor))
  140.     if coroutine.status( tProcess.co ) == "dead" then
  141.         multishell.printTable(tProcess,1,"window","terminal")
  142.         if nCurrentProcess~=1 then
  143.             if nCurrentProcess == nProcess then
  144.                 selectProcess( 1 )
  145.             end
  146.             if nCurrentProcess~= 1 then
  147.                 tProcesses[ nProcess ] = nil
  148.             end
  149.         end
  150.     end
  151. end
  152.  
  153. local function cullProcesses()
  154.     local culled = false
  155.     for n=multishell.getCount(),1,-1 do
  156.         culled = culled or cullProcess( n )
  157.     end
  158.     return culled
  159. end
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168. function multishell.getFocus()
  169.     return nCurrentProcess
  170. end
  171.  
  172. function multishell.setFocus( n )
  173.     if n >= 1 and n <= multishell.getCount() then
  174.         selectProcess( n )
  175.         return true
  176.     end
  177.     return false
  178. end
  179.  
  180. function multishell.getTitle( n )
  181.     if n >= 1 and n <= multishell.getCount() then
  182.         return tProcesses[n].sTitle
  183.     end
  184.     return nil
  185. end
  186.  
  187. function multishell.setTitle( n, sTitle )
  188.     if n >= 1 and n <= multishell.getCount() then
  189.         setProcessTitle( n, sTitle )
  190.     end
  191. end
  192.  
  193. function multishell.getCurrent()
  194.     return nRunningProcess
  195. end
  196.  
  197. function multishell.launch( tProgramEnv, sProgramPath, ... )
  198.     local previousTerm = term.current()
  199.     local nResult = launchProcess( tProgramEnv, sProgramPath, ... )
  200.     term.redirect( previousTerm )
  201.     return nResult
  202. end
  203.  
  204. function multishell.getCount()
  205.     local count = 0
  206.  
  207.     for id, proc in pairs(tProcesses) do
  208.         count = count + 1
  209.     end
  210.  
  211.     return count
  212. end
  213.  
  214. -- Begin
  215. --parentTerm.clear()
  216. selectProcess( launchProcess( {
  217.     ["shell"] = shell,
  218.     ["multishell"] = multishell,
  219. }, "/rom/programs/shell" ) )
  220.  
  221. -- Run processes
  222. while multishell.getCount() > 0 do
  223.     -- Get the event
  224.     local tEventData = { os.pullEventRaw() }
  225.     local sEvent = tEventData[1]
  226.  
  227.     if sEvent == "char" or sEvent == "key" or sEvent == "paste" or sEvent == "terminate" then
  228.         -- Keyboard event
  229.         -- Passthrough to current process
  230.         resumeProcess( nCurrentProcess, unpack( tEventData ) )
  231.         cullProcess( nCurrentProcess )
  232.  
  233.     elseif sEvent == "mouse_click" or sEvent == "mouse_drag" or sEvent == "mouse_scroll" then
  234.         -- Click event
  235.         local button, x, y = tEventData[2], tEventData[3], tEventData[4]
  236.         -- Passthrough to current process
  237.         resumeProcess( nCurrentProcess, sEvent, button, x, y )
  238.     --  cullProcess( nCurrentProcess )
  239.     elseif sEvent == "process_kill" then
  240.    
  241.         resumeProcess( tEventData[2], unpack( tEventData ) )
  242.  
  243.     else
  244.         -- Other event
  245.         -- Passthrough to all processes
  246.         print (sEvent)
  247.         local nLimit = multishell.getCount() -- Storing this ensures any new things spawned don't get the event
  248.         for n=2,nLimit do
  249.             resumeProcess( n, unpack( tEventData ) )
  250.         end
  251.     --  cullProcesses()
  252.  
  253.     end
  254. end
  255.  
  256. -- Shutdown
  257. term.redirect( parentTerm )
Advertisement
Add Comment
Please, Sign In to add comment