SHOW:
|
|
- or go back to the newest paste.
| 1 | local sideNames = rs.getSides() | |
| 2 | local sensorSides = {}
| |
| 3 | local sideSelection, targetSelection, targetOffset, detailOffset = 1, 1, 1, 1 | |
| 4 | local detailLines, targetNameMenuTable | |
| 5 | local graphing, graphSide, graphTarget, graphMatch, graphInstance = false | |
| 6 | ||
| 7 | os.loadAPI("ocs/apis/graph")
| |
| 8 | os.loadAPI("ocs/apis/sensor")
| |
| 9 | ||
| 10 | local function checkSensors() | |
| 11 | for _,side in ipairs(sideNames) do | |
| 12 | if peripheral.getType(side) == "sensor" then | |
| 13 | sensorSides[side] = true | |
| 14 | else | |
| 15 | sensorSides[side] = false | |
| 16 | end | |
| 17 | end | |
| 18 | end | |
| 19 | ||
| 20 | local function writeEntry(menuTable, index, cursorPos) | |
| 21 | if cursorPos == index then | |
| 22 | term.setBackgroundColor(term.isColor() and colors.blue or colors.white) | |
| 23 | term.setTextColor(term.isColor() and colors.white or colors.black) | |
| 24 | term.write(string.sub(menuTable[index], 1, 16)) | |
| 25 | term.setBackgroundColor(colors.black) | |
| 26 | term.setTextColor(colors.white) | |
| 27 | else | |
| 28 | term.write(string.sub(menuTable[index], 1, 16)) | |
| 29 | end | |
| 30 | end | |
| 31 | ||
| 32 | local function toLines(currTable, linesTable, trackingTable, depth) | |
| 33 | for k,v in pairs(currTable) do | |
| 34 | if type(v) == "table" then | |
| 35 | table.insert(linesTable, string.rep(" ", depth)..tostring(k)..":")
| |
| 36 | if trackingTable[v] then | |
| 37 | table.insert(linesTable, string.rep(" ", depth + 1).."<Cyclic Reference: "..trackingTable[v]..">")
| |
| 38 | else | |
| 39 | trackingTable[v] = #linesTable | |
| 40 | toLines(v, linesTable, trackingTable, depth + 1) | |
| 41 | end | |
| 42 | else | |
| 43 | table.insert(linesTable, string.rep(" ", depth)..tostring(k).."> "..tostring(v))
| |
| 44 | end | |
| 45 | end | |
| 46 | end | |
| 47 | ||
| 48 | local function drawDividerDown(startY) | |
| 49 | local w, h = term.getSize() | |
| 50 | for i=startY, h do | |
| 51 | term.setCursorPos(17, i) | |
| 52 | term.write("|")
| |
| 53 | end | |
| 54 | end | |
| 55 | ||
| 56 | local function redraw() | |
| 57 | w, h = term.getSize() | |
| 58 | --pre-fetch sensor targets and detailed target information. | |
| 59 | local targetNames = nil | |
| 60 | detailLines = {}
| |
| 61 | checkSensors() | |
| 62 | if sensorSides[sideNames[sideSelection]] then | |
| 63 | targetNames = sensor.call(sideNames[sideSelection], "getSensorName") and sensor.call(sideNames[sideSelection], "getTargets") | |
| 64 | targetNameMenuTable = {}
| |
| 65 | if targetNames then | |
| 66 | for k,v in pairs(targetNames) do | |
| 67 | table.insert(targetNameMenuTable, k) | |
| 68 | end | |
| 69 | table.sort(targetNameMenuTable) | |
| 70 | if #targetNameMenuTable > 0 then | |
| 71 | toLines(sensor.call(sideNames[sideSelection], "getTargetDetails", targetNameMenuTable[targetSelection]), detailLines, {}, 0)
| |
| 72 | end | |
| 73 | end | |
| 74 | end | |
| 75 | --now draw the screen. | |
| 76 | term.clear() | |
| 77 | term.setCursorPos(1, 1) | |
| 78 | term.write("=Sensor Info Viewer="..string.rep("=", w - 20))
| |
| 79 | term.setCursorPos(1, 2) | |
| 80 | for n,side in ipairs(sideNames) do | |
| 81 | if n == sideSelection then | |
| 82 | term.setBackgroundColor(term.isColor() and colors.blue or colors.white) | |
| 83 | term.setTextColor(term.isColor() and colors.white or colors.black) | |
| 84 | term.write(side) | |
| 85 | term.setBackgroundColor(colors.black) | |
| 86 | term.setTextColor(colors.white) | |
| 87 | term.write(" ")
| |
| 88 | else | |
| 89 | term.write(side.." ") | |
| 90 | end | |
| 91 | end | |
| 92 | term.setCursorPos(1, 3) | |
| 93 | term.write("-Targets--------+-Info-"..string.rep("-", w - 23))
| |
| 94 | ||
| 95 | if targetNames then | |
| 96 | --make sure we have valid targets, even if we have a valid sensor. | |
| 97 | if #targetNameMenuTable > 0 then | |
| 98 | term.setCursorPos(1, 4) | |
| 99 | if targetOffset > 1 then | |
| 100 | term.write("/\\")
| |
| 101 | else | |
| 102 | writeEntry(targetNameMenuTable, 1, targetSelection) | |
| 103 | end | |
| 104 | --h-5 to leave room for top and bottom entries. | |
| 105 | for i=1, math.min(h - 5, #targetNameMenuTable - 1) do | |
| 106 | term.setCursorPos(1, i + 4) | |
| 107 | writeEntry(targetNameMenuTable, targetOffset + i, targetSelection) | |
| 108 | end | |
| 109 | if #targetNameMenuTable >= h then | |
| 110 | term.setCursorPos(1, h) | |
| 111 | if #targetNameMenuTable > targetOffset + h - 4 then | |
| 112 | term.write("\\/")
| |
| 113 | else | |
| 114 | writeEntry(targetNameMenuTable, #targetNameMenuTable, targetSelection) | |
| 115 | end | |
| 116 | end | |
| 117 | ||
| 118 | --detailed info. | |
| 119 | for i=1, math.min(h - 3, #detailLines - ((detailOffset - 1) * (h - 3))) do | |
| 120 | term.setCursorPos(17, i + 3) | |
| 121 | term.write("|"..string.sub(detailLines[(detailOffset - 1) * (h - 3) + i], 1, w - 17))
| |
| 122 | end | |
| 123 | local currX, currY = term.getCursorPos() | |
| 124 | drawDividerDown(currY + 1) | |
| 125 | else | |
| 126 | term.setCursorPos(1, 4) | |
| 127 | term.write("No targets found|")
| |
| 128 | drawDividerDown(5) | |
| 129 | end | |
| 130 | else | |
| 131 | if peripheral.getType(sideNames[sideSelection]) == "sensor" then | |
| 132 | term.setCursorPos(1, 4) | |
| 133 | term.write("No sensor card |")
| |
| 134 | drawDividerDown(5) | |
| 135 | else | |
| 136 | term.setCursorPos(1, 4) | |
| 137 | term.write("No sensor found |")
| |
| 138 | drawDividerDown(5) | |
| 139 | end | |
| 140 | end | |
| 141 | term.setCursorPos(1, h) | |
| 142 | end | |
| 143 | ||
| 144 | local function findGraphMatch(currTable, target, matchCount, trackingTable) | |
| 145 | for k, v in pairs(currTable) do | |
| 146 | if type(v) == "table" then | |
| 147 | if trackingTable[v] then return false end | |
| 148 | trackingTable[v] = true | |
| 149 | ret, path, count = findGraphMatch(v, target, matchCount, trackingTable) | |
| 150 | if ret and path then | |
| 151 | return ret, tostring(k).."-"..path | |
| 152 | elseif count then | |
| 153 | matchCount = count | |
| 154 | end | |
| 155 | elseif type(v) == "number" then | |
| 156 | matchCount = matchCount + 1 | |
| 157 | if matchCount == target then return v, tostring(k) end | |
| 158 | end | |
| 159 | end | |
| 160 | return false, nil, matchCount | |
| 161 | end | |
| 162 | ||
| 163 | local function createGraph(targetNum) | |
| 164 | local monSide = "" | |
| 165 | for k, side in ipairs(rs.getSides()) do | |
| 166 | if peripheral.getType(side) == "monitor" then | |
| 167 | monSide = side | |
| 168 | break | |
| 169 | end | |
| 170 | end | |
| 171 | if monSide and targetNum >= 1 and findGraphMatch(sensor.call(graphSide, "getTargetDetails", graphTarget), targetNum, 0, {}) then
| |
| 172 | graphMatch = targetNum | |
| 173 | local val, name = findGraphMatch(sensor.call(graphSide, "getTargetDetails", graphTarget), targetNum, 0, {})
| |
| 174 | local updateFunc = function() return (findGraphMatch(sensor.call(graphSide, "getTargetDetails", graphTarget), graphMatch, 0, {})) end
| |
| 175 | graphInst = graph.new(peripheral.wrap(monSide), updateFunc, name) | |
| 176 | return graphInst | |
| 177 | end | |
| 178 | end | |
| 179 | ||
| 180 | while true do | |
| 181 | redraw() | |
| 182 | local e, p1 = os.pullEvent() | |
| 183 | if e == "key" then | |
| 184 | local w, h = term.getSize() | |
| 185 | if p1 == 203 then | |
| 186 | --left, selects previous side | |
| 187 | if sideSelection > 1 then | |
| 188 | sideSelection = sideSelection - 1 | |
| 189 | targetSelection = 1 | |
| 190 | targetOffset = 1 | |
| 191 | detailOffset = 1 | |
| 192 | detailLines = nil | |
| 193 | end | |
| 194 | elseif p1 == 205 then | |
| 195 | --right, selects next side | |
| 196 | if sideSelection < 6 then | |
| 197 | sideSelection = sideSelection + 1 | |
| 198 | targetSelection = 1 | |
| 199 | targetOffset = 1 | |
| 200 | detailOffset = 1 | |
| 201 | detailLines = nil | |
| 202 | end | |
| 203 | elseif p1 == 200 then | |
| 204 | --up, selects previous target, adjusting offset if necessary. | |
| 205 | if targetSelection > 1 then | |
| 206 | if targetSelection - targetOffset + 1 == 2 and targetOffset > 1 then | |
| 207 | targetOffset = targetOffset - 1 | |
| 208 | end | |
| 209 | targetSelection = targetSelection - 1 | |
| 210 | detailOffset = 1 | |
| 211 | detailLines = nil | |
| 212 | end | |
| 213 | elseif p1 == 208 then | |
| 214 | --down, selects next target, adjusting offset if necessary. | |
| 215 | if targetNameMenuTable and targetSelection < #targetNameMenuTable then | |
| 216 | if targetSelection - targetOffset + 1 == h - 4 and targetSelection ~= #targetNameMenuTable - 1 then | |
| 217 | targetOffset = targetOffset + 1 | |
| 218 | end | |
| 219 | targetSelection = targetSelection + 1 | |
| 220 | detailOffset = 1 | |
| 221 | detailLines = nil | |
| 222 | end | |
| 223 | - | elseif p1 == 201 then |
| 223 | + | elseif p1 == 23 then |
| 224 | - | --pgup, moves detail |
| 224 | + | --I, moves detail |
| 225 | if detailOffset > 1 then | |
| 226 | detailOffset = detailOffset - 1 | |
| 227 | end | |
| 228 | - | elseif p1 == 209 then |
| 228 | + | elseif p1 == 37 then |
| 229 | - | --pgdown, moves detail |
| 229 | + | --K, moves detail |
| 230 | local w, h = term.getSize() | |
| 231 | if detailLines and detailOffset < math.ceil(#detailLines / (h - 3)) then | |
| 232 | detailOffset = detailOffset + 1 | |
| 233 | end | |
| 234 | --and now, since redraw() will eat char events with the change to sensor.call: | |
| 235 | elseif p1 == 31 then --s | |
| 236 | if detailLines then | |
| 237 | local fileHandle = io.open("sensorDetailed-"..sideNames[sideSelection].."-"..targetNameMenuTable[targetSelection], "w")
| |
| 238 | if fileHandle then | |
| 239 | for k, v in ipairs(detailLines) do | |
| 240 | fileHandle:write(v.."\n") | |
| 241 | end | |
| 242 | fileHandle:close() | |
| 243 | end | |
| 244 | end | |
| 245 | elseif p1 == 16 then --q | |
| 246 | sleep(0) | |
| 247 | return | |
| 248 | elseif p1 == 34 then --g | |
| 249 | if graph then | |
| 250 | graphing = not graphing | |
| 251 | if not graphing then | |
| 252 | graphSide = nil | |
| 253 | graphTarget = nil | |
| 254 | graphUpdate = nil | |
| 255 | else | |
| 256 | graphSide = sideNames[sideSelection] | |
| 257 | graphTarget = targetNameMenuTable[targetSelection] | |
| 258 | graphInstance = createGraph(1) | |
| 259 | graphUpdate = os.startTimer(0.5) | |
| 260 | end | |
| 261 | end | |
| 262 | elseif p1 == 49 then --n | |
| 263 | if graphing then | |
| 264 | local newGraph = createGraph(graphMatch + 1) | |
| 265 | if newGraph then | |
| 266 | graphInstance = newGraph | |
| 267 | graphUpdate = os.startTimer(0.5) | |
| 268 | end | |
| 269 | end | |
| 270 | elseif p1 == 25 then --p | |
| 271 | if graphing then | |
| 272 | local newGraph = createGraph(graphMatch - 1) | |
| 273 | if newGraph then | |
| 274 | graphInstance = newGraph | |
| 275 | graphUpdate = os.startTimer(0.5) | |
| 276 | end | |
| 277 | end | |
| 278 | end | |
| 279 | elseif e == "timer" then | |
| 280 | if p1 == graphUpdate then | |
| 281 | graphInstance:draw() | |
| 282 | graphUpdate = os.startTimer(0.5) | |
| 283 | end | |
| 284 | end | |
| 285 | end |