From 39897457f90fb843ed476f16619eb269769703ee Mon Sep 17 00:00:00 2001 From: WahPlus Date: Wed, 17 Sep 2025 20:54:56 +0300 Subject: [PATCH] Added log printing on the screen on startup. The log library now prints all the logs on startup. --- halyde/kernel/boot.lua | 22 +++++++++++++--------- halyde/kernel/tsched.lua | 38 ++++++++++++++++++++++++-------------- halyde/shell/shell.lua | 14 ++++++++++---- lib/component.lua | 32 ++++++++++++++++++-------------- lib/log.lua | 36 +++++++++++++++++++++++++++++++++++- 5 files changed, 100 insertions(+), 42 deletions(-) diff --git a/halyde/kernel/boot.lua b/halyde/kernel/boot.lua index 7803964..1172b2f 100644 --- a/halyde/kernel/boot.lua +++ b/halyde/kernel/boot.lua @@ -4,8 +4,17 @@ _G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file _G._OSLOGO = "" _G._PUBLIC = {} _G._PUBLIC.unicode = assert(loadfile("/lib/unicode.lua")(loadfile)) +local component = assert(loadfile("/lib/component.lua")(loadfile)) +local gpu = component.gpu +local screenAddress = component.list("screen")() + +gpu.bind(screenAddress) +gpu.setResolution(gpu.maxResolution()) + local log = assert(loadfile("/lib/log.lua")(loadfile)) +log.kernel.info("Bound GPU to screen " .. tostring(screenAddress)) + local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil repeat tmpdata = handle:read(math.huge) @@ -68,16 +77,11 @@ log.kernel.info("Loading modules") require("/halyde/kernel/modload.lua") package.preload("component") +log.kernel.info("Pre-loaded /lib/component.lua") package.preload("computer") -log.kernel.info("Pre-loaded low-level packages") - -local component = require("component") -local gpu = component.gpu -local screenAddress = component.list("screen")() - -gpu.bind(screenAddress) -gpu.setResolution(gpu.maxResolution()) -log.kernel.info("Bound GPU to screen " .. tostring(screenAddress)) +log.kernel.info("Pre-loaded /lib/computer.lua") +package.preload("log") +log.kernel.info("Pre-loaded /lib/log.lua") if not filesystem.exists("/halyde/config/shell.json") then -- Auto-generate configs filesystem.copy("/halyde/config/generate/shell.json", "/halyde/config/shell.json") diff --git a/halyde/kernel/tsched.lua b/halyde/kernel/tsched.lua index 4b35129..0df42e4 100644 --- a/halyde/kernel/tsched.lua +++ b/halyde/kernel/tsched.lua @@ -11,8 +11,10 @@ local computer = require("computer") local filesystem = require("filesystem") local json = require("json") local gpu = component.gpu -function _G._PUBLIC.tsched.runAsTask(path,...) - local args = {...} +local log = require("log") + +function _G._PUBLIC.tsched.runAsTask(path, ...) + local args = { ... } local function taskFunction() local result, errorMessage = xpcall(function(...) local args = table.pack(...) @@ -29,13 +31,13 @@ function _G._PUBLIC.tsched.runAsTask(path,...) -- 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) + 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)) + assert(load(data, "=" .. path, "t", userland))(table.unpack(args)) end, function(errorMessage) return errorMessage .. "\n \n" .. debug.traceback() end, --[[ path,]] table.unpack(args)) @@ -49,19 +51,25 @@ function _G._PUBLIC.tsched.runAsTask(path,...) end --require(path, table.unpack(args)) end - local _,taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$")) + 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 + 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 @@ -70,14 +78,16 @@ function _G._PUBLIC.tsched.removeTask(id) 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 (if this isn't considered proper..?) + 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()) @@ -138,6 +148,7 @@ end _PUBLIC.tsched.addTask(taskFunction, "evmgr") 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) @@ -155,12 +166,11 @@ for _, line in ipairs(json.decode(data)) do end -- _G.cormgr.loadCoroutine("/halyde/core/shell.lua") +log.setPrintLogs(false) while true do runTasks() if #_G.tsched.tasks == 0 then - computer.beep(1000, 0.5) - while true do - computer.pullSignal() - end + log.kernel.warn("No more tasks left! Shutting down...") + computer.shutdown() end end diff --git a/halyde/shell/shell.lua b/halyde/shell/shell.lua index 65afe1d..3b0ba0e 100644 --- a/halyde/shell/shell.lua +++ b/halyde/shell/shell.lua @@ -18,21 +18,25 @@ _G.shell = {} function _G.shell.getWorkingDirectory() return workingDirectory end + function _G.shell.setWorkingDirectory(dir) checkArg(1, dir, "string") workingDirectory = dir end + function _G.shell.getAliases() return table.copy(aliases) end + function _G.shell.addAlias(executable, aliasName) checkArg(1, executable, "string") checkArg(2, aliasName, "string") - aliases[aliasName]=executable + aliases[aliasName] = executable end + function _G.shell.removeAlias(aliasName) checkArg(1, aliasName, "string") - aliases[aliasName]=nil + aliases[aliasName] = nil end local function runAsTask(path, ...) @@ -99,7 +103,7 @@ function _G.shell.run(command) return end for _, item in pairs(PATH) do - if fs.exists(item..args[1]) and not fs.isDirectory(item .. args[1]) then + if fs.exists(item .. args[1]) and not fs.isDirectory(item .. args[1]) then local path = fs.concat(item, args[1]) table.remove(args, 1) runAsTask(path, table.unpack(args)) @@ -116,12 +120,14 @@ function _G.shell.run(command) end end end - print("No such file or command: "..args[1]) + print("No such file or command: " .. args[1]) end local shareTable = ipc.shareWithAll() shareTable.shell = _G.shell +terminal.clear() + print(shellcfg["startupMessage"]:format(_OSVERSION, shellcfg.splashMessages[math.random(1, #shellcfg.splashMessages)])) while true do coroutine.yield() diff --git a/lib/component.lua b/lib/component.lua index e48288b..ec4b71f 100644 --- a/lib/component.lua +++ b/lib/component.lua @@ -11,7 +11,7 @@ end --local ocelot = LLcomponent.proxy(LLcomponent.list("ocelot")()) --ocelot.log("loaded") -_G.componentlib = {["additions"] = {}, ["removals"] = {}} +_G.componentlib = { ["additions"] = {}, ["removals"] = {} } compLib.virtual = {} function compLib.virtual.add(address, componentType, proxy) @@ -23,7 +23,7 @@ function compLib.virtual.add(address, componentType, proxy) if _PUBLIC.tsched then proc = _PUBLIC.tsched.getCurrentTask() end - componentlib.additions[address] = {["componentType"] = componentType, ["proxy"] = proxy, ["proc"] = proc} + componentlib.additions[address] = { ["componentType"] = componentType, ["proxy"] = proxy, ["proc"] = proc } if componentlib.removals[address] then componentlib.removals[address] = nil end @@ -49,7 +49,7 @@ end function compLib.list(componentType) checkArg(1, componentType, "string", "nil") - local componentList = table.copy(LLcomponent.list(componentType)) + local componentList = LLcomponent.list(componentType) for address, dataTable in pairs(componentlib.additions) do if dataTable.componentType == componentType or not componentType then componentList[address] = dataTable.componentType @@ -59,10 +59,12 @@ function compLib.list(componentType) componentList[address] = nil end local i, value - setmetatable(componentList, {__call = function(self) - i, value = next(self, i) - return i, value - end}) + setmetatable(componentList, { + __call = function(self) + i, value = next(self, i) + return i, value + end + }) return componentList end @@ -93,19 +95,21 @@ function compLib.get(address) end for currentAddress, name in compLib.list() do if currentAddress:find("^" .. address) then - return(currentAddress) + return (currentAddress) end end return nil, "full address not found" end -- Add main component proxies to the library -setmetatable(compLib, {["__index"] = function(_, item) - if compLib.list(item)() then - return compLib.proxy(compLib.list(item)()) - else - return compLib[item] +setmetatable(compLib, { + ["__index"] = function(_, item) + if compLib.list(item)() then + return compLib.proxy(compLib.list(item)()) + else + return compLib[item] + end end -end}) +}) return compLib diff --git a/lib/log.lua b/lib/log.lua index 3607c1c..8630ed2 100644 --- a/lib/log.lua +++ b/lib/log.lua @@ -1,15 +1,24 @@ -local fs, computer +local fs, computer, gpu local chunkSize = 1024 if require then fs = require("filesystem") computer = require("computer") + gpu = require("component").gpu else local loadfile = ... fs = loadfile("/lib/filesystem.lua")(loadfile) computer = _G.computer + gpu = loadfile("/lib/component.lua")(loadfile).gpu end +local resX, resY = gpu.getResolution() local log = {} +if not _G.logSettings then + _G.logSettings = { -- We have to preload the library just for this :P + ["printLogs"] = true, + ["printerY"] = 1 + } +end local logFileSizeLimit = 16384 @@ -60,6 +69,26 @@ local function writeToLog(path, text) readHandle:close() writeHandle:close() end + + if _G.logSettings.printLogs then + -- Print onscreen + if text:sub(1, 4) == "INFO" then -- Set color + gpu.setForeground(0xFFFFFF) + elseif text:sub(1, 4) == "WARN" then + gpu.setForeground(0xFFFF00) + elseif text:sub(1, 5) == "ERROR" then + gpu.setForeground(0xFF0000) + end + repeat -- Line wrapping + if _G.logSettings.printerY > resY then + gpu.copy(1, 2, resX, resY - 1, 0, -1) + _G.logSettings.printerY = resY + end + gpu.set(1, _G.logSettings.printerY, text .. string.rep(" ", resX - #text)) + text = text:sub(resX + 1) + _G.logSettings.printerY = _G.logSettings.printerY + 1 + until text == "" + end end setmetatable(log, { @@ -82,4 +111,9 @@ setmetatable(log, { end, }) +function log.setPrintLogs(setting) -- Yes, this works with the metatable. + checkArg(1, setting, "boolean") + _G.logSettings.printLogs = setting +end + return log