Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --
- -- Copyright 2019 KaseiFR <kaseifr@gmail.com>
- --
- -- Permission is hereby granted, free of charge, to any person obtaining a copy
- -- of this software and associated documentation files (the "Software"), to deal
- -- in the Software without restriction, including without limitation the rights
- -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- -- copies of the Software, and to permit persons to whom the Software is
- -- furnished to do so, subject to the following conditions:
- --
- -- The above copyright notice and this permission notice shall be included in all
- -- copies or substantial portions of the Software.
- --
- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- -- SOFTWARE.
- --
- local component = require('component')
- local computer = require('computer')
- local coroutine = require('coroutine')
- local event = require('event')
- local filesystem = require('filesystem')
- local serialization = require('serialization')
- local thread = require('thread')
- local tty = require('tty')
- local unicode = require('unicode')
- local GUI = require('GUI')
- --local cuutil = require('cuutil')
- --local servicegui = require('servicegui')
- --data = {}
- --current_draw = {}
- --fullCheckInterval = 1
- --
- --serviceList = {
- -- AE_autocrafting = ae_auto_processor,
- -- chunkloader = chunkloader
- --}
- --
- --_serviceSet = Set(serviceList)
- local chunkdata = {}
- function main()
- local resetBColor, resetFColor = tty.gpu().getBackground(), tty.gpu().getForeground()
- local app = buildGui()
- app:draw(true)
- -- Start some background tasks
- local background = {}
- table.insert(background, event.listen("key_up", function(key, address, char)
- if char == string.byte('q') then
- event.push('exit')
- end
- end))
- table.insert(background, event.listen("redraw", function(key)
- app:draw()
- end))
- table.insert(background, event.listen("net_msg", function(eventname, from, port, message)
- if port == 1122 then
- local mdata = serialization.unserialize(message)
- if mdata.service == "chunkloader" then
- updateLoaders(mdata.key, mdata.value)
- end
- end
- end))
- --table.insert(background, thread.create(failFast(mainloop)))
- table.insert(background, thread.create(failFast(function()
- app:start()
- end)))
- -- Block until we receive the exit signal
- local _, err = event.pull("exit")
- -- Cleanup
- app:stop()
- for _, b in ipairs(background) do
- if type(b) == 'table' and b.kill then
- b:kill()
- else
- event.cancel(b)
- end
- end
- tty.gpu().setBackground(resetBColor)
- tty.gpu().setForeground(resetFColor)
- tty.clear()
- if err then
- io.stderr:write(err)
- os.exit(1)
- else
- os.exit(0)
- end
- end
- function log(...)
- -- TODO: reserve a part of the screen for logs
- for i, v in ipairs { ... } do
- if i > 1 then
- io.stderr:write(' ')
- end
- io.stderr:write(tostring(v))
- end
- io.stderr:write('\n')
- end
- function updateLoaders(key, value)
- chunkdata = value
- event.push('redraw')
- end
- function logRam(msg)
- --free, total = computer.freeMemory(), computer.totalMemory()
- --log(msg, 'RAM', (total - free) * 100 / total, '%')
- end
- function pretty(x)
- return serialization.serialize(x, true)
- end
- function failFast(fn)
- return function(...)
- local res = table.pack(xpcall(fn, debug.traceback, ...))
- if not res[1] then
- event.push('exit', res[2])
- end
- return table.unpack(res, 2)
- end
- end
- function yield(msg)
- --local gpu = tty.gpu()
- --local _, h = gpu.getViewport()
- --gpu.set(1, h, msg)
- os.sleep()
- end
- function itemKey(item, withLabel)
- local key = item.name .. '$' .. math.floor(item.damage)
- if withLabel then
- --log('using label for', item.label)
- key = key .. '$' .. item.label
- end
- return key
- end
- function equals(t1, t2)
- if t1 == t2 then
- return true
- end
- if type(t1) ~= type(t2) or type(t1) ~= 'table' then
- return false
- end
- for k1, v1 in pairs(t1) do
- local v2 = t2[k1]
- if not equals(v1, v2) then
- return false
- end
- end
- for k2, _ in pairs(t2) do
- if t1[k2] == nil then
- return false
- end
- end
- return true
- end
- function filter(array, predicate)
- local res = {}
- for _, v in ipairs(array) do
- if predicate(v) then
- table.insert(res, v)
- end
- end
- return res
- end
- function contains(haystack, needle)
- if haystack == needle then
- return true
- end
- if type(haystack) ~= type(needle) or type(haystack) ~= 'table' then
- return false
- end
- for k, v in pairs(needle) do
- if not contains(haystack[k], v) then
- return false
- end
- end
- return true
- end
- function override(object, method, fn)
- local super = object[method] or function()
- end
- object[method] = function(...)
- fn(super, ...)
- end
- end
- function numberValidator(str)
- n = tonumber(str, 10)
- return n and math.floor(n) == n
- end
- -- Stay close to the 16 Minecraft colors in order to work on gold GPU/screen
- local C_BACKGROUND = 0x3C3C3C
- local C_STATUS_BAR = 0xC3C3C3
- local C_STATUS_TEXT = 0x1E1E1E
- local C_STATUS_PRESSED = 0xFFFF00
- local C_BADGE = 0xD2D2D2
- local C_BADGE_ERR = 0xFF4900 --0xFFB6FF
- local C_BADGE_BUSY = 0x336DFF
- local C_BADGE_SELECTED = 0xFFAA00
- local C_BADGE_TEXT = 0x1E1E1E
- local C_INPUT = 0xFFFFFF
- local C_INPUT_TEXT = 0x1E1E1E
- local C_SCROLLBAR = C_BADGE_SELECTED
- local C_SCROLLBAR_BACKGROUND = 0xFFFFFF
- function buildGui()
- local app = GUI.application()
- local statusBar = app:addChild(GUI.container(1, 1, app.width, 1))
- local window = app:addChild(GUI.container(1, 1 + statusBar.height, app.width, app.height - statusBar.height))
- window:addChild(GUI.panel(1, 1, window.width, window.height, C_BACKGROUND))
- local columns = math.floor(window.width / 8) + 1
- local rows = math.floor(window.height / 4)
- local statusView = window:addChild(GUI.layout(1, 1, window.width - 7, window.height-1, columns, rows))
- for i = 1, columns do
- statusView:setAlignment(i, 1, GUI.ALIGNMENT_HORIZONTAL_CENTER, GUI.ALIGNMENT_VERTICAL_CENTER)
- statusView:setMargin(i, 1, 1, 1)
- end
- --statusView.showGrid = true
- override(statusView, 'draw', function(super, self, ...)
- self.children = {}
- local maxx, maxy, minx, miny = -math.huge, -math.huge, math.huge, math.huge
- for _, v in pairs(chunkdata) do
- local x = math.tointeger(v.x)
- local y = math.tointeger(v.y)
- if x > maxx then
- maxx = x
- end
- if x < minx then
- minx = x
- end
- if y > maxy then
- maxy = y
- end
- if y < miny then
- miny = y
- end
- end
- local totalcoloums = maxy - miny + 1
- if totalcoloums > columns then
- print("error to many columns")
- end
- local left_offset = math.floor((columns - totalcoloums) / 2)
- local yoffset = maxy + 1 + left_offset
- local xoffset = -minx + 2
- for k, v in pairs(chunkdata) do
- local badge = GUI.container(1, 1, math.floor(self.width / columns - 1), 3)
- self:setPosition( (-1 * math.tointeger(v.y)) + yoffset, math.tointeger(v.x) + xoffset, self:addChild(badge))
- local badgecolor = v.status == 1 and 0x009900 or 0xff0000
- badge:addChild(GUI.panel(1, 1, badge.width, 3, badgecolor))
- local textcolor = v.y == "40" and 0x0066ff or C_BADGE_TEXT
- badge:addChild(GUI.label(2, 2, badge.width, 1, textcolor, v.x .. ":" .. v.y):setAlignment(GUI.ALIGNMENT_HORIZONTAL_CENTER, GUI.ALIGNMENT_VERTICAL_CENTER))
- end
- super(self, ...)
- end)
- -- Status bar
- statusBar:addChild(GUI.panel(1, 1, statusBar.width, statusBar.height, C_STATUS_BAR))
- local statusText = statusBar:addChild(GUI.text(2, 1, C_STATUS_TEXT, ''))
- statusText.eventHandler = function(app, self)
- local good = 0
- local bad = 0
- for _,v in pairs(chunkdata) do
- if v.status == 1 then
- good = good + 1
- else
- bad = bad + 1
- end
- end
- self.text = string.format('Chunkloaders online: %d/%d', good, good + bad)
- end
- statusText.eventHandler(app, statusText)
- statusBar:addChild(GUI.button(statusBar.width - 6, 1, 8, 1, C_STATUS_BAR, C_STATUS_TEXT, C_STATUS_BAR, C_STATUS_PRESSED, '[Exit]')).onTouch = function(app, object)
- event.push('exit')
- end
- return app
- end
- function attachScrollbar(obj)
- local width = (obj.width > 60) and 2 or 1
- obj.width = obj.width - width
- local bar = GUI.scrollBar(obj.x + obj.width, obj.y, width, obj.height, C_SCROLLBAR_BACKGROUND, C_SCROLLBAR,
- 0, 1, 0, 1, 4, false)
- obj.parent:addChild(bar)
- obj.scrollBar = bar
- override(obj, 'eventHandler', function(super, app, self, key, ...)
- if key == 'scroll' then
- -- forward scrolls on the main object to the scrollbar
- bar.eventHandler(app, bar, key, ...)
- end
- super(app, self, key, ...)
- end)
- return bar
- end
- -- Start the program
- main()
Add Comment
Please, Sign In to add comment