Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Implementation of a redstone switchboard controller.
- -- The controller queries the network for any switchboard endpoints and displays them on a monitor.
- -- Clicking an endpoint on the monitor toggles the output at that endpoint.
- -- Configuration variables.
- local sModemSide = "bottom"
- local sMonitorSide = "back"
- local nTextScale = 1
- -- State variables.
- local tEndPoints = {}
- local tMonitor
- -- Endpoint format:
- -- ID: Computer ID of endpoint
- -- Name: Name of the endpoint
- -- State: Current output state of the endpoint
- -- PosX: Position on screen (X)
- -- PosY: Position on screen (Y)
- -- Len: Size of active area on screen
- -- Initialize the controller.
- local function Initialize()
- print("Controller initializing...")
- -- Initialize the monitor.
- tMonitor = peripheral.wrap(sMonitorSide)
- tMonitor.setTextScale(nTextScale)
- tMonitor.setBackgroundColor(colors.black)
- tMonitor.setTextColor(colors.white)
- tMonitor.setCursorBlink(false)
- tMonitor.clear()
- -- Initialize rednet, and start a global update.
- print("Sending broadcast state request...")
- rednet.open(sModemSide)
- rednet.broadcast({Command="get"}, "switchboard")
- end
- -- Gets the maximum name length of all currently known endpoints.
- local function GetMaxEndpointLength()
- local nIndex
- local nLength = 0
- for nIndex = 1, #tEndPoints do
- if string.len(tEndPoints[nIndex].Name) > nLength then
- nLength = string.len(tEndPoints[nIndex].Name)
- end
- end
- return nLength
- end
- -- Draws the display on the monitor.
- local function DrawDisplay()
- local nPosX = 1
- local nPosY = 1
- local nWidth
- local nHeight
- local nMaxWidth
- local nIndex
- nWidth, nHeight = tMonitor.getSize()
- nMaxWidth = GetMaxEndpointLength()
- for nIndex = 1, #tEndPoints do
- -- Update active area
- tEndPoints[nIndex].PosX = nPosX
- tEndPoints[nIndex].PosY = nPosY
- tEndPoints[nIndex].Len = nMaxWidth + 2
- -- Change background color to represent state.
- tMonitor.setCursorPos(nPosX, nPosY)
- if tEndPoints[nIndex].State == true then
- tMonitor.setBackgroundColor(colors.lime)
- else
- tMonitor.setBackgroundColor(colors.red)
- end
- -- Write to the screen.
- tMonitor.write("[" .. tEndPoints[nIndex].Name .. string.rep(" ", nMaxWidth - string.len(tEndPoints[nIndex].Name)) .. "]")
- -- Update cursor X pos.
- nPosX = nPosX + nMaxWidth + 2
- if nPosX + nMaxWidth + 2 > nWidth then
- -- end of line. Clear to end of line.
- tMonitor.setBackgroundColor(colors.black)
- tMonitor.write(string.rep(" ", nWidth - nPosX))
- -- Update cursor Y pos.
- nPosX = 1
- nPosY = nPosY + 1
- if nPosY > nHeight then
- -- Can't fit any more.
- return
- end
- end
- end
- -- Clear rest of screen.
- while true do
- tMonitor.setCursorPos(nPosX, nPosY)
- tMonitor.setBackgroundColor(colors.black)
- -- Clear to end of line.
- tMonitor.setBackgroundColor(colors.black)
- tMonitor.write(string.rep(" ", nWidth - nPosX))
- -- Cursor update.
- nPosX = 1
- nPosY = nPosY + 1
- if nPosY > nHeight then
- break
- end
- end
- end
- -- Returns an endpoint given X,Y coordinates on the monitor.
- local function GetEndPointFromCoords(nPosX, nPosY)
- local nIndex
- local tEndPoint
- for nIndex = 1, #tEndPoints do
- tEndPoint = tEndPoints[nIndex]
- if tEndPoint.PosY == nPosY then
- if tEndPoint.PosX <= nPosX then
- if tEndPoint.PosX + tEndPoint.Len >= nPosX then
- return tEndPoint
- end
- end
- end
- end
- return nil
- end
- -- Sends a command to the endpoint, setting the output state
- local function SetEndPointState(tEndPoint, bState)
- rednet.send(tEndPoint.ID, {Command="set", State=bState}, "switchboard")
- end
- -- Handles a mouse click on the monitor.
- local function HandleTouch(nPosX, nPosY)
- local tEndPoint
- tEndPoint = GetEndPointFromCoords(nPosX, nPosY)
- if tEndPoint ~= nil then
- SetEndPointState(tEndPoint, not tEndPoint.State)
- end
- end
- -- Handles a rednet message.
- local function HandleRednetMessage(nID, tMessage)
- for nIndex = 1, #tEndPoints do
- if tEndPoints[nIndex].ID == nID then
- tEndPoints[nIndex].Name = tMessage.Name
- tEndPoints[nIndex].State = tMessage.State
- return
- end
- end
- -- Add a new endpoint entry.
- tEndPoints[#tEndPoints + 1] = {ID=nID, Name=tMessage.Name, State=tMessage.State, PosX=-1, PosY=-1, Len=0}
- print("Added new endpoint: " .. tMessage.Name)
- end
- -- Main program.
- Initialize()
- -- Main messaging loop.
- while true do
- local sEvent
- local aParam1
- local aParam2
- local aParam3
- sEvent, aParam1, aParam2, aParam3 = os.pullEvent()
- if sEvent == "monitor_touch" then
- HandleTouch(aParam2, aParam3)
- elseif sEvent == "rednet_message" then
- if aParam3 ~= nil then
- if aParam3 == "switchboard" then
- HandleRednetMessage(aParam1, aParam2)
- DrawDisplay()
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement