lua/minit.lua
2025-07-09 12:56:25 +00:00

189 lines
4.6 KiB
Lua

-- Minit Beta 1.0.0
-- Copyright (C) 2023 AlexDevs
-- This software is licensed under the MIT license.
settings.define("minit.cycleSleep", {
description = "Sleep time between cycles",
type = "number",
default = 0.1,
})
settings.define("minit.cycleTimeout", {
description = "Cycles timeout",
type = "number",
default = 1,
})
settings.define("minit.modulesPath", {
description = "Path to modules",
type = "string",
default = "modules",
})
local modulesPath = settings.get("minit.modulesPath")
local neuralInterface
local expect = require("cc.expect").expect
local logPrefix = "%s %s:"
local function getTime()
return os.date("%H:%M:%S")
end
local function log(label, ...)
local time = getTime()
print(string.format(logPrefix, time, label), ...)
end
local function logError(label, ...)
local time = getTime()
printError(string.format(logPrefix, time, label), ...)
end
local modules = {}
local function loadModules()
log("Minit", "Loading modules from /" .. modulesPath)
local files = fs.list(modulesPath)
for i = 1, #files do
local ok, par = pcall(require, fs.combine(modulesPath, files[i])
:gsub("/", ".")
:gsub("%.lua$", ""))
if ok then
par.name = par.name or files[i]:gsub("%.lua$", "")
table.insert(modules, par)
log("Minit", "Loaded module " .. par.name)
else
logError("Minit", "Could not load module " .. files[i] .. ": " .. par)
end
end
end
local function getCallbacks(name, ...)
local args = table.pack(...)
local callbacks = {}
for i = 1, #modules do
local module = modules[i]
if type(module[name]) == "function" then
table.insert(callbacks, function()
module[name](table.unpack(args))
end)
end
end
return table.unpack(callbacks)
end
local tasks = {}
local function addTask(task)
expect(1, task, "function")
table.insert(tasks, coroutine.create(task))
end
local function initModules()
for i = 1, #modules do
local module = modules[i]
if type(module.init) == "function" then
module.init({
addTask = addTask,
log = function(...)
log(module.name, ...)
end,
logError = function(...)
logError(module.name, ...)
end,
})
end
end
end
local function setupNeuralInterface()
neuralInterface = peripheral.wrap("back")
if not neuralInterface then
error("No neural interface found")
end
-- Wait for owner to be alive
local function getOwner()
local meta
parallel.waitForAny(function()
meta = neuralInterface.getMetaOwner()
end, function()
sleep(1)
end)
return meta
end
local meta = getOwner()
if not meta or not meta.isAlive then
log("Minit", "Waiting for respawn...")
end
while not meta or not meta.isAlive do
sleep(0.2)
meta = getOwner()
end
parallel.waitForAll(getCallbacks("setup", neuralInterface))
end
local function cycleUpdate()
local metaOwner = neuralInterface.getMetaOwner()
parallel.waitForAll(getCallbacks("update", metaOwner))
sleep(settings.get("minit.cycleSleep"))
end
local function tasksHandler()
local ev = { n = 0 }
local filters = {}
while true do
for i, thread in pairs(tasks) do
if coroutine.status(thread) == "dead" then
tasks[i] = nil
filters[i] = nil
else
if filters[i] == nil or filters[i] == ev[1] or ev[1] == "terminate" then
local ok, param = coroutine.resume(thread, table.unpack(ev, 1, ev.n))
if not ok then
logError("Task", param)
else
filters[i] = param
end
end
end
end
ev = table.pack(coroutine.yield())
end
end
local function main()
setupNeuralInterface()
while true do
parallel.waitForAny(
cycleUpdate,
function()
sleep(settings.get("minit.cycleTimeout"))
end
)
end
end
loadModules()
initModules()
parallel.waitForAny(
function()
while true do
local ok, err = pcall(main)
if not ok then
if err == "Terminated" then
break
end
logError("Minit", err)
sleep(1)
end
end
end,
tasksHandler
)