Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local ser = require('serialization')
- local term = require('term')
- local comp = require('component')
- local pc = require('computer')
- local MAX_UI_LINES = 8
- local SIZE_SUFFICES = { 'b', 'kB', 'MB', 'GB' }
- local function formatSize(size)
- local current = size
- local suffix = 1
- while true do
- if current < 1536 or suffix >= #SIZE_SUFFICES then
- return tostring(math.floor(current * 100) / 100) .. SIZE_SUFFICES[suffix]
- end
- current = current / 1024.0
- suffix = suffix + 1
- end
- end
- local function startsWith(str, prefix)
- return string.find(str, '^' .. prefix) ~= nil
- end
- local function renderTableLines(stateTable)
- local minX, maxX
- local minZ, maxZ
- local tbl = {}
- for cell, state in pairs(stateTable) do
- local x, _, z = table.unpack(ser.unserialize(cell))
- if tbl[x] == nil then
- tbl[x] = {}
- end
- if state.state == 'empty' then
- tbl[x][z] = 'E'
- elseif state.state == '?' then
- tbl[x][z] = '?'
- elseif state.state == 'dried' then
- tbl[x][z] = 'D'
- elseif state.state == 'water' then
- tbl[x][z] = 'W'
- elseif state.state == 'growing' then
- tbl[x][z] = 'P'
- elseif state.state == 'grown' then
- tbl[x][z] = 'G'
- elseif startsWith(state.state, 'obstructed') then
- tbl[x][z] = 'O'
- elseif state.state == 'corrupt' then
- tbl[x][z] = 'X'
- elseif state.state == 'none' then
- tbl[x][z] = 'N'
- else
- tbl[x][z] = '<' .. state.state .. '>'
- end
- if minX == nil then
- minX = x
- else
- minX = math.min(minX, x)
- end
- if minZ == nil then
- minZ = z
- else
- minZ = math.min(minZ, z)
- end
- if maxX == nil then
- maxX = x
- else
- maxX = math.max(maxX, x)
- end
- if maxZ == nil then
- maxZ = z
- else
- maxZ = math.max(maxZ, z)
- end
- end
- local szX = maxX - minX
- local szZ = maxZ - minZ
- local lines = { }
- if szX < szZ then
- for x = minX, maxX do
- local line = ''
- for z = minZ, maxZ do
- line = line .. (tbl[x][z] or '!') .. ' '
- end
- table.insert(lines, line)
- end
- else
- for z = minZ, maxZ do
- local line = ''
- for x = minX, maxX do
- line = line .. (tbl[x][z] or '!')
- end
- table.insert(lines, line)
- end
- end
- return lines
- end
- local screenWidth, screenHeight = comp.getPrimary('gpu').getResolution()
- local function drawString(x, y, str)
- term.setCursor(x, y)
- term.write(str)
- end
- local function drawBorderV(pos)
- for i = 1, screenHeight do
- drawString(pos, i, '║')
- end
- end
- local function drawBorderVTil(pos, til)
- local tilRow = til or screenHeight
- for i = 1, tilRow do
- local chr = '║'
- if i == tilRow then
- chr = '╩'
- end
- drawString(pos, i, chr)
- end
- end
- local function drawBorderHTil(pos, til)
- local tilCol = til or screenWidth
- for i = 1, tilCol do
- local chr = '═'
- if i == tilCol then
- chr = '╣'
- end
- drawString(i, pos, chr)
- end
- end
- local function drawBorderHFrom(pos, from)
- local fromCol = from or 1
- for i = fromCol, screenWidth do
- local chr = '═'
- if i == fromCol then
- chr = '╠'
- end
- drawString(i, pos, chr)
- end
- end
- local function drawLines(col, row, lines)
- local vpos = row
- local lineLength = 0
- for _, line in ipairs(lines) do
- drawString(col, vpos, line)
- vpos = vpos + 1
- lineLength = math.max(lineLength, #line)
- end
- return vpos, (lineLength + col)
- end
- local function cellStats(stateTable)
- local stats = {}
- for _, cell in pairs(stateTable) do
- stats[cell.state] = (stats[cell.state] or 0) + 1
- end
- return stats
- end
- local function drawStats(
- stateTable,
- queueStats, runningStats,
- doneStats, failedStats,
- timeoutStats, failures
- )
- term.clear()
- local vposLeft = 2
- local vposCenter = 2
- local lineLength = 0
- local leftBorderPos = 0
- if stateTable ~= nil then
- local tableLines = renderTableLines(stateTable)
- table.insert(tableLines, 1, '')
- table.insert(tableLines, 1, 'Farm state:')
- vposLeft, lineLength = drawLines(2, vposLeft, tableLines)
- tableLines = {}
- table.insert(tableLines, 'Cell stats:')
- table.insert(tableLines, '')
- for state, count in pairs(cellStats(stateTable)) do
- table.insert(tableLines, state .. ' : ' .. tostring(count))
- end
- leftBorderPos = lineLength + 2
- vposCenter, lineLength = drawLines(leftBorderPos + 2, vposCenter, tableLines)
- end
- local borderPos = lineLength + 2
- if lineLength == 0 then
- borderPos = math.floor(screenWidth * 0.6)
- end
- vposLeft = math.max(vposLeft, vposCenter) + 2
- drawBorderHTil(vposLeft, borderPos)
- drawBorderVTil(leftBorderPos, vposLeft)
- drawBorderV(borderPos)
- vposLeft = vposLeft + 2
- local vposRight = 2
- local lines = {}
- table.insert(lines, 'Pending tasks:')
- for name, count in pairs(queueStats) do
- table.insert(lines, name .. ' : ' .. count)
- end
- vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
- lines = {}
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- table.insert(lines, '')
- table.insert(lines, 'Running tasks:')
- for name, count in pairs(runningStats) do
- table.insert(lines, name .. ' : ' .. count)
- end
- vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
- lines = {}
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- table.insert(lines, '')
- table.insert(lines, 'Completed tasks:')
- for name, count in pairs(doneStats) do
- table.insert(lines, name .. ' : ' .. count)
- end
- vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
- lines = {}
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- table.insert(lines, '')
- table.insert(lines, 'Failed tasks:')
- for name, count in pairs(failedStats) do
- table.insert(lines, name .. ' : ' .. count)
- end
- vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
- lines = {}
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- table.insert(lines, '')
- table.insert(lines, 'Timed out tasks:')
- for name, count in pairs(timeoutStats) do
- table.insert(lines, name .. ' : ' .. count)
- end
- vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
- lines = {}
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- lines = {}
- table.insert(lines, 'Task failures: ')
- local minS = math.min(MAX_UI_LINES, #failures)
- for i = 1, minS do
- table.insert(lines, failures[i].name .. '\t' .. failures[i].error)
- end
- if minS < #failures then
- table.insert(lines, '...')
- end
- drawLines(2, vposLeft + 2, lines)
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- drawBorderHFrom(vposRight, borderPos)
- if vposRight == vposLeft then
- drawString(borderPos, vposRight, '╬')
- end
- vposRight = vposRight + 1
- drawLines(borderPos + 2, vposRight, {
- 'Memory usage: '
- .. formatSize(pc.totalMemory() - pc.freeMemory())
- .. '/' .. formatSize(pc.totalMemory())
- })
- end
- return {
- drawStats = drawStats
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement