Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local sideNames = rs.getSides()
- local sensorSides = {}
- local sideSelection, targetSelection, targetOffset, detailOffset = 1, 1, 1, 1
- local detailLines, targetNameMenuTable
- local graphing, graphSide, graphTarget, graphMatch, graphInstance = false
- os.loadAPI("ocs/apis/graph")
- os.loadAPI("ocs/apis/sensor")
- local function checkSensors()
- for _,side in ipairs(sideNames) do
- if peripheral.getType(side) == "sensor" then
- sensorSides[side] = true
- else
- sensorSides[side] = false
- end
- end
- end
- local function writeEntry(menuTable, index, cursorPos)
- if cursorPos == index then
- term.setBackgroundColor(term.isColor() and colors.blue or colors.white)
- term.setTextColor(term.isColor() and colors.white or colors.black)
- term.write(string.sub(menuTable[index], 1, 16))
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- else
- term.write(string.sub(menuTable[index], 1, 16))
- end
- end
- local function toLines(currTable, linesTable, trackingTable, depth)
- for k,v in pairs(currTable) do
- if type(v) == "table" then
- table.insert(linesTable, string.rep(" ", depth)..tostring(k)..":")
- if trackingTable[v] then
- table.insert(linesTable, string.rep(" ", depth + 1).."<Cyclic Reference: "..trackingTable[v]..">")
- else
- trackingTable[v] = #linesTable
- toLines(v, linesTable, trackingTable, depth + 1)
- end
- else
- table.insert(linesTable, string.rep(" ", depth)..tostring(k).."> "..tostring(v))
- end
- end
- end
- local function drawDividerDown(startY)
- local w, h = term.getSize()
- for i=startY, h do
- term.setCursorPos(17, i)
- term.write("|")
- end
- end
- local function redraw()
- w, h = term.getSize()
- --pre-fetch sensor targets and detailed target information.
- local targetNames = nil
- detailLines = {}
- checkSensors()
- if sensorSides[sideNames[sideSelection]] then
- targetNames = sensor.call(sideNames[sideSelection], "getSensorName") and sensor.call(sideNames[sideSelection], "getTargets")
- targetNameMenuTable = {}
- if targetNames then
- for k,v in pairs(targetNames) do
- table.insert(targetNameMenuTable, k)
- end
- table.sort(targetNameMenuTable)
- if #targetNameMenuTable > 0 then
- toLines(sensor.call(sideNames[sideSelection], "getTargetDetails", targetNameMenuTable[targetSelection]), detailLines, {}, 0)
- end
- end
- end
- --now draw the screen.
- term.clear()
- term.setCursorPos(1, 1)
- term.write("=Sensor Info Viewer="..string.rep("=", w - 20))
- term.setCursorPos(1, 2)
- for n,side in ipairs(sideNames) do
- if n == sideSelection then
- term.setBackgroundColor(term.isColor() and colors.blue or colors.white)
- term.setTextColor(term.isColor() and colors.white or colors.black)
- term.write(side)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.write(" ")
- else
- term.write(side.." ")
- end
- end
- term.setCursorPos(1, 3)
- term.write("-Targets--------+-Info-"..string.rep("-", w - 23))
- if targetNames then
- --make sure we have valid targets, even if we have a valid sensor.
- if #targetNameMenuTable > 0 then
- term.setCursorPos(1, 4)
- if targetOffset > 1 then
- term.write("/\\")
- else
- writeEntry(targetNameMenuTable, 1, targetSelection)
- end
- --h-5 to leave room for top and bottom entries.
- for i=1, math.min(h - 5, #targetNameMenuTable - 1) do
- term.setCursorPos(1, i + 4)
- writeEntry(targetNameMenuTable, targetOffset + i, targetSelection)
- end
- if #targetNameMenuTable >= h then
- term.setCursorPos(1, h)
- if #targetNameMenuTable > targetOffset + h - 4 then
- term.write("\\/")
- else
- writeEntry(targetNameMenuTable, #targetNameMenuTable, targetSelection)
- end
- end
- --detailed info.
- for i=1, math.min(h - 3, #detailLines - ((detailOffset - 1) * (h - 3))) do
- term.setCursorPos(17, i + 3)
- term.write("|"..string.sub(detailLines[(detailOffset - 1) * (h - 3) + i], 1, w - 17))
- end
- local currX, currY = term.getCursorPos()
- drawDividerDown(currY + 1)
- else
- term.setCursorPos(1, 4)
- term.write("No targets found|")
- drawDividerDown(5)
- end
- else
- if peripheral.getType(sideNames[sideSelection]) == "sensor" then
- term.setCursorPos(1, 4)
- term.write("No sensor card |")
- drawDividerDown(5)
- else
- term.setCursorPos(1, 4)
- term.write("No sensor found |")
- drawDividerDown(5)
- end
- end
- term.setCursorPos(1, h)
- end
- local function findGraphMatch(currTable, target, matchCount, trackingTable)
- for k, v in pairs(currTable) do
- if type(v) == "table" then
- if trackingTable[v] then return false end
- trackingTable[v] = true
- ret, path, count = findGraphMatch(v, target, matchCount, trackingTable)
- if ret and path then
- return ret, tostring(k).."-"..path
- elseif count then
- matchCount = count
- end
- elseif type(v) == "number" then
- matchCount = matchCount + 1
- if matchCount == target then return v, tostring(k) end
- end
- end
- return false, nil, matchCount
- end
- local function createGraph(targetNum)
- local monSide = ""
- for k, side in ipairs(rs.getSides()) do
- if peripheral.getType(side) == "monitor" then
- monSide = side
- break
- end
- end
- if monSide and targetNum >= 1 and findGraphMatch(sensor.call(graphSide, "getTargetDetails", graphTarget), targetNum, 0, {}) then
- graphMatch = targetNum
- local val, name = findGraphMatch(sensor.call(graphSide, "getTargetDetails", graphTarget), targetNum, 0, {})
- local updateFunc = function() return (findGraphMatch(sensor.call(graphSide, "getTargetDetails", graphTarget), graphMatch, 0, {})) end
- graphInst = graph.new(peripheral.wrap(monSide), updateFunc, name)
- return graphInst
- end
- end
- while true do
- redraw()
- local e, p1 = os.pullEvent()
- if e == "key" then
- local w, h = term.getSize()
- if p1 == 203 then
- --left, selects previous side
- if sideSelection > 1 then
- sideSelection = sideSelection - 1
- targetSelection = 1
- targetOffset = 1
- detailOffset = 1
- detailLines = nil
- end
- elseif p1 == 205 then
- --right, selects next side
- if sideSelection < 6 then
- sideSelection = sideSelection + 1
- targetSelection = 1
- targetOffset = 1
- detailOffset = 1
- detailLines = nil
- end
- elseif p1 == 200 then
- --up, selects previous target, adjusting offset if necessary.
- if targetSelection > 1 then
- if targetSelection - targetOffset + 1 == 2 and targetOffset > 1 then
- targetOffset = targetOffset - 1
- end
- targetSelection = targetSelection - 1
- detailOffset = 1
- detailLines = nil
- end
- elseif p1 == 208 then
- --down, selects next target, adjusting offset if necessary.
- if targetNameMenuTable and targetSelection < #targetNameMenuTable then
- if targetSelection - targetOffset + 1 == h - 4 and targetSelection ~= #targetNameMenuTable - 1 then
- targetOffset = targetOffset + 1
- end
- targetSelection = targetSelection + 1
- detailOffset = 1
- detailLines = nil
- end
- elseif p1 == 201 then
- --pgup, moves detail
- if detailOffset > 1 then
- detailOffset = detailOffset - 1
- end
- elseif p1 == 209 then
- --pgdown, moves detail
- local w, h = term.getSize()
- if detailLines and detailOffset < math.ceil(#detailLines / (h - 3)) then
- detailOffset = detailOffset + 1
- end
- --and now, since redraw() will eat char events with the change to sensor.call:
- elseif p1 == 31 then --s
- if detailLines then
- local fileHandle = io.open("sensorDetailed-"..sideNames[sideSelection].."-"..targetNameMenuTable[targetSelection], "w")
- if fileHandle then
- for k, v in ipairs(detailLines) do
- fileHandle:write(v.."\n")
- end
- fileHandle:close()
- end
- end
- elseif p1 == 16 then --q
- sleep(0)
- return
- elseif p1 == 34 then --g
- if graph then
- graphing = not graphing
- if not graphing then
- graphSide = nil
- graphTarget = nil
- graphUpdate = nil
- else
- graphSide = sideNames[sideSelection]
- graphTarget = targetNameMenuTable[targetSelection]
- graphInstance = createGraph(1)
- graphUpdate = os.startTimer(0.5)
- end
- end
- elseif p1 == 49 then --n
- if graphing then
- local newGraph = createGraph(graphMatch + 1)
- if newGraph then
- graphInstance = newGraph
- graphUpdate = os.startTimer(0.5)
- end
- end
- elseif p1 == 25 then --p
- if graphing then
- local newGraph = createGraph(graphMatch - 1)
- if newGraph then
- graphInstance = newGraph
- graphUpdate = os.startTimer(0.5)
- end
- end
- end
- elseif e == "timer" then
- if p1 == graphUpdate then
- graphInstance:draw()
- graphUpdate = os.startTimer(0.5)
- end
- end
- end
Add Comment
Please, Sign In to add comment