diff --git a/Libraries/graphics/colors.lua b/Libraries/graphics/colors.lua index d1288dd..eed19dd 100644 --- a/Libraries/graphics/colors.lua +++ b/Libraries/graphics/colors.lua @@ -5,37 +5,50 @@ local colors = { magenta = 0xFF00FF, yellow = 0xFFFF00, cyan = 0x00FFFF, + greenYellow = 0xADFF2F, green = 0x008000, + darkOliveGreen = 0x556B2F, + indigo = 0x4B0082, purple = 0x800080, + deepSkyBlue = 0x00BFFF, + dodgerBlue = 0x1E90FF, steelBlue = 0x4682B4, - brown = 0xA52A2A, - chocolate = 0xD2691E, + darkSlateBlue = 0x483D8B, + midnightBlue = 0x191970, + navy = 0x000080, + darkOrange = 0xFFA500, rosyBrown = 0xBC8F8F, + goldenRod = 0xDAA520, + chocolate = 0xD2691E, + brown = 0xA52A2A, + maroon = 0x800000, white = 0xFFFFFF, lightGray = 0xD3D3D3, darkGray = 0xA9A9A9, darkSlateGrey = 0x2F4F4F, + notBlack = 0x181828, black = 0x000000 } ---[[ local newColors = { - machineBackground = colors.darkGray, - progressBackground = colors.lightGray, - labelColor = colors.chocolate, - errorColor = colors.red, - idleColor = colors.purple, - workingColor = colors.steelBlue, - positiveEUColor = colors.lime, - negativeEUColor = colors.brown, - timeColor = colors.purple, - textColor = colors.black, - hudColor = colors.darkSlateGrey, - mainColor = colors.rosyBrown, background = colors.black, + machineBackground = colors.notBlack, + progressBackground = colors.indigo, + barColor = colors.deepSkyBlue, + labelColor = colors.goldenRod, + idleColor = colors.lime, + workingColor = colors.deepSkyBlue, + offColor = colors.brown, + errorColor = colors.red, + positiveEUColor = colors.lime, + negativeEUColor = colors.red, + timeColor = colors.purple, + textColor = colors.steelBlue, + hudColor = colors.darkSlateGrey, + mainColor = colors.goldenRod, accentA = colors.cyan, - accentB = colors.magenta, - barColor = colors.blue + accentB = colors.blue } for name, color in pairs(newColors) do @@ -58,13 +71,15 @@ end colors.RGB = RGB +--]] setmetatable( colors, { __index = function(self, color) - return self.RGB[color] or 0, 0, 0 + return self[color] or 0, 0, 0 end } ) + --]] return colors diff --git a/Libraries/graphics/doubleBuffering.lua b/Libraries/graphics/doubleBuffering.lua new file mode 100644 index 0000000..933f6d1 --- /dev/null +++ b/Libraries/graphics/doubleBuffering.lua @@ -0,0 +1,795 @@ +local component = require("component") +local unicode = require("unicode") +Computer = require("computer") +-------------------------------------------------------------------------------- + +local bufferWidth, bufferHeight +local currentFrameBackgrounds, + currentFrameForegrounds, + currentFrameSymbols, + newFrameBackgrounds, + newFrameForegrounds, + newFrameSymbols +local drawLimitX1, drawLimitX2, drawLimitY1, drawLimitY2 +local GPUProxy, + GPUProxyGetResolution, + GPUProxySetResolution, + GPUProxyBind, + GPUProxySetBackground, + GPUProxySetForeground, + GPUProxySet + +local mathCeil, mathFloor, mathAbs = math.ceil, math.floor, math.abs +local tableInsert, tableConcat = table.insert, table.concat +local colorBlend +if Computer.getArchitecture and Computer.getArchitecture() == "Lua 5.3" then + colorBlend = load([[function(color1, color2, transparency) + local invertedTransparency = 1 - transparency + return ((color2 >> 16) * invertedTransparency + (color1 >> 16) * transparency) // 1 << 16 | + ((color2 >> 8 & 0xFF) * invertedTransparency + (color1 >> 8 & 0xFF) * transparency) // 1 << 8 | + ((color2 & 0xFF) * invertedTransparency + (color1 & 0xFF) * transparency) // 1 + end]]) +else + colorBlend = load([[function(color1, color2, transparency) + local invertedTransparency = 1 - transparency + + local r1 = color1 / 65536 + r1 = r1 - r1 % 1 + local g1 = (color1 - r1 * 65536) / 256 + g1 = g1 - g1 % 1 + + local r2 = color2 / 65536 + r2 = r2 - r2 % 1 + local g2 = (color2 - r2 * 65536) / 256 + g2 = g2 - g2 % 1 + + local r, g, b = + r2 * invertedTransparency + r1 * transparency, + g2 * invertedTransparency + g1 * transparency, + (color2 - r2 * 65536 - g2 * 256) * invertedTransparency + (color1 - r1 * 65536 - g1 * 256) * transparency + + return (r - r % 1) * 65536 + (g - g % 1) * 256 + (b - b % 1) + end]]) +end +local unicodeLen, unicodeSub = unicode.len, unicode.sub + +-------------------------------------------------------------------------------- + +local function getIndex(x, y) + return bufferWidth * (y - 1) + x +end + +local function getCurrentFrameTables() + return currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols +end + +local function getNewFrameTables() + return newFrameBackgrounds, newFrameForegrounds, newFrameSymbols +end + +-------------------------------------------------------------------------------- + +local function setDrawLimit(x1, y1, x2, y2) + drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = x1, y1, x2, y2 +end + +local function resetDrawLimit() + drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = 1, 1, bufferWidth, bufferHeight +end + +local function getDrawLimit() + return drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 +end + +-------------------------------------------------------------------------------- + +local function flush(width, height) + if not width or not height then + width, height = GPUProxyGetResolution() + end + + currentFrameBackgrounds, + currentFrameForegrounds, + currentFrameSymbols, + newFrameBackgrounds, + newFrameForegrounds, + newFrameSymbols = {}, {}, {}, {}, {}, {} + bufferWidth = width + bufferHeight = height + resetDrawLimit() + + for y = 1, bufferHeight do + for x = 1, bufferWidth do + tableInsert(currentFrameBackgrounds, 0x010101) + tableInsert(currentFrameForegrounds, 0xFEFEFE) + tableInsert(currentFrameSymbols, " ") + + tableInsert(newFrameBackgrounds, 0x010101) + tableInsert(newFrameForegrounds, 0xFEFEFE) + tableInsert(newFrameSymbols, " ") + end + end +end + +local function setResolution(width, height) + GPUProxySetResolution(width, height) + flush(width, height) +end + +local function getResolution() + return bufferWidth, bufferHeight +end + +local function getWidth() + return bufferWidth +end + +local function getHeight() + return bufferHeight +end + +local function bindScreen(...) + GPUProxyBind(...) + flush(GPUProxyGetResolution()) +end + +local function getGPUProxy() + return GPUProxy +end + +local function updateGPUProxyMethods() + GPUProxyGet = GPUProxy.get + GPUProxyGetResolution = GPUProxy.getResolution + GPUProxyGetBackground = GPUProxy.getBackground + GPUProxyGetForeground = GPUProxy.getForeground + + GPUProxySet = GPUProxy.set + GPUProxySetResolution = GPUProxy.setResolution + GPUProxySetBackground = GPUProxy.setBackground + GPUProxySetForeground = GPUProxy.setForeground + + GPUProxyBind = GPUProxy.bind + GPUProxyFill = GPUProxy.fill +end + +local function bindGPU(address) + GPUProxy = component.proxy(address) + updateGPUProxyMethods() + flush(GPUProxyGetResolution()) +end + +-------------------------------------------------------------------------------- + +local function rawSet(index, background, foreground, symbol) + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol +end + +local function rawGet(index) + return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] +end + +local function get(x, y) + if x >= 1 and y >= 1 and x <= bufferWidth and y <= bufferHeight then + local index = bufferWidth * (y - 1) + x + return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] + else + return 0x000000, 0x000000, " " + end +end + +local function set(x, y, background, foreground, symbol) + if x >= drawLimitX1 and y >= drawLimitY1 and x <= drawLimitX2 and y <= drawLimitY2 then + local index = bufferWidth * (y - 1) + x + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol + end +end + +local function drawRectangle(x, y, width, height, background, foreground, symbol, transparency) + local index, indexStepOnReachOfSquareWidth = bufferWidth * (y - 1) + x, bufferWidth - width + for j = y, y + height - 1 do + if j >= drawLimitY1 and j <= drawLimitY2 then + for i = x, x + width - 1 do + if i >= drawLimitX1 and i <= drawLimitX2 then + if transparency then + newFrameBackgrounds[index], newFrameForegrounds[index] = + colorBlend(newFrameBackgrounds[index], background, transparency), + colorBlend(newFrameForegrounds[index], background, transparency) + else + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + background, + foreground, + symbol + end + end + + index = index + 1 + end + + index = index + indexStepOnReachOfSquareWidth + else + index = index + bufferWidth + end + end +end + +local function clear(color, transparency) + drawRectangle(1, 1, bufferWidth, bufferHeight, color or 0x0, 0x000000, " ", transparency) +end + +local function copy(x, y, width, height) + local copyArray, index = {width, height} + + for j = y, y + height - 1 do + for i = x, x + width - 1 do + if i >= 1 and j >= 1 and i <= bufferWidth and j <= bufferHeight then + index = bufferWidth * (j - 1) + i + tableInsert(copyArray, newFrameBackgrounds[index]) + tableInsert(copyArray, newFrameForegrounds[index]) + tableInsert(copyArray, newFrameSymbols[index]) + else + tableInsert(copyArray, 0x0) + tableInsert(copyArray, 0x0) + tableInsert(copyArray, " ") + end + end + end + + return copyArray +end + +local function paste(startX, startY, picture) + local imageWidth = picture[1] + local bufferIndex, pictureIndex, bufferIndexStepOnReachOfImageWidth = + bufferWidth * (startY - 1) + startX, + 3, + bufferWidth - imageWidth + + for y = startY, startY + picture[2] - 1 do + if y >= drawLimitY1 and y <= drawLimitY2 then + for x = startX, startX + imageWidth - 1 do + if x >= drawLimitX1 and x <= drawLimitX2 then + newFrameBackgrounds[bufferIndex] = picture[pictureIndex] + newFrameForegrounds[bufferIndex] = picture[pictureIndex + 1] + newFrameSymbols[bufferIndex] = picture[pictureIndex + 2] + end + + bufferIndex, pictureIndex = bufferIndex + 1, pictureIndex + 3 + end + + bufferIndex = bufferIndex + bufferIndexStepOnReachOfImageWidth + else + bufferIndex, pictureIndex = bufferIndex + bufferWidth, pictureIndex + imageWidth * 3 + end + end +end + +local function rasterizeLine(x1, y1, x2, y2, method) + local inLoopValueFrom, + inLoopValueTo, + outLoopValueFrom, + outLoopValueTo, + isReversed, + inLoopValueDelta, + outLoopValueDelta = x1, x2, y1, y2, false, mathAbs(x2 - x1), mathAbs(y2 - y1) + if inLoopValueDelta < outLoopValueDelta then + inLoopValueFrom, + inLoopValueTo, + outLoopValueFrom, + outLoopValueTo, + isReversed, + inLoopValueDelta, + outLoopValueDelta = y1, y2, x1, x2, true, outLoopValueDelta, inLoopValueDelta + end + + if outLoopValueFrom > outLoopValueTo then + outLoopValueFrom, outLoopValueTo = outLoopValueTo, outLoopValueFrom + inLoopValueFrom, inLoopValueTo = inLoopValueTo, inLoopValueFrom + end + + local outLoopValue, outLoopValueCounter, outLoopValueTriggerIncrement = + outLoopValueFrom, + 1, + inLoopValueDelta / outLoopValueDelta + local outLoopValueTrigger = outLoopValueTriggerIncrement + for inLoopValue = inLoopValueFrom, inLoopValueTo, inLoopValueFrom < inLoopValueTo and 1 or -1 do + if isReversed then + method(outLoopValue, inLoopValue) + else + method(inLoopValue, outLoopValue) + end + + outLoopValueCounter = outLoopValueCounter + 1 + if outLoopValueCounter > outLoopValueTrigger then + outLoopValue, outLoopValueTrigger = outLoopValue + 1, outLoopValueTrigger + outLoopValueTriggerIncrement + end + end +end + +local function rasterizeEllipse(centerX, centerY, radiusX, radiusY, method) + local function rasterizeEllipsePoints(XP, YP) + method(centerX + XP, centerY + YP) + method(centerX - XP, centerY + YP) + method(centerX - XP, centerY - YP) + method(centerX + XP, centerY - YP) + end + + local x, y, changeX, changeY, ellipseError, twoASquare, twoBSquare = + radiusX, + 0, + radiusY * radiusY * (1 - 2 * radiusX), + radiusX * radiusX, + 0, + 2 * radiusX * radiusX, + 2 * radiusY * radiusY + local stoppingX, stoppingY = twoBSquare * radiusX, 0 + + while stoppingX >= stoppingY do + rasterizeEllipsePoints(x, y) + + y, stoppingY, ellipseError = y + 1, stoppingY + twoASquare, ellipseError + changeY + changeY = changeY + twoASquare + + if (2 * ellipseError + changeX) > 0 then + x, stoppingX, ellipseError = x - 1, stoppingX - twoBSquare, ellipseError + changeX + changeX = changeX + twoBSquare + end + end + + x, y, changeX, changeY, ellipseError, stoppingX, stoppingY = + 0, + radiusY, + radiusY * radiusY, + radiusX * radiusX * (1 - 2 * radiusY), + 0, + 0, + twoASquare * radiusY + + while stoppingX <= stoppingY do + rasterizeEllipsePoints(x, y) + + x, stoppingX, ellipseError = x + 1, stoppingX + twoBSquare, ellipseError + changeX + changeX = changeX + twoBSquare + + if (2 * ellipseError + changeY) > 0 then + y, stoppingY, ellipseError = y - 1, stoppingY - twoASquare, ellipseError + changeY + changeY = changeY + twoASquare + end + end +end + +local function drawLine(x1, y1, x2, y2, background, foreground, symbol) + rasterizeLine( + x1, + y1, + x2, + y2, + function(x, y) + set(x, y, background, foreground, symbol) + end + ) +end + +local function drawEllipse(centerX, centerY, radiusX, radiusY, background, foreground, symbol) + rasterizeEllipse( + centerX, + centerY, + radiusX, + radiusY, + function(x, y) + set(x, y, background, foreground, symbol) + end + ) +end + +local function drawText(x, y, textColor, data, transparency) + if y >= drawLimitY1 and y <= drawLimitY2 then + local charIndex, bufferIndex = 1, bufferWidth * (y - 1) + x + + for charIndex = 1, unicodeLen(data) do + if x >= drawLimitX1 and x <= drawLimitX2 then + if transparency then + newFrameForegrounds[bufferIndex] = + colorBlend(newFrameBackgrounds[bufferIndex], textColor, transparency) + else + newFrameForegrounds[bufferIndex] = textColor + end + + newFrameSymbols[bufferIndex] = unicodeSub(data, charIndex, charIndex) + end + + x, bufferIndex = x + 1, bufferIndex + 1 + end + end +end + +local function drawImage(startX, startY, picture, blendForeground) + local bufferIndex, pictureIndex, imageWidth, backgrounds, foregrounds, alphas, symbols = + bufferWidth * (startY - 1) + startX, + 1, + picture[1], + picture[3], + picture[4], + picture[5], + picture[6] + local bufferIndexStepOnReachOfImageWidth = bufferWidth - imageWidth + + for y = startY, startY + picture[2] - 1 do + if y >= drawLimitY1 and y <= drawLimitY2 then + for x = startX, startX + imageWidth - 1 do + if x >= drawLimitX1 and x <= drawLimitX2 then + if alphas[pictureIndex] == 0 then + newFrameBackgrounds[bufferIndex], newFrameForegrounds[bufferIndex] = + backgrounds[pictureIndex], + foregrounds[pictureIndex] + elseif alphas[pictureIndex] > 0 and alphas[pictureIndex] < 1 then + newFrameBackgrounds[bufferIndex] = + colorBlend( + newFrameBackgrounds[bufferIndex], + backgrounds[pictureIndex], + alphas[pictureIndex] + ) + + if blendForeground then + newFrameForegrounds[bufferIndex] = + colorBlend( + newFrameForegrounds[bufferIndex], + foregrounds[pictureIndex], + alphas[pictureIndex] + ) + else + newFrameForegrounds[bufferIndex] = foregrounds[pictureIndex] + end + elseif alphas[pictureIndex] == 1 and symbols[pictureIndex] ~= " " then + newFrameForegrounds[bufferIndex] = foregrounds[pictureIndex] + end + + newFrameSymbols[bufferIndex] = symbols[pictureIndex] + end + + bufferIndex, pictureIndex = bufferIndex + 1, pictureIndex + 1 + end + + bufferIndex = bufferIndex + bufferIndexStepOnReachOfImageWidth + else + bufferIndex, pictureIndex = bufferIndex + bufferWidth, pictureIndex + imageWidth + end + end +end + +local function drawFrame(x, y, width, height, color) + local stringUp, stringDown, x2 = + "╭" .. string.rep("─", width - 2) .. "╮", + "╰" .. string.rep("─", width - 2) .. "╯", + x + width - 1 + + drawText(x, y, color, stringUp) + y = y + 1 + for i = 1, height - 2 do + drawText(x, y, color, "│") + drawText(x2, y, color, "│") + y = y + 1 + end + drawText(x, y, color, stringDown) +end + +-------------------------------------------------------------------------------- + +local function semiPixelRawSet(index, color, yPercentTwoEqualsZero) + local upperPixel, lowerPixel, bothPixel = "▀", "▄", "█" + local background, foreground, symbol = + newFrameBackgrounds[index], + newFrameForegrounds[index], + newFrameSymbols[index] + + if yPercentTwoEqualsZero then + if symbol == upperPixel then + if color == foreground then + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + color, + foreground, + bothPixel + else + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + color, + foreground, + symbol + end + elseif symbol == bothPixel then + if color ~= background then + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + background, + color, + lowerPixel + end + else + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + background, + color, + lowerPixel + end + else + if symbol == lowerPixel then + if color == foreground then + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + color, + foreground, + bothPixel + else + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + color, + foreground, + symbol + end + elseif symbol == bothPixel then + if color ~= background then + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + background, + color, + upperPixel + end + else + newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = + background, + color, + upperPixel + end + end +end + +local function semiPixelSet(x, y, color) + local yFixed = mathCeil(y / 2) + if x >= drawLimitX1 and yFixed >= drawLimitY1 and x <= drawLimitX2 and yFixed <= drawLimitY2 then + semiPixelRawSet(bufferWidth * (yFixed - 1) + x, color, y % 2 == 0) + end +end + +local function drawSemiPixelRectangle(x, y, width, height, color) + local index, indexStepForward, indexStepBackward, jPercentTwoEqualsZero, jFixed = + bufferWidth * (mathCeil(y / 2) - 1) + x, + (bufferWidth - width), + width + for j = y, y + height - 1 do + jPercentTwoEqualsZero = j % 2 == 0 + + for i = x, x + width - 1 do + jFixed = mathCeil(j / 2) + semiPixelRawSet(index, color, jPercentTwoEqualsZero) + index = index + 1 + end + + if jPercentTwoEqualsZero then + index = index + indexStepForward + else + index = index - indexStepBackward + end + end +end + +local function drawSemiPixelLine(x1, y1, x2, y2, color) + rasterizeLine( + x1, + y1, + x2, + y2, + function(x, y) + semiPixelSet(x, y, color) + end + ) +end + +local function drawSemiPixelEllipse(centerX, centerY, radiusX, radiusY, color) + rasterizeEllipse( + centerX, + centerY, + radiusX, + radiusY, + function(x, y) + semiPixelSet(x, y, color) + end + ) +end + +-------------------------------------------------------------------------------- + +local function getPointTimedPosition(firstPoint, secondPoint, time) + return { + x = firstPoint.x + (secondPoint.x - firstPoint.x) * time, + y = firstPoint.y + (secondPoint.y - firstPoint.y) * time + } +end + +local function getConnectionPoints(points, time) + local connectionPoints = {} + for point = 1, #points - 1 do + tableInsert(connectionPoints, getPointTimedPosition(points[point], points[point + 1], time)) + end + return connectionPoints +end + +local function getMainPointPosition(points, time) + if #points > 1 then + return getMainPointPosition(getConnectionPoints(points, time), time) + else + return points[1] + end +end + +local function drawSemiPixelCurve(points, color, precision) + local linePoints = {} + for time = 0, 1, precision or 0.01 do + tableInsert(linePoints, getMainPointPosition(points, time)) + end + + for point = 1, #linePoints - 1 do + drawSemiPixelLine( + mathFloor(linePoints[point].x), + mathFloor(linePoints[point].y), + mathFloor(linePoints[point + 1].x), + mathFloor(linePoints[point + 1].y), + color + ) + end +end + +-------------------------------------------------------------------------------- + +local function drawChanges(force) + local index, indexStepOnEveryLine, changes = + bufferWidth * (drawLimitY1 - 1) + drawLimitX1, + (bufferWidth - drawLimitX2 + drawLimitX1 - 1), + {} + local x, equalChars, equalCharsIndex, charX, charIndex, currentForeground + local currentFrameBackground, + currentFrameForeground, + currentFrameSymbol, + changesCurrentFrameBackground, + changesCurrentFrameBackgroundCurrentFrameForeground + + local changesCurrentFrameBackgroundCurrentFrameForegroundIndex + + for y = drawLimitY1, drawLimitY2 do + x = drawLimitX1 + while x <= drawLimitX2 do + -- Determine if some pixel data was changed (or if argument was passed) + if + currentFrameBackgrounds[index] ~= newFrameBackgrounds[index] or + currentFrameForegrounds[index] ~= newFrameForegrounds[index] or + currentFrameSymbols[index] ~= newFrameSymbols[index] or + force + then + -- Make pixel at both frames equal + currentFrameBackground, currentFrameForeground, currentFrameSymbol = + newFrameBackgrounds[index], + newFrameForegrounds[index], + newFrameSymbols[index] + currentFrameBackgrounds[index] = currentFrameBackground + currentFrameForegrounds[index] = currentFrameForeground + currentFrameSymbols[index] = currentFrameSymbol + + -- Look for pixels with equal chars from right of current pixel + equalChars, equalCharsIndex, charX, charIndex = {currentFrameSymbol}, 2, x + 1, index + 1 + while charX <= drawLimitX2 do + -- Pixels becomes equal only if they have same background and (whitespace char or same foreground) + if + currentFrameBackground == newFrameBackgrounds[charIndex] and + (newFrameSymbols[charIndex] == " " or + currentFrameForeground == newFrameForegrounds[charIndex]) + then + -- Make pixel at both frames equal + currentFrameBackgrounds[charIndex] = newFrameBackgrounds[charIndex] + currentFrameForegrounds[charIndex] = newFrameForegrounds[charIndex] + currentFrameSymbols[charIndex] = newFrameSymbols[charIndex] + + equalChars[equalCharsIndex], equalCharsIndex = + currentFrameSymbols[charIndex], + equalCharsIndex + 1 + else + break + end + + charX, charIndex = charX + 1, charIndex + 1 + end + + -- Group pixels that need to be drawn by background and foreground + changes[currentFrameBackground] = changes[currentFrameBackground] or {} + changesCurrentFrameBackground = changes[currentFrameBackground] + changesCurrentFrameBackground[currentFrameForeground] = + changesCurrentFrameBackground[currentFrameForeground] or {index = 1} + changesCurrentFrameBackgroundCurrentFrameForeground = + changesCurrentFrameBackground[currentFrameForeground] + changesCurrentFrameBackgroundCurrentFrameForegroundIndex = + changesCurrentFrameBackgroundCurrentFrameForeground.index + + changesCurrentFrameBackgroundCurrentFrameForeground[ + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + ], + changesCurrentFrameBackgroundCurrentFrameForegroundIndex = + x, + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1 + changesCurrentFrameBackgroundCurrentFrameForeground[ + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + ], + changesCurrentFrameBackgroundCurrentFrameForegroundIndex = + y, + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1 + changesCurrentFrameBackgroundCurrentFrameForeground[ + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + ], + changesCurrentFrameBackgroundCurrentFrameForegroundIndex = + tableConcat(equalChars), + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1 + + x, index, changesCurrentFrameBackgroundCurrentFrameForeground.index = + x + equalCharsIndex - 2, + index + equalCharsIndex - 2, + changesCurrentFrameBackgroundCurrentFrameForegroundIndex + end + + x, index = x + 1, index + 1 + end + + index = index + indexStepOnEveryLine + end + + -- Draw grouped pixels on screen + for background, foregrounds in pairs(changes) do + GPUProxySetBackground(background) + + for foreground, pixels in pairs(foregrounds) do + if currentForeground ~= foreground then + GPUProxySetForeground(foreground) + currentForeground = foreground + end + + for i = 1, #pixels, 3 do + GPUProxySet(pixels[i], pixels[i + 1], pixels[i + 2]) + end + end + end + + changes = nil +end + +-------------------------------------------------------------------------------- + +bindGPU(component.getPrimary("gpu").address) + +return { + -- getCoordinates = getCoordinates, + getIndex = getIndex, + setDrawLimit = setDrawLimit, + resetDrawLimit = resetDrawLimit, + getDrawLimit = getDrawLimit, + flush = flush, + setResolution = setResolution, + bindScreen = bindScreen, + bindGPU = bindGPU, + getGPUProxy = getGPUProxy, + getResolution = getResolution, + getWidth = getWidth, + getHeight = getHeight, + getCurrentFrameTables = getCurrentFrameTables, + getNewFrameTables = getNewFrameTables, + rawSet = rawSet, + rawGet = rawGet, + get = get, + set = set, + clear = clear, + copy = copy, + paste = paste, + rasterizeLine = rasterizeLine, + rasterizeEllipse = rasterizeEllipse, + semiPixelRawSet = semiPixelRawSet, + semiPixelSet = semiPixelSet, + drawChanges = drawChanges, + drawRectangle = drawRectangle, + drawLine = drawLine, + drawEllipse = drawEllipse, + drawText = drawText, + drawImage = drawImage, + drawFrame = drawFrame, + drawSemiPixelRectangle = drawSemiPixelRectangle, + drawSemiPixelLine = drawSemiPixelLine, + drawSemiPixelEllipse = drawSemiPixelEllipse, + drawSemiPixelCurve = drawSemiPixelCurve +} diff --git a/Libraries/graphics/widgets.lua b/Libraries/graphics/widgets.lua index 6672bd4..b9b1e30 100644 --- a/Libraries/graphics/widgets.lua +++ b/Libraries/graphics/widgets.lua @@ -4,7 +4,7 @@ Colors = require("colors") local widgets = {} -function widgets.gtMachineInit(GPU, name, address) +function widgets.gtMabchineInit(GPU, name, address) local maintenanceIndex = 0 local machine = util.machine(address) Graphics.rectangle(GPU, 1, 1, 28, 9, Colors.background) @@ -99,7 +99,8 @@ function widgets.gtMachine(GPU, name, address) end _, f, _ = GPU.get(6, 1) if - ((Graphics.windows[name].data == 0 or string.match(machine.getSensorInformation()[Graphics.windows[name].data], ".*c0.*")) and + ((Graphics.windows[name].data == 0 or + string.match(machine.getSensorInformation()[Graphics.windows[name].data], ".*c0.*")) and machine.isWorkAllowed()) == true then if f ~= Colors.background then diff --git a/Programs/monitor-system/api/gui/constants.lua b/Programs/monitor-system/api/gui/constants.lua new file mode 100644 index 0000000..b0c6562 --- /dev/null +++ b/Programs/monitor-system/api/gui/constants.lua @@ -0,0 +1,6 @@ +local constants = {} + +constants.baseWidth = 40 +constants.baseHeight = 10 + +return constants diff --git a/Programs/monitor-system/api/gui/overview.lua b/Programs/monitor-system/api/gui/overview.lua deleted file mode 100644 index 2312ca2..0000000 --- a/Programs/monitor-system/api/gui/overview.lua +++ /dev/null @@ -1,5 +0,0 @@ -local function render() - -end - -return render diff --git a/Programs/monitor-system/api/gui/page/glasses.lua b/Programs/monitor-system/api/gui/page/glasses.lua new file mode 100644 index 0000000..a2032da --- /dev/null +++ b/Programs/monitor-system/api/gui/page/glasses.lua @@ -0,0 +1,11 @@ +--[[ +|ove| glasses | +|wid| w | w | w | +|hel| w | w | w | +|sto| w | w | w | +|not| power |b|f| +--]] + +return { + title = "Glasses" +} diff --git a/Programs/monitor-system/api/gui/page/help.lua b/Programs/monitor-system/api/gui/page/help.lua new file mode 100644 index 0000000..220cf46 --- /dev/null +++ b/Programs/monitor-system/api/gui/page/help.lua @@ -0,0 +1,11 @@ +--[[ +|gla| help | +|wid|ev ti|ev ti| +|ove|ev ti|ev ti| +|sto|ev ti|ev ti| +|not| power |b|f| +--]] + +return { + title = "Help" +} diff --git a/Programs/monitor-system/api/gui/page/init.lua b/Programs/monitor-system/api/gui/page/init.lua new file mode 100644 index 0000000..0d413b1 --- /dev/null +++ b/Programs/monitor-system/api/gui/page/init.lua @@ -0,0 +1,211 @@ +-- Import section +Computer = require("computer") +Unicode = require("unicode") +Event = require("event") +DoubleBuffer = require("graphics.doubleBuffering") +Constants = require("api.gui.constants") +Colors = require("graphics.colors") +Widget = require("api.gui.widget") +-- + +-- GPU resolution should be 160 x 50. +-- Screen should be 8 x 5 blocks. +-- That way, each block should have a resolution of 20 x 10 +-- Organizing the page: +---- Title on top of the page (title) +---- Side panel on the left With a width of 40 pixels (panel) +---- 2 buttons for page navigation (b, f) +------- Each with a width of 20 pixels +---- 1 Power widget on the bottom, with a width of 80 pixels (power) +---- 9 Regular widgets on the right, in a 3 x 3 grid (w) +------ Each one with a width of 40 pixels +--[[ +| p | title | +| a | w | w | w | +| n | w | w | w | +| e | w | w | w | +| l | power |b|f| +--]] +local pages = { + glasses = require("api.gui.page.glasses"), + widgets = require("api.gui.page.widgets"), + help = require("api.gui.page.help"), + stock = require("api.gui.page.stock"), + notifications = require("api.gui.page.notifications"), + overview = require("api.gui.page.overview") +} +pages[1] = pages.glasses +pages[2] = pages.widgets +pages[3] = pages.help +pages[4] = pages.stock +pages[5] = pages.notifications +pages[6] = pages.overview + +local page = {} + +local elements = { + machineWidgets = {}, + powerWidgets = {}, + panelSections = {}, + navigationButtons = {} +} + +Event.listen( + "touch", + function(_, _, x, y) + local xContribution = x / Constants.baseWidth + local yContribution = 4 * math.floor(y / Constants.baseHeight) + local screenIndex = 1 + (math.floor(2 * (xContribution + yContribution))) / 2 + + local selected = elements[screenIndex] or elements[screenIndex - 0.5] + selected:onClick() + end +) + +local function drawTitle(title) + local x = Constants.baseWidth + local y = 1 + local width = 3 * Constants.baseWidth + local height = math.floor(0.8 * Constants.baseHeight) + Widget.drawBaseWidget(x, y, width, height, title) +end + +local function drawPanelSection(index, title) + local width = math.floor(0.6 * Constants.baseWidth) + local height = math.floor(0.6 * Constants.baseHeight) + local x = math.floor((Constants.baseWidth - width) / 2) + local y = (index - 1) * Constants.baseHeight + math.floor((Constants.baseHeight - height) / 2) + Widget.drawBaseWidget(x, y, width, height, title) +end + +local function drawNavigationButton(self, index) + local width = math.floor(0.3 * Constants.baseWidth) + local height = math.floor(0.6 * Constants.baseHeight) + local x = math.floor((2.4 + 0.4 * index) * Constants.baseWidth) + math.floor((Constants.baseWidth - width) / 2) + local y = 4 * Constants.baseHeight + math.floor((Constants.baseHeight - height) / 2) + if self.active then + Widget.drawBaseWidget(x, y, width, height, self.title) + end +end + +local function clickNavigationButton(self) + if not self.active then + return + end + if self.title == "◀" then + elements.machineWidgets.active.index = elements.machineWidgets.active.index - 1 + else + elements.machineWidgets.active.index = elements.machineWidgets.active.index + 1 + end + for i = 1, 9 do + elements.machineWidgets.active[i] = elements.machineWidgets[9 * (elements.machineWidgets.active.index - 1) + i] + end + + elements[6] = elements.machineWidgets.active[1] + elements[7] = elements.machineWidgets.active[2] + elements[8] = elements.machineWidgets.active[3] + elements[10] = elements.machineWidgets.active[4] + elements[11] = elements.machineWidgets.active[5] + elements[12] = elements.machineWidgets.active[6] + elements[14] = elements.machineWidgets.active[7] + elements[15] = elements.machineWidgets.active[8] + elements[16] = elements.machineWidgets.active[9] + Widget.clear() +end + +function page.create(element) + drawTitle(element.title) + + local panelIndex = 1 + for _, pg in ipairs(pages) do + if pg ~= element then + elements.panelSections[panelIndex] = { + title = pg.title, + onClick = function() + page.create(pg) + end + } + drawPanelSection(panelIndex, pg.title) + panelIndex = panelIndex + 1 + end + end + + elements.machineWidgets.active = {} + elements.machineWidgets.active.index = 1 + for i = 1, 9 do + elements.machineWidgets.active[i] = elements.machineWidgets[9 * (elements.machineWidgets.active.index - 1) + i] + end + elements.navigationButtons[1] = { + title = "◀", + active = true, + update = function(self) + self.active = elements.machineWidgets[elements.machineWidgets.active.index * 9 - 10] ~= nil + end, + onClick = clickNavigationButton, + draw = drawNavigationButton + } + elements.navigationButtons[2] = { + title = "▶", + active = true, + update = function(self) + self.active = elements.machineWidgets[elements.machineWidgets.active.index * 9 + 1] ~= nil + end, + onClick = clickNavigationButton, + draw = drawNavigationButton + } + + elements[4.5] = { + onClick = function() + Computer.shutdown(true) + end + } + + elements[6] = elements.machineWidgets.active[1] + elements[7] = elements.machineWidgets.active[2] + elements[8] = elements.machineWidgets.active[3] + elements[10] = elements.machineWidgets.active[4] + elements[11] = elements.machineWidgets.active[5] + elements[12] = elements.machineWidgets.active[6] + elements[14] = elements.machineWidgets.active[7] + elements[15] = elements.machineWidgets.active[8] + elements[16] = elements.machineWidgets.active[9] + + elements[18] = elements.powerWidgets[1] + elements[19] = elements.powerWidgets[1] + + elements[1] = elements.panelSections[1] + elements[5] = elements.panelSections[2] + elements[9] = elements.panelSections[3] + elements[13] = elements.panelSections[4] + elements[17] = elements.panelSections[5] + + elements[20] = elements.navigationButtons[1] + elements[20.5] = elements.navigationButtons[2] +end + +function page.fake() + elements.machineWidgets = Widget.fakeWidgets() + elements.powerWidgets = Widget.fakePowerWidget() + page.create(pages.overview) +end + +function page.update() + for _, machineWidget in ipairs(elements.machineWidgets) do + machineWidget:update() + end + for index, activeMachineWidget in ipairs(elements.machineWidgets.active) do + activeMachineWidget.draw(activeMachineWidget, index) + end + for index, powerWidget in ipairs(elements.powerWidgets) do + powerWidget:update() + powerWidget:draw(index) + end + for index, navigationButton in ipairs(elements.navigationButtons) do + navigationButton:update() + navigationButton:draw(index) + end + + DoubleBuffer.drawChanges() +end + +return page diff --git a/Programs/monitor-system/api/gui/page/notifications.lua b/Programs/monitor-system/api/gui/page/notifications.lua new file mode 100644 index 0000000..edfabbf --- /dev/null +++ b/Programs/monitor-system/api/gui/page/notifications.lua @@ -0,0 +1,11 @@ +--[[ +|gla| notifs. | +|wid|ev ti|ev ti| +|hel|ev ti|ev ti| +|sto|ev ti|ev ti| +|ove| power |b|f| +--]] + +return { + title ="Notifications" +} diff --git a/Programs/monitor-system/api/gui/page/overview.lua b/Programs/monitor-system/api/gui/page/overview.lua new file mode 100644 index 0000000..bd7790d --- /dev/null +++ b/Programs/monitor-system/api/gui/page/overview.lua @@ -0,0 +1,11 @@ +--[[ +|gla| overview | +|wid| w | w | w | +|hel| w | w | w | +|sto| w | w | w | +|not| power |b|f| +--]] + +return { + title = "Overview" +} diff --git a/Programs/monitor-system/api/gui/page/stock.lua b/Programs/monitor-system/api/gui/page/stock.lua new file mode 100644 index 0000000..24a8387 --- /dev/null +++ b/Programs/monitor-system/api/gui/page/stock.lua @@ -0,0 +1,11 @@ +--[[ +|gla| stock | +|wid|ev ti|ev ti| +|hel|ev ti|ev ti| +|ove|ev ti|ev ti| +|not| power |b|f| +--]] + +return { + title = "Stock" +} diff --git a/Programs/monitor-system/api/gui/page/widgets.lua b/Programs/monitor-system/api/gui/page/widgets.lua new file mode 100644 index 0000000..f02073f --- /dev/null +++ b/Programs/monitor-system/api/gui/page/widgets.lua @@ -0,0 +1,11 @@ +--[[ +|gla| widgets | +|ove| w | w | w | +|hel| w | w | w | +|sto| w | w | w | +|not| power |b|f| +--]] + +return { + title = "Widgets" +} diff --git a/Programs/monitor-system/api/gui/panel.lua b/Programs/monitor-system/api/gui/panel.lua new file mode 100644 index 0000000..6db0328 --- /dev/null +++ b/Programs/monitor-system/api/gui/panel.lua @@ -0,0 +1,27 @@ +-- Import section +Page = require("api.gui.page") +Graphics = require("graphics.graphics") +Colors = require("colors") +Component = require("component") +GPU = Component.gpu +-- + +local panel = { + currentPage = Page.overview +} + +function panel.render() + Graphics.rectangle(GPU, 0, 0, 20, 160, Colors.background) + for index, page in ipairs(Page) do + if page ~= panel.currentPage then + Graphics.text(GPU, 0, 10 * (index - 1), Colors.labelColor, panel.title) + end + end +end + +function panel.navigate(page) + panel.findText(page.title) + page.render() +end + +return panel diff --git a/Programs/monitor-system/api/gui/widget.lua b/Programs/monitor-system/api/gui/widget.lua new file mode 100644 index 0000000..19f38e8 --- /dev/null +++ b/Programs/monitor-system/api/gui/widget.lua @@ -0,0 +1,239 @@ +Component = require("component") +Unicode = require("unicode") +DoubleBuffer = require("graphics.doubleBuffering") +Constants = require("api.gui.constants") +Colors = require("graphics.colors") + +local widget = {} + +local states = { + {name = "ON", color = Colors.workingColor}, + {name = "IDLE", color = Colors.idleColor}, + {name = "OFF", color = Colors.offColor}, + {name = "BROKEN", color = Colors.errorColor} +} + +local function drawProgress(x, y, width, height, progress, maxProgress, color) + progress = math.floor(progress * (width + height - 2) / (maxProgress ~= 0 and maxProgress or 1)) + + local lengths = { + first = progress > 5 and 5 or progress, + second = progress > height - 2 + 5 and height - 2 or progress - (5), + third = progress > width - 7 + height - 2 + 5 and width - 7 or progress - (height - 2 + 5) + } + DoubleBuffer.drawRectangle(x + 6, y / 2 + 1, 2, 1, Colors.machineBackground, Colors.machineBackground, "█") + DoubleBuffer.drawSemiPixelRectangle(x + 6 - lengths.first, y + 1, lengths.first, 1, color) + DoubleBuffer.drawSemiPixelRectangle(x + 1, y + 2, 1, lengths.second, color) + DoubleBuffer.drawSemiPixelRectangle(x + 1, y + height, lengths.third, 1, color) + DoubleBuffer.drawRectangle( + x + width - 6, + (y + height) / 2, + 2, + 1, + Colors.machineBackground, + Colors.machineBackground, + "█" + ) + DoubleBuffer.drawSemiPixelRectangle(x + width - 4, y + height, lengths.first, 1, color) + DoubleBuffer.drawSemiPixelRectangle(x + width, y + height - lengths.second, 1, lengths.second, color) + DoubleBuffer.drawSemiPixelRectangle(x + 1 + width - lengths.third, y + 1, lengths.third, 1, color) +end + +function widget.drawBaseWidget(x, y, width, height, title) + DoubleBuffer.drawRectangle( + x + 1, + y + 1, + width - 1, + height - 1, + Colors.machineBackground, + Colors.machineBackground, + "█" + ) + DoubleBuffer.drawLine( + x + 3, + y + math.ceil(0.5 * height), + x + width - 3, + y + math.ceil(0.5 * height), + Colors.machineBackground, + Colors.textColor, + "─" + ) + DoubleBuffer.drawFrame(x + 1, y + 1, width - 1, height - 1, Colors.labelColor) + title = Unicode.len(title) < width - 8 and " " .. title .. " " or " " .. string.gsub(title, "%l*%s", "") .. " " + DoubleBuffer.drawText(x + math.floor((width - Unicode.len(title) + 1) / 2), y + 3, Colors.labelColor, title) +end + +local function draw(self, index) + if self.type == "power" then + index = 10 + end + local scale = self.scale or 1 + local width = Constants.baseWidth * scale + local height = Constants.baseHeight + local x = Constants.baseWidth + Constants.baseWidth * ((index - 1) % 3) + local y = height * math.ceil((index) / 3) + + widget.drawBaseWidget(x, y, width, height, self.name) + + drawProgress(x, 2 * y, width - 1, 2 * (height - 1), 1, 1, Colors.progressBackground) + drawProgress(x, 2 * y, width - 1, 2 * (height - 1), self.progress, self.maxProgress, Colors.barColor) + DoubleBuffer.drawText(x + 4, y + 7, self.state.color, self.state.name) + if self.state == states[4] then + drawProgress(x, 2 * y, width - 1, 2 * (height - 1), 1, 1, Colors.errorColor) + else + local middleInfo = self:getMiddleString() + if middleInfo then + DoubleBuffer.drawText(x + 3 + 3 + Unicode.len("IDLE"), y + height - 3, Colors.textColor, middleInfo) + end + DoubleBuffer.drawText( + x + width - Unicode.len(self.progress .. "/" .. self.maxProgress .. " s") - 3, + y + height - 3, + Colors.accentA, + self.progress .. "/" .. self.maxProgress .. " s" + ) + end +end + +function widget.clear() + DoubleBuffer.drawRectangle( + Constants.baseWidth, + Constants.baseHeight, + 3 * Constants.baseWidth, + 4 * Constants.baseHeight, + Colors.background, + Colors.background, + "█" + ) +end + +local fake = {} + +fake.names = { + "Cleanroom", + "Electric Blast Furnace", + "Miner", + "Vacuum Freezer", + "Multi Smelter", + "Sifter", + "Large Chemical Reactor", + "Distillery", + "Oil Cracking Unit", + "Implosion Compressor" +} + +fake.machineWidget = {} + +function fake.machineWidget:update() + local breakWidget = math.random(10000) > 9999 + if breakWidget and self.state ~= states[3] then + self.state = states[4] + end + if self.state == states[1] then + self.progress = self.progress + 1 + if self.progress >= self.maxProgress then + self.progress = 0 + self.maxProgress = 0 + self.state = states[2] + end + elseif self.state == states[2] then + if math.random(1000) > 999 then + self.state = states[1] + self.maxProgress = math.random(500) + end + elseif self.state == states[3] then + self.progress = self.progress + 1 + if self.progress >= self.maxProgress then + self.progress = 0 + self.maxProgress = 0 + end + end +end + +function fake.machineWidget:onClick() + if self.state == states[1] or self.state == states[2] then + self.state = states[3] + elseif self.state == states[3] then + if self.progress < self.maxProgress then + self.state = states[1] + else + self.progress = 0 + self.maxProgress = 0 + self.state = states[2] + end + elseif self.state == states[4] then + self.progress = 0 + self.maxProgress = 0 + self.state = states[2] + end +end + +function fake.machineWidget:getMiddleString() +end + +function fake.machineWidget.create() + local state = states[math.random(4)] + return { + name = fake.names[math.random(10)] .. " " .. math.floor(math.random(3)), + state = state, + progress = 0, + maxProgress = state ~= states[3] and state ~= states[4] and math.random(500) or 0, + type = "machine", + update = fake.machineWidget.update, + onClick = fake.machineWidget.onClick, + getMiddleString = fake.machineWidget.getMiddleString, + draw = draw + } +end + +fake.powerWidget = {} + +function fake.powerWidget:update() + self.progress = self.progress + self.dProgress +end + +function fake.powerWidget:onClick() + self.dProgress = -self.dProgress +end + +function fake.powerWidget:getMiddleString() + local remaining = self.dProgress > 0 and self.maxProgress - self.progress or -self.progress + return (self.dProgress > 0 and "+" or "") .. + self.dProgress .. "EU/s. " .. (self.dProgress > 0 and "Full in: " or "Empty in: ") .. remaining / self.dProgress +end + +function fake.powerWidget.create() + return { + name = "Power", + state = states[1], + progress = math.random(16000000), + maxProgress = 16000000, + scale = 2, + type = "power", + dProgress = 1, + update = fake.powerWidget.update, + onClick = fake.powerWidget.onClick, + getMiddleString = fake.powerWidget.getMiddleString, + draw = draw + } +end + +function widget.fakeWidgets() + local fakeWidgets = {} + + for _ = 1, math.random(30) do + table.insert(fakeWidgets, fake.machineWidget.create()) + end + + return fakeWidgets +end + +function widget.fakePowerWidget() + local fakePowerWidgets = {} + + table.insert(fakePowerWidgets, fake.powerWidget.create()) + fakePowerWidgets[11] = fakePowerWidgets[10] + + return fakePowerWidgets +end + +return widget diff --git a/Programs/monitor-system/data/datasource/multi-block.lua b/Programs/monitor-system/data/datasource/multi-block.lua index fad817c..bee6ef9 100755 --- a/Programs/monitor-system/data/datasource/multi-block.lua +++ b/Programs/monitor-system/data/datasource/multi-block.lua @@ -19,6 +19,11 @@ function MultiBlock:getNumberOfProblems() return Parser.parseProblems(sensorInformation[5]) end +function MultiBlock:getProgress() + local sensorInformation = self:getSensorInformation() + return Parser.parseProgress(sensorInformation[1]) +end + function MultiBlock:getEfficiencyPercentage() local sensorInformation = self:getSensorInformation() return Parser.parseEfficiency(sensorInformation[5]) diff --git a/Programs/monitor-system/domain/energy/get-energy-status-usecase.lua b/Programs/monitor-system/domain/energy/get-energy-status-usecase.lua index 9a4e346..b08630d 100755 --- a/Programs/monitor-system/domain/energy/get-energy-status-usecase.lua +++ b/Programs/monitor-system/domain/energy/get-energy-status-usecase.lua @@ -3,7 +3,7 @@ local getConsumption = require("domain.energy.get-consumption-usecase") local getProduction = require("domain.energy.get-production-usecase") -- -local function exec(energyProducers, energyBuffer) +local function exec(energyBuffer) -- local comsumption = getConsumption(energyBuffer) -- local production = getProduction(energyBuffer) local consumption = energyBuffer:getAverageInput() diff --git a/Programs/monitor-system/init.lua b/Programs/monitor-system/init.lua index f236b8d..5e186c3 100755 --- a/Programs/monitor-system/init.lua +++ b/Programs/monitor-system/init.lua @@ -1,42 +1,50 @@ -- Import section -MultiBlock = require("data.datasource.multi-block") -SingleBlock = require("data.datasource.single-block") -EnergyProvider = require("data.datasource.energy-provider") +-- Event = require("event") +-- Colors = require("graphics.colors") +-- Widget = require("api.gui.widget") +Page = require("api.gui.page") +-- Graphics = require("graphics.graphics") +-- MultiBlock = require("data.datasource.multi-block") +-- SingleBlock = require("data.datasource.single-block") +-- EnergyProvider = require("data.datasource.energy-provider") -local cleanroomAddresses = require("config.addresses.cleanroom") -local multiBlockAddresses = require("config.addresses.multi-blocks") -local energyBufferAddress = require("config.addresses.energy-buffers") +-- local cleanroomAddresses = require("config.addresses.cleanroom") +-- local multiBlockAddresses = require("config.addresses.multi-blocks") +-- local energyBufferAddresses = require("config.addresses.energy-buffers") -local protectCleanroomRecipes = require("domain.cleanroom.protect-recipes-usecase") -local getMultiblockStatuses = require("domain.multiblock.get-multiblock-status-usecase") -local getEnergyStatus = require("domain.energy.get-energy-status-usecase") -local listMiners = require("domain.miner.list-miners-usecase") -local getMinersStatuses = require("domain.miner.get-miner-status-usecase") +-- local protectCleanroomRecipes = require("domain.cleanroom.protect-recipes-usecase") +-- local getMultiblockStatuses = require("domain.multiblock.get-multiblock-status-usecase") +-- local getEnergyStatus = require("domain.energy.get-energy-status-usecase") +-- local listMiners = require("domain.miner.list-miners-usecase") +-- local getMinersStatuses = require("domain.miner.get-miner-status-usecase") + +-- local GPU = Component.gpu -- -local cleanroom = MultiBlock:new(multiBlockAddresses.cleanroom) -cleanroom.name = "cleanroom" +--[[ local cleanroomMachines = {} -for _, address in pairs(cleanroomAddresses) do - table.insert(cleanroomMachines, SingleBlock:new(address)) +for name, address in pairs(cleanroomAddresses) do + table.insert(cleanroomMachines, SingleBlock:new(address, name)) end -local EBF11 = MultiBlock:new(multiBlockAddresses.EBF11) -EBF11.name = "EBF11" +local multiblocks = {} +for name, address in pairs(multiBlockAddresses) do + table.insert(multiblocks, MultiBlock:new(address, name)) +end -local multiblocks = {cleanroom, EBF11} +local batteryBuffers = {} +for name, address in pairs(energyBufferAddresses) do + table.insert(batteryBuffers, EnergyProvider:new(address, name)) +end -local energyBuffer = EnergyProvider:new(energyBufferAddress.batteryBuffer1) - -local energyProducers = {} local multiblocksStatuses = {} for i = 1, 100 do print(i) - protectCleanroomRecipes(cleanroom, cleanroomMachines) + protectCleanroomRecipes(multiblocks[1], cleanroomMachines) multiblocksStatuses = getMultiblockStatuses(multiblocks) - local energyStatus = getEnergyStatus(energyProducers, energyBuffer) + -- local energyStatus = getEnergyStatus(batteryBuffers[1]) local minersList = listMiners() local minersStatuses = getMinersStatuses(minersList) @@ -45,9 +53,66 @@ for i = 1, 100 do i = i + 1 end -for multiblock, status in pairs(multiblocksStatuses) do - print(multiblock .. ": \ - problems: " .. status.problems .. "\ - efficiency: " .. status.efficiencyPercentage) +for multiblockName, status in pairs(multiblocksStatuses) do + print( + multiblockName .. ":", + "\n problems: " .. status.problems, + "\n efficiency: " .. status.efficiencyPercentage, + "\n probably uses: " .. status.probablyUses + ) end + require("api.sound.zelda-secret")() +--]] + +Page.fake() + +while true do + Page.update() + os.sleep(0) +end + +--[[ +Page = require("api.gui.page") +Notifications = {} +local components = {} +local function getComponents() + local multiBlockAddresses = require("config.addresses.multi-blocks") + local energyBufferAddresses = require("config.addresses.energy-buffers") + + local multiblocks = {} + for name, address in pairs(multiBlockAddresses) do + table.insert(multiblocks, MultiBlock:new(address, name)) + end + + local batteryBuffers = {} + for name, address in pairs(energyBufferAddresses) do + table.insert(batteryBuffers, EnergyProvider:new(address, name)) + end + + return {table.unpack(multiblocks), batteryBuffers} +end + +local function setup() + components = getComponents() + Page.overview.setup() +end + +local function loop() + while true do + for index, component in ipairs(components) do + local updated, notification = component:update() + if updated then + Page:draw(component, index) + end + if notification then + table.insert(Notifications, 1, {notification, os.time()}) + end + end + Page:render() + end +end + +setup() +loop() +--]] diff --git a/Programs/setup.lua b/Programs/setup.lua index ef87f42..d125d6c 100644 --- a/Programs/setup.lua +++ b/Programs/setup.lua @@ -9,7 +9,7 @@ shell.execute("wget " .. tarMan .. " -f") shell.setWorkingDirectory("/bin") shell.execute("wget " .. tarBin .. " -f") -local InfOS = "https://github.com/gordominossi/InfOS/releases/download/v0/InfOS.tar" +local InfOS = "https://github.com/gordominossi/InfOS/releases/download/v0.1/InfOS.tar" shell.setWorkingDirectory("/home") print("Updating InfOS") diff --git a/Programs/update.lua b/Programs/update.lua deleted file mode 100644 index 2d45129..0000000 --- a/Programs/update.lua +++ /dev/null @@ -1,18 +0,0 @@ --- wget https://raw.githubusercontent.com/gordominossi/InfOS/master/Programs/update.lua -f - -local shell = require("shell") - -local tarMan = "https://raw.githubusercontent.com/mpmxyz/ocprograms/master/usr/man/tar.man" -local tarBin = "https://raw.githubusercontent.com/mpmxyz/ocprograms/master/home/bin/tar.lua" -local InfOS = "https://github.com/gordominossi/InfOS/releases/download/v0/InfOS.tar" - -shell.setWorkingDirectory("/usr/man") -shell.execute("wget " .. tarMan .. " -f") - -shell.setWorkingDirectory("/bin") -shell.execute("wget " .. tarBin .. " -f") - -shell.setWorkingDirectory("/home") -print("Updating InfOS") -shell.execute("wget " .. InfOS .. " -f") -shell.execute("tar -xf InfOS.tar")