Skip to content

Instantly share code, notes, and snippets.

@ruliana
Last active August 17, 2023 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruliana/b48dcbaa1ddd92882e9a3cca36d6777f to your computer and use it in GitHub Desktop.
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
---------------------
----- 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