Advertisement
MadManMarkAu

[CC] Switchboard Controller

May 28th, 2016
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.76 KB | None | 0 0
  1. -- Implementation of a redstone switchboard controller.
  2. -- The controller queries the network for any switchboard endpoints and displays them on a monitor.
  3. -- Clicking an endpoint on the monitor toggles the output at that endpoint.
  4.  
  5. -- Configuration variables.
  6. local sModemSide = "bottom"
  7. local sMonitorSide = "back"
  8. local nTextScale = 1
  9.  
  10. -- State variables.
  11. local tEndPoints = {}
  12. local tMonitor
  13.  
  14. -- Endpoint format:
  15. -- ID: Computer ID of endpoint
  16. -- Name: Name of the endpoint
  17. -- State: Current output state of the endpoint
  18. -- PosX: Position on screen (X)
  19. -- PosY: Position on screen (Y)
  20. -- Len: Size of active area on screen
  21.  
  22. -- Initialize the controller.
  23. local function Initialize()
  24.     print("Controller initializing...")
  25.     -- Initialize the monitor.
  26.     tMonitor = peripheral.wrap(sMonitorSide)
  27.     tMonitor.setTextScale(nTextScale)
  28.     tMonitor.setBackgroundColor(colors.black)
  29.     tMonitor.setTextColor(colors.white)
  30.     tMonitor.setCursorBlink(false)
  31.     tMonitor.clear()
  32.    
  33.     -- Initialize rednet, and start a global update.
  34.     print("Sending broadcast state request...")
  35.     rednet.open(sModemSide)
  36.     rednet.broadcast({Command="get"}, "switchboard")
  37. end
  38.  
  39. -- Gets the maximum name length of all currently known endpoints.
  40. local function GetMaxEndpointLength()
  41.     local nIndex
  42.     local nLength = 0
  43.    
  44.     for nIndex = 1, #tEndPoints do
  45.         if string.len(tEndPoints[nIndex].Name) > nLength then
  46.             nLength = string.len(tEndPoints[nIndex].Name)
  47.         end
  48.     end
  49.    
  50.     return nLength
  51. end
  52.  
  53. -- Draws the display on the monitor.
  54. local function DrawDisplay()
  55.     local nPosX = 1
  56.     local nPosY = 1
  57.     local nWidth
  58.     local nHeight
  59.     local nMaxWidth
  60.     local nIndex
  61.    
  62.     nWidth, nHeight = tMonitor.getSize()
  63.     nMaxWidth = GetMaxEndpointLength()
  64.    
  65.     for nIndex = 1, #tEndPoints do
  66.         -- Update active area
  67.         tEndPoints[nIndex].PosX = nPosX
  68.         tEndPoints[nIndex].PosY = nPosY
  69.         tEndPoints[nIndex].Len = nMaxWidth + 2
  70.        
  71.         -- Change background color to represent state.
  72.         tMonitor.setCursorPos(nPosX, nPosY)
  73.         if tEndPoints[nIndex].State == true then
  74.             tMonitor.setBackgroundColor(colors.lime)
  75.         else
  76.             tMonitor.setBackgroundColor(colors.red)
  77.         end
  78.        
  79.         -- Write to the screen.
  80.         tMonitor.write("[" .. tEndPoints[nIndex].Name .. string.rep(" ", nMaxWidth - string.len(tEndPoints[nIndex].Name)) .. "]")
  81.        
  82.         -- Update cursor X pos.
  83.         nPosX = nPosX + nMaxWidth + 2
  84.         if nPosX + nMaxWidth + 2 > nWidth then
  85.             -- end of line. Clear to end of line.
  86.             tMonitor.setBackgroundColor(colors.black)
  87.             tMonitor.write(string.rep(" ", nWidth - nPosX))
  88.  
  89.             -- Update cursor Y pos.
  90.             nPosX = 1
  91.             nPosY = nPosY + 1
  92.             if nPosY > nHeight then
  93.                 -- Can't fit any more.
  94.                 return
  95.             end
  96.         end
  97.     end
  98.  
  99.     -- Clear rest of screen.
  100.     while true do
  101.         tMonitor.setCursorPos(nPosX, nPosY)
  102.         tMonitor.setBackgroundColor(colors.black)
  103.  
  104.         -- Clear to end of line.
  105.         tMonitor.setBackgroundColor(colors.black)
  106.         tMonitor.write(string.rep(" ", nWidth - nPosX))
  107.  
  108.         -- Cursor update.
  109.         nPosX = 1
  110.         nPosY = nPosY + 1
  111.         if nPosY > nHeight then
  112.             break
  113.         end
  114.     end
  115. end
  116.  
  117. -- Returns an endpoint given X,Y coordinates on the monitor.
  118. local function GetEndPointFromCoords(nPosX, nPosY)
  119.     local nIndex
  120.     local tEndPoint
  121.  
  122.     for nIndex = 1, #tEndPoints do
  123.         tEndPoint = tEndPoints[nIndex]
  124.        
  125.         if tEndPoint.PosY == nPosY then
  126.             if tEndPoint.PosX <= nPosX then
  127.                 if tEndPoint.PosX + tEndPoint.Len >= nPosX then
  128.                     return tEndPoint
  129.                 end
  130.             end
  131.         end
  132.     end
  133.    
  134.     return nil
  135. end
  136.  
  137. -- Sends a command to the endpoint, setting the output state
  138. local function SetEndPointState(tEndPoint, bState)
  139.     rednet.send(tEndPoint.ID, {Command="set", State=bState}, "switchboard")
  140. end
  141.  
  142. -- Handles a mouse click on the monitor.
  143. local function HandleTouch(nPosX, nPosY)
  144.     local tEndPoint
  145.    
  146.     tEndPoint = GetEndPointFromCoords(nPosX, nPosY)
  147.    
  148.     if tEndPoint ~= nil then
  149.         SetEndPointState(tEndPoint, not tEndPoint.State)
  150.     end
  151. end
  152.  
  153. -- Handles a rednet message.
  154. local function HandleRednetMessage(nID, tMessage)
  155.     for nIndex = 1, #tEndPoints do
  156.         if tEndPoints[nIndex].ID == nID then
  157.             tEndPoints[nIndex].Name = tMessage.Name
  158.             tEndPoints[nIndex].State = tMessage.State
  159.             return
  160.         end
  161.     end
  162.    
  163.     -- Add a new endpoint entry.
  164.     tEndPoints[#tEndPoints + 1] = {ID=nID, Name=tMessage.Name, State=tMessage.State, PosX=-1, PosY=-1, Len=0}
  165.     print("Added new endpoint: " .. tMessage.Name)
  166. end
  167.  
  168. -- Main program.
  169.  
  170. Initialize()
  171.  
  172. -- Main messaging loop.
  173. while true do
  174.     local sEvent
  175.     local aParam1
  176.     local aParam2
  177.     local aParam3
  178.    
  179.     sEvent, aParam1, aParam2, aParam3 = os.pullEvent()
  180.    
  181.     if sEvent == "monitor_touch" then
  182.         HandleTouch(aParam2, aParam3)
  183.     elseif sEvent == "rednet_message" then
  184.         if aParam3 ~= nil then
  185.             if aParam3 == "switchboard" then
  186.                 HandleRednetMessage(aParam1, aParam2)
  187.                 DrawDisplay()
  188.             end
  189.         end
  190.     end
  191. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement