Last active
August 17, 2023 01:16
-
-
Save ruliana/b48dcbaa1ddd92882e9a3cca36d6777f to your computer and use it in GitHub Desktop.
Lua script for print in a screen the belt throughput in FICSIT Network
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--------------------- | |
----- UTILITIES ----- | |
--------------------- | |
-- Utilities to get components from the network | |
function getComponents(className) | |
local compos = component.proxy(component.findComponent(findClass(className))) | |
if #compos == 0 then | |
error(string.format("No component of class \"%s\" found", className)) | |
end | |
return compos | |
end | |
function getComponent(className) | |
return getComponents(className)[1] | |
end | |
function getPCI(className) | |
local device = computer.getPCIDevices(findClass(className))[1] | |
if not device then | |
error(string.format("No device of class \"%s\" found", className)) | |
end | |
return device | |
end | |
-- Transform and key value table into a array of pairs | |
-- Useful for sorting | |
function assocToArr(coll) | |
local rslt = {} | |
for k, v in pairs(coll) do | |
table.insert(rslt, {k, v}) | |
end | |
return rslt | |
end | |
-- Sorting function because table.sort is failing | |
-- with "local jump" error inside the compare function | |
function quicksort(arr, compare, bottom, top) | |
local comp = compare or function (a, b) return a < b end | |
local low = bottom or 1 | |
local high = top or #arr | |
if low < high then | |
local pi = partition(arr, comp, low, high) | |
quicksort(arr, comp, low, pi - 1) | |
quicksort(arr, comp, pi + 1, high) | |
end | |
end | |
function partition(arr, compare, low, high) | |
local pivot = arr[high] | |
local i = low - 1 | |
for j = low, high-1 do | |
if compare(arr[j], pivot) then | |
i = i + 1 | |
arr[i], arr[j] = arr[j], arr[i] | |
end | |
end | |
arr[i + 1], arr[high] = arr[high], arr[i + 1] | |
return i + 1 | |
end | |
--------------------- | |
---- MAIN PROGRAM --- | |
--------------------- | |
-- How many time-of-arrival we are going to store for each item | |
timeQueueSize = 61 | |
local gpu = getPCI("GPUT1") | |
gpu:bindScreen(getComponent("Screen")) | |
gpu:setSize(80, 20) | |
function clear() | |
local w, h = gpu:getSize() | |
gpu:setBackground(0, 0, 0, 0) | |
gpu:fill(0, 0, w, h, " ") | |
end | |
function write(x, y, text) | |
gpu:setForeground(1, 1, 1, 1) | |
gpu:setText(x, y, text) | |
end | |
splitters = getComponents("CodeableSplitter") | |
if #splitters == 0 then | |
error("No splitters connected") | |
end | |
event.ignoreAll() | |
event.clear() | |
for _, splitter in pairs(splitters) do | |
event.listen(splitter) | |
-- Discard the item in the queue when we start | |
-- the system, so events get triggered | |
if splitter:getInput() then | |
splitter:transferItem(1) | |
end | |
end | |
timeAnchor = {} -- Last absolute recorded time for an item | |
timeTable = {} -- Last n time of arrival for each item | |
timeAvg = {} -- Average time of arrivel based on the window above | |
function sortTimeTable(t) | |
local rslt = assocToArr(t) | |
quicksort(rslt, function (a, b) return a[2] < b[2] end) | |
return rslt | |
end | |
local lastUpdate = computer.millis() | |
while true do | |
local msg, sender = event.pull() | |
if msg == "ItemRequest" then | |
-- Add time to the queue under the item name | |
local timeInMillis = computer.millis() | |
local itemName = sender:getInput().type.name | |
local itemTimes = timeTable[itemName] | |
if itemTimes then | |
-- Keep the table with a constant size | |
if #itemTimes >= timeQueueSize then | |
table.remove(itemTimes, 1) | |
end | |
table.insert(itemTimes, timeInMillis) | |
-- Calculate interval | |
local delta = itemTimes[#itemTimes] - itemTimes[1] | |
timeAvg[itemName] = delta / (#itemTimes - 1) | |
else | |
timeTable[itemName] = {timeInMillis} | |
end | |
sender:transferItem(1) | |
-- Print the queue in the screen every 3 seconds | |
local currentUpdate = computer.millis() | |
if currentUpdate - lastUpdate > 3000 then | |
clear() | |
local w, h = gpu:getSize() | |
local col = 1 | |
local row = 0 | |
for _, e in ipairs(sortTimeTable(timeAvg)) do | |
name = e[1] | |
time = e[2] | |
timeInSeconds = math.floor(((time / 100) + 0.5)) / 10 | |
itemsPerMinute = 60000 / time -- 1 / (time / 1000 / 60) | |
write(col, row, string.format("%25s: %5.1f/min (%2d) (%4.1fs)", name, itemsPerMinute, #timeTable[name] - 1, timeInSeconds)) | |
row = row + 1 | |
if row > h then | |
col = 40 | |
row = 0 | |
end | |
end | |
gpu:flush() | |
lastUpdate = currentUpdate | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment