Advertisement
PaymentOption

Multi-Shell simpler

Feb 7th, 2013
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.42 KB | None | 0 0
  1. --[[
  2.     Multishell  Trystan Cannon
  3.                 6 February 2013
  4.                
  5.     This is a clone of the multi-shell program
  6.     posted in the programs section of ComputerCraft
  7.     forums on the day of this file's creation.
  8. ]]--
  9.  
  10. --========================================================
  11. -- Variables:
  12.  
  13. local PROGRAM_PATH  = "rom/programs/shell" -- The program to run an instance of.
  14. local NUM_INSTANCES = 10 -- The number of instances to run of PROGRAM_PATH.
  15.  
  16. local instanceStack   = {} -- The stack/table of instance objects. instaceStack[n] = { thread = coroutine, terminal = table }
  17. local currentInstance = 1  -- The index of the current instance object in the instance stack.
  18. --========================================================
  19.  
  20.  
  21.  
  22. --========================================================
  23. -- Terminal functions:
  24.  
  25. -- Creates and returns a new copy of the term.native function for redirection.
  26. local function createTerminal()
  27.     local terminal = {
  28.         buffer = {}
  29.     }
  30.    
  31.     for index, item in pairs(term.native) do
  32.         terminal[index] = function( ... )
  33.             terminal.buffer[#terminal.buffer + 1] = {functionName = index, parameters = { ... }}
  34.             return item( ... )
  35.         end
  36.     end
  37.    
  38.     terminal.flushBuffer = function()
  39.             for index, item in pairs(terminal.buffer) do
  40.                 term.native[item.functionName](unpack(item.parameters))
  41.             end
  42.     end
  43.     terminal.emptyBuffer = function()
  44.         terminal.buffer = {}
  45.     end
  46.     terminal.clear = function()
  47.         terminal.emptyBuffer()
  48.         term.native.clear()
  49.     end
  50.    
  51.     return terminal
  52. end
  53. --========================================================
  54.  
  55.  
  56. --========================================================
  57. -- Instance functions:
  58.  
  59. -- Creates a new instance object using the global PROGRAM_PATH as the target program.
  60. local function createInstance()
  61.     -- Create the new instance object by making a new thread for the program using coroutine.create() and a new terminal
  62.     -- using createTerminal().
  63.     local thread   = coroutine.create(function()
  64.         while true do
  65.             local eventData   = { os.pullEvent() }
  66.             local hasFinished = coroutine.resume(os.run({}, PROGRAM_PATH), unpack( eventData ))
  67.            
  68.             if hasFinished then
  69.                 return "Finished."
  70.             end
  71.         end
  72.     end)
  73.    
  74.     local instance = { thread = thread, terminal = createTerminal() }
  75.    
  76.     return instance
  77. end
  78.  
  79. -- Fills the instance stack with desired instances of the desired program.
  80. local function initInstanceStack()
  81.     for instanceNum = 1, NUM_INSTANCES do
  82.         instanceStack[instanceNum] = createInstance()
  83.     end
  84. end
  85. --========================================================
  86.  
  87.  
  88.  
  89. --========================================================
  90. -- Main entry point:
  91.  
  92. initInstanceStack()
  93. term.redirect(instanceStack[currentInstance].terminal)
  94.  
  95. while true do
  96.     local eventData = { os.pullEvent() }
  97.    
  98.     -- Handle switching instances before anything else.
  99.     if eventData[1] == "key" and (eventData[2] == keys["leftCtrl"] or eventData[2] == keys["rightCtrl"]) then
  100.         -- Start a timer to make sure we don't discard an event to an instance.
  101.         local keyTimer = os.startTimer(0.8)
  102.         local hotKeyEvent, instanceNumber = os.pullEvent()
  103.        
  104.         -- Swap instances if that is what the user wants to do.
  105.         if hotKeyEvent == "key" and instanceNumber - 1 >= 1 and instanceNumber - 1 <= 10 then
  106.             currentInstance = instanceNumber - 1
  107.             -- Update the current instance.
  108.             term.redirect(instanceStack[currentInstance].terminal)
  109.             term.native.clear()
  110.             term.native.setCursorPos(1, 1)
  111.             instanceStack[currentInstance].terminal.flushBuffer()
  112.            
  113.             -- Nullify the event for this iteration.
  114.             eventData = {}
  115.         end
  116.     end
  117.    
  118.     -- Clean up any dead instances.
  119.     for index, instance in pairs(instanceStack) do
  120.         if coroutine.status(instance.thread) == "dead" then
  121.             instanceStack[index] = nil
  122.         end
  123.     end
  124.    
  125.     -- Update the current thread with this event.
  126.     coroutine.resume(instanceStack[currentInstance].thread, unpack( eventData ))
  127. end
  128.  
  129. -- If the loop breaks, then restore the terminal.
  130. term.redirect(term.native)
  131. --========================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement