Advertisement
kmeinkopf

hive-ui.lua

Mar 11th, 2023 (edited)
822
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.70 KB | None | 0 0
  1. local ser = require('serialization')
  2. local term = require('term')
  3. local comp = require('component')
  4. local pc = require('computer')
  5.  
  6. local MAX_UI_LINES = 8
  7.  
  8. local SIZE_SUFFICES = { 'b', 'kB', 'MB', 'GB' }
  9.  
  10. local function formatSize(size)
  11.   local current = size
  12.   local suffix = 1
  13.  
  14.   while true do
  15.     if current < 1536 or suffix >= #SIZE_SUFFICES then
  16.       return tostring(math.floor(current * 100) / 100) .. SIZE_SUFFICES[suffix]
  17.     end
  18.  
  19.     current = current / 1024.0
  20.     suffix = suffix + 1
  21.   end
  22. end
  23.  
  24. local function startsWith(str, prefix)
  25.   return string.find(str, '^' .. prefix) ~= nil
  26. end
  27.  
  28. local function renderTableLines(stateTable)
  29.   local minX, maxX
  30.   local minZ, maxZ
  31.  
  32.   local tbl = {}
  33.  
  34.   for cell, state in pairs(stateTable) do
  35.     local x, _, z = table.unpack(ser.unserialize(cell))
  36.  
  37.     if tbl[x] == nil then
  38.       tbl[x] = {}
  39.     end
  40.  
  41.     if state.state == 'empty' then
  42.       tbl[x][z] = 'E'
  43.     elseif state.state == '?' then
  44.       tbl[x][z] = '?'
  45.     elseif state.state == 'dried' then
  46.       tbl[x][z] = 'D'
  47.     elseif state.state == 'water' then
  48.       tbl[x][z] = 'W'
  49.     elseif state.state == 'growing' then
  50.       tbl[x][z] = 'P'
  51.     elseif state.state == 'grown' then
  52.       tbl[x][z] = 'G'
  53.     elseif startsWith(state.state, 'obstructed') then
  54.       tbl[x][z] = 'O'
  55.     elseif state.state == 'corrupt' then
  56.       tbl[x][z] = 'X'
  57.     elseif state.state == 'none' then
  58.       tbl[x][z] = 'N'
  59.     else
  60.       tbl[x][z] = '<' .. state.state .. '>'
  61.     end
  62.  
  63.     if minX == nil then
  64.       minX = x
  65.     else
  66.       minX = math.min(minX, x)
  67.     end
  68.     if minZ == nil then
  69.       minZ = z
  70.     else
  71.       minZ = math.min(minZ, z)
  72.     end
  73.     if maxX == nil then
  74.       maxX = x
  75.     else
  76.       maxX = math.max(maxX, x)
  77.     end
  78.     if maxZ == nil then
  79.       maxZ = z
  80.     else
  81.       maxZ = math.max(maxZ, z)
  82.     end
  83.   end
  84.  
  85.   local szX = maxX - minX
  86.   local szZ = maxZ - minZ
  87.  
  88.   local lines = { }
  89.  
  90.   if szX < szZ then
  91.     for x = minX, maxX do
  92.       local line = ''
  93.       for z = minZ, maxZ do
  94.         line = line .. (tbl[x][z] or '!') .. ' '
  95.       end
  96.       table.insert(lines, line)
  97.     end
  98.   else
  99.     for z = minZ, maxZ do
  100.       local line = ''
  101.       for x = minX, maxX do
  102.         line = line .. (tbl[x][z] or '!')
  103.       end
  104.       table.insert(lines, line)
  105.     end
  106.   end
  107.  
  108.   return lines
  109. end
  110.  
  111. local screenWidth, screenHeight = comp.getPrimary('gpu').getResolution()
  112.  
  113. local function drawString(x, y, str)
  114.   term.setCursor(x, y)
  115.   term.write(str)
  116. end
  117.  
  118. local function drawBorderV(pos)
  119.   for i = 1, screenHeight do
  120.     drawString(pos, i, '║')
  121.   end
  122. end
  123.  
  124. local function drawBorderVTil(pos, til)
  125.   local tilRow = til or screenHeight
  126.   for i = 1, tilRow do
  127.     local chr = '║'
  128.     if i == tilRow then
  129.       chr = '╩'
  130.     end
  131.     drawString(pos, i, chr)
  132.   end
  133. end
  134.  
  135. local function drawBorderHTil(pos, til)
  136.   local tilCol = til or screenWidth
  137.  
  138.   for i = 1, tilCol do
  139.     local chr = '═'
  140.     if i == tilCol then
  141.       chr = '╣'
  142.     end
  143.  
  144.     drawString(i, pos, chr)
  145.   end
  146. end
  147.  
  148. local function drawBorderHFrom(pos, from)
  149.   local fromCol = from or 1
  150.  
  151.   for i = fromCol, screenWidth do
  152.     local chr = '═'
  153.     if i == fromCol then
  154.       chr = '╠'
  155.     end
  156.  
  157.     drawString(i, pos, chr)
  158.   end
  159. end
  160.  
  161. local function drawLines(col, row, lines)
  162.   local vpos = row
  163.  
  164.   local lineLength = 0
  165.  
  166.   for _, line in ipairs(lines) do
  167.     drawString(col, vpos, line)
  168.     vpos = vpos + 1
  169.     lineLength = math.max(lineLength, #line)
  170.   end
  171.  
  172.   return vpos, (lineLength + col)
  173. end
  174.  
  175. local function cellStats(stateTable)
  176.   local stats = {}
  177.  
  178.   for _, cell in pairs(stateTable) do
  179.     stats[cell.state] = (stats[cell.state] or 0) + 1
  180.   end
  181.  
  182.   return stats
  183. end
  184.  
  185. local function drawStats(
  186.     stateTable,
  187.     queueStats, runningStats,
  188.     doneStats, failedStats,
  189.     timeoutStats, failures
  190. )
  191.   term.clear()
  192.  
  193.   local vposLeft = 2
  194.   local vposCenter = 2
  195.   local lineLength = 0
  196.  
  197.   local leftBorderPos = 0
  198.  
  199.   if stateTable ~= nil then
  200.     local tableLines = renderTableLines(stateTable)
  201.  
  202.     table.insert(tableLines, 1, '')
  203.     table.insert(tableLines, 1, 'Farm state:')
  204.  
  205.     vposLeft, lineLength = drawLines(2, vposLeft, tableLines)
  206.  
  207.     tableLines = {}
  208.  
  209.     table.insert(tableLines, 'Cell stats:')
  210.     table.insert(tableLines, '')
  211.  
  212.     for state, count in pairs(cellStats(stateTable)) do
  213.       table.insert(tableLines, state .. ' : ' .. tostring(count))
  214.     end
  215.  
  216.     leftBorderPos = lineLength + 2
  217.  
  218.     vposCenter, lineLength = drawLines(leftBorderPos + 2, vposCenter, tableLines)
  219.   end
  220.  
  221.   local borderPos = lineLength + 2
  222.   if lineLength == 0 then
  223.     borderPos = math.floor(screenWidth * 0.6)
  224.   end
  225.  
  226.   vposLeft = math.max(vposLeft, vposCenter) + 2
  227.  
  228.   drawBorderHTil(vposLeft, borderPos)
  229.   drawBorderVTil(leftBorderPos, vposLeft)
  230.   drawBorderV(borderPos)
  231.  
  232.   vposLeft = vposLeft + 2
  233.  
  234.   local vposRight = 2
  235.  
  236.   local lines = {}
  237.  
  238.   table.insert(lines, 'Pending tasks:')
  239.   for name, count in pairs(queueStats) do
  240.     table.insert(lines, name .. ' : ' .. count)
  241.   end
  242.  
  243.   vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
  244.   lines = {}
  245.  
  246.   drawBorderHFrom(vposRight, borderPos)
  247.  
  248.   if vposRight == vposLeft then
  249.     drawString(borderPos, vposRight, '╬')
  250.   end
  251.  
  252.   vposRight = vposRight + 1
  253.  
  254.   table.insert(lines, '')
  255.   table.insert(lines, 'Running tasks:')
  256.   for name, count in pairs(runningStats) do
  257.     table.insert(lines, name .. ' : ' .. count)
  258.   end
  259.  
  260.   vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
  261.   lines = {}
  262.  
  263.   drawBorderHFrom(vposRight, borderPos)
  264.   if vposRight == vposLeft then
  265.     drawString(borderPos, vposRight, '╬')
  266.   end
  267.   vposRight = vposRight + 1
  268.  
  269.   table.insert(lines, '')
  270.   table.insert(lines, 'Completed tasks:')
  271.   for name, count in pairs(doneStats) do
  272.     table.insert(lines, name .. ' : ' .. count)
  273.   end
  274.  
  275.   vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
  276.   lines = {}
  277.  
  278.   drawBorderHFrom(vposRight, borderPos)
  279.   if vposRight == vposLeft then
  280.     drawString(borderPos, vposRight, '╬')
  281.   end
  282.   vposRight = vposRight + 1
  283.  
  284.   table.insert(lines, '')
  285.   table.insert(lines, 'Failed tasks:')
  286.   for name, count in pairs(failedStats) do
  287.     table.insert(lines, name .. ' : ' .. count)
  288.   end
  289.  
  290.   vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
  291.   lines = {}
  292.  
  293.   drawBorderHFrom(vposRight, borderPos)
  294.   if vposRight == vposLeft then
  295.     drawString(borderPos, vposRight, '╬')
  296.   end
  297.   vposRight = vposRight + 1
  298.  
  299.   table.insert(lines, '')
  300.   table.insert(lines, 'Timed out tasks:')
  301.   for name, count in pairs(timeoutStats) do
  302.     table.insert(lines, name .. ' : ' .. count)
  303.   end
  304.  
  305.   vposRight = drawLines(borderPos + 2, vposRight, lines) + 1
  306.   lines = {}
  307.  
  308.   drawBorderHFrom(vposRight, borderPos)
  309.   if vposRight == vposLeft then
  310.     drawString(borderPos, vposRight, '╬')
  311.   end
  312.   vposRight = vposRight + 1
  313.  
  314.   lines = {}
  315.  
  316.   table.insert(lines, 'Task failures: ')
  317.   local minS = math.min(MAX_UI_LINES, #failures)
  318.   for i = 1, minS do
  319.     table.insert(lines, failures[i].name .. '\t' .. failures[i].error)
  320.   end
  321.   if minS < #failures then
  322.     table.insert(lines, '...')
  323.   end
  324.  
  325.   drawLines(2, vposLeft + 2, lines)
  326.  
  327.   drawBorderHFrom(vposRight, borderPos)
  328.   if vposRight == vposLeft then
  329.     drawString(borderPos, vposRight, '╬')
  330.   end
  331.   vposRight = vposRight + 1
  332.  
  333.   drawBorderHFrom(vposRight, borderPos)
  334.   if vposRight == vposLeft then
  335.     drawString(borderPos, vposRight, '╬')
  336.   end
  337.   vposRight = vposRight + 1
  338.  
  339.   drawLines(borderPos + 2, vposRight, {
  340.     'Memory usage: '
  341.         .. formatSize(pc.totalMemory() - pc.freeMemory())
  342.         .. '/' .. formatSize(pc.totalMemory())
  343.   })
  344. end
  345.  
  346. return {
  347.   drawStats = drawStats
  348. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement