189 lines
4.6 KiB
Lua
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
|
|
)
|