diff --git a/halyde/kernel/modload.lua b/halyde/kernel/modload.lua index 68c863a..619552f 100644 --- a/halyde/kernel/modload.lua +++ b/halyde/kernel/modload.lua @@ -8,50 +8,58 @@ local modules = {} local moduleTypes = {} local function loadModule(modName) - local moduleData = modules[modName] - table.remove(moduleList, table.find(moduleList, modName)) - if not moduleData then return end - if not moduleData.check() then - return - end - if moduleData.dependencies then - for _, dependency in pairs(moduleData.dependencies) do - if table.find(moduleList, dependency) then - loadModule(dependency) - elseif table.find(moduleList, dependency .. ".lua") then - loadModule(dependency .. ".lua") - else - for typeLookupDrvName, typeLookupDrvType in pairs(moduleTypes) do - if typeLookupDrvType == dependency then - loadModule(typeLookupDrvName) - -- Don't break, because there can be multiple modules of the correct type - end - end - end - end - end - --print(modName) - if moduleData.init then -- I have no idea why this would not exist, but it's a failsafe - moduleData.init() - end + local moduleData = modules[modName] + table.remove(moduleList, table.find(moduleList, modName)) + if not moduleData then + log.kernel.warn(string.format("[modload: %s] Could not find module data.", modName)) + return + end + if not moduleData.check() then + log.kernel.info(string.format("[modload: %s] Module not ready - skipping", modName)) + return + end + if moduleData.dependencies then + for _, dependency in pairs(moduleData.dependencies) do + if table.find(moduleList, dependency) then + loadModule(dependency) + elseif table.find(moduleList, dependency .. ".lua") then + loadModule(dependency .. ".lua") + else + for typeLookupDrvName, typeLookupDrvType in pairs(moduleTypes) do + if typeLookupDrvType == dependency then + loadModule(typeLookupDrvName) + -- Don't break, because there can be multiple modules of the correct type + end + end + end + end + end + --print(modName) + log.kernel.info(string.format("[modload: %s] Loading module", modName)) + if moduleData.init then -- I have no idea why this would not exist, but it's a failsafe + moduleData.init() + end end for _, modName in pairs(moduleList) do -- Get all the module types - local moduleData = require(fs.concat(modulePath, modName)) -- TODO: Make this not actually throw an error, rather put something in the log and move on - if type(moduleData)~="table" then - log.add(string.format("[modload: %s] Module returned invalid type (%s) - skipping",modName,type(moduleData)),"error") - goto continue - end - modules[modName]=moduleData - if moduleData.type then - --print(moduleData.type) - moduleTypes[modName] = moduleData.type -- Not the other way around because there can be multiple modules of the same type, but there can't be multiple entries with the same key - end - ::continue:: + log.kernel.info(string.format("[modload: %s] Getting data from module", modName)) + local moduleData = require(fs.concat(modulePath, modName)) -- TODO: Make this not actually throw an error, rather put something in the log and move on + if type(moduleData) ~= "table" then + log.kernel.error( + string.format("[modload: %s] Module returned invalid type (%s) - skipping", modName, type(moduleData)) + ) + goto continue + end + modules[modName] = moduleData + if moduleData.type then + --print(moduleData.type) + moduleTypes[modName] = moduleData.type -- Not the other way around because there can be multiple modules of the same type, but there can't be multiple entries with the same key + end + ::continue:: end while moduleList[1] do - if moduleList[1]:sub(-1, -1) ~= "/" then -- Check if it's not a directory. If it is, it might be module config - loadModule(moduleList[1]) - end + if moduleList[1]:sub(-1, -1) ~= "/" then -- Check if it's not a directory. If it is, it might be module config + loadModule(moduleList[1]) + end end diff --git a/halyde/kernel/tsched.lua b/halyde/kernel/tsched.lua index 0df42e4..8bf9643 100644 --- a/halyde/kernel/tsched.lua +++ b/halyde/kernel/tsched.lua @@ -14,136 +14,139 @@ local gpu = component.gpu local log = require("log") function _G._PUBLIC.tsched.runAsTask(path, ...) - local args = { ... } - local function taskFunction() - local result, errorMessage = xpcall(function(...) - local args = table.pack(...) - if not filesystem.exists(path) then - error("No such file: " .. path) - end - local handle, data, tmpdata = filesystem.open(path), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() + local args = { ... } + local function taskFunction() + local result, errorMessage = xpcall(function(...) + local args = table.pack(...) + if not filesystem.exists(path) then + error("No such file: " .. path) + end + local handle, data, tmpdata = filesystem.open(path), "", nil + repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + handle:close() - -- Userland environment definition - local userland = table.copy(_PUBLIC) - userland._G = userland - userland.load = function(chunk, chunkname, mode, env) - if not env or env == _G then env = userland end -- if they SOMEHOW get the kernel environment they're not running jack shit - return load(chunk, chunkname, mode, env) - end - userland.require = reqgen(userland.load) + -- Userland environment definition + local userland = table.copy(_PUBLIC) + userland._G = userland + userland.load = function(chunk, chunkname, mode, env) + if not env or env == _G then + env = userland + end -- if they SOMEHOW get the kernel environment they're not running jack shit + return load(chunk, chunkname, mode, env) + end + userland.require = reqgen(userland.load) - assert(load(data, "=" .. path, "t", userland))(table.unpack(args)) - end, function(errorMessage) - return errorMessage .. "\n \n" .. debug.traceback() - end, --[[ path,]] table.unpack(args)) - if not result then - if print then - gpu.freeAllBuffers() - print("\n\27[91m" .. errorMessage) - else - error(errorMessage) - end - end - --require(path, table.unpack(args)) - end - local _, taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) - taskInfo.path = path - taskInfo.args = table.copy(args) + assert(load(data, "=" .. path, "t", userland))(table.unpack(args)) + end, function(errorMessage) + return errorMessage .. "\n \n" .. debug.traceback() + end, --[[ path,]] table.unpack(args)) + if not result then + if print then + gpu.freeAllBuffers() + print("\n\27[91m" .. errorMessage) + else + error(errorMessage) + end + end + --require(path, table.unpack(args)) + end + local _, taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) + taskInfo.path = path + taskInfo.args = table.copy(args) end function _G._PUBLIC.tsched.addTask(func, name) - local task = coroutine.create(func) - local taskInfo = { ["task"] = task, ["name"] = name, ["id"] = idCounter } - if currentTask and type(currentTask.id) == "number" then - taskInfo.parent = currentTask.id - end - table.insert(tsched.tasks, taskInfo) - idCounter = idCounter + 1 - if taskInfo.parent then - log.kernel.info("Created task " .. name .. " with PID " .. idCounter - 1 .. " by parent with PID " .. taskInfo - .parent) - else - log.kernel.info("Created task " .. name .. " with PID " .. idCounter - 1 .. " (no parent found)") - end - return task, taskInfo + local task = coroutine.create(func) + local taskInfo = { ["task"] = task, ["name"] = name, ["id"] = idCounter } + if currentTask and type(currentTask.id) == "number" then + taskInfo.parent = currentTask.id + end + table.insert(tsched.tasks, taskInfo) + idCounter = idCounter + 1 + if taskInfo.parent then + log.kernel.info( + "Created task " .. name .. " with PID " .. idCounter - 1 .. " by parent with PID " .. taskInfo.parent + ) + else + log.kernel.info("Created task " .. name .. " with PID " .. idCounter - 1 .. " (no parent found)") + end + return task, taskInfo end function _G._PUBLIC.tsched.removeTask(id) - -- TODO: Check for user permissions before running - for index, task in pairs(tsched.tasks) do - if task.id == id then - table.remove(tsched.tasks, index) - log.kernel.info("Removed task with PID " .. id) - return true - end - end - log.kernel.warn("Tried to remove task that doesn't exist - PID " .. id) - return false + -- TODO: Check for user permissions before running + for index, task in pairs(tsched.tasks) do + if task.id == id then + table.remove(tsched.tasks, index) + log.kernel.info("Removed task with PID " .. id) + return true + end + end + log.kernel.warn("Tried to remove task that doesn't exist - PID " .. id) + return false end function handleError(errormsg) - if errormsg == nil then -- TODO: Replace with proper error handling - print("\27[91munknown error" .. "\n \n" .. debug.traceback()) - else - print("\27[91m" .. tostring(errormsg) .. "\n \n" .. debug.traceback()) - end + if errormsg == nil then -- TODO: Replace with proper error handling + print("\27[91munknown error" .. "\n \n" .. debug.traceback()) + else + print("\27[91m" .. tostring(errormsg) .. "\n \n" .. debug.traceback()) + end end local function runTasks() - for i = 1, #_G.tsched.tasks do - if tsched.tasks[i] then - currentTask = tsched.tasks[i] - local result, errorMessage = coroutine.resume(tsched.tasks[i].task) - if not result then - handleError(errorMessage) - end - if coroutine.status(tsched.tasks[i].task) == "dead" then - _PUBLIC.tsched.removeTask(tsched.tasks[i].id) - --ocelot.log("Removed coroutine") - i = i - 1 - end - --computer.pullSignal(0) - --coroutine.yield() - end - end + for i = 1, #_G.tsched.tasks do + if tsched.tasks[i] then + currentTask = tsched.tasks[i] + local result, errorMessage = coroutine.resume(tsched.tasks[i].task) + if not result then + handleError(errorMessage) + end + if coroutine.status(tsched.tasks[i].task) == "dead" then + _PUBLIC.tsched.removeTask(tsched.tasks[i].id) + --ocelot.log("Removed coroutine") + i = i - 1 + end + --computer.pullSignal(0) + --coroutine.yield() + end + end end function _G._PUBLIC.tsched.getCurrentTask() - return table.copy(currentTask) + return table.copy(currentTask) end function _G._PUBLIC.tsched.getTasks() - return table.copy(tsched.tasks) + return table.copy(tsched.tasks) end local function taskFunction() - local result, errorMessage = xpcall(function() - if not filesystem.exists("/halyde/kernel/evmgr.lua") then - error("No such file: /halyde/kernel/evmgr.lua") - end - local handle, data, tmpdata = filesystem.open("/halyde/kernel/evmgr.lua"), "", nil - repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") - until not tmpdata - handle:close() - assert(load(data, "=/halyde/kernel/evmgr.lua"))() - end, function(errorMessage) - return errorMessage .. "\n \n" .. debug.traceback() - end, "/halyde/kernel/evmgr.lua") - if not result then - if print then - gpu.freeAllBuffers() - print("\n\27[91m" .. errorMessage) - else - error(errorMessage) - end - end + local result, errorMessage = xpcall(function() + if not filesystem.exists("/halyde/kernel/evmgr.lua") then + error("No such file: /halyde/kernel/evmgr.lua") + end + local handle, data, tmpdata = filesystem.open("/halyde/kernel/evmgr.lua"), "", nil + repeat + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") + until not tmpdata + handle:close() + assert(load(data, "=/halyde/kernel/evmgr.lua"))() + end, function(errorMessage) + return errorMessage .. "\n \n" .. debug.traceback() + end, "/halyde/kernel/evmgr.lua") + if not result then + if print then + gpu.freeAllBuffers() + print("\n\27[91m" .. errorMessage) + else + error(errorMessage) + end + end end _PUBLIC.tsched.addTask(taskFunction, "evmgr") package.preload("event") @@ -151,26 +154,26 @@ package.preload("event") log.kernel.info("Starting startup apps...") local handle, data, tmpdata = filesystem.open("/halyde/config/startupapps.json", "r"), "", nil repeat - tmpdata = handle:read(math.huge or math.maxinteger) - data = data .. (tmpdata or "") + tmpdata = handle:read(math.huge or math.maxinteger) + data = data .. (tmpdata or "") until not tmpdata handle:close() for _, line in ipairs(json.decode(data)) do - if line ~= "" then - --[[ if _G.print then + if line ~= "" then + --[[ if _G.print then print(line) end ]] - _G._PUBLIC.tsched.runAsTask(line) - runTasks() - end + _G._PUBLIC.tsched.runAsTask(line) + runTasks() + end end -- _G.cormgr.loadCoroutine("/halyde/core/shell.lua") log.setPrintLogs(false) while true do - runTasks() - if #_G.tsched.tasks == 0 then - log.kernel.warn("No more tasks left! Shutting down...") - computer.shutdown() - end + runTasks() + if #_G.tsched.tasks == 0 then + log.kernel.warn("No more tasks left! Shutting down...") + computer.shutdown() + end end