ALPHA 3.0.0 - Added Inter-Process Communication and fixed the bug where the shell would continue taking in input when a command was still running.

This commit is contained in:
WahPlus
2025-08-21 21:03:17 +03:00
parent 5276d2437b
commit ef0ffa1886
10 changed files with 208 additions and 73 deletions
+1 -3
View File
@@ -3,7 +3,6 @@ local filesystem = assert(loadfile("/lib/filesystem.lua")(loadfile))
_G._OSVERSION = "HALYDE VERSION" -- TODO: Put this in a separate config file
_G._OSLOGO = ""
_G._PUBLIC = {}
local ocelot = component.proxy(component.list("ocelot")())
local handle, tmpdata = filesystem.open("/halyde/config/oslogo.ans", "r"), nil
repeat
@@ -16,7 +15,6 @@ _G.package = {["preloaded"] = {}}
loadfile("/halyde/kernel/modules/datatools.lua")()
function _G.require(module, ...)
ocelot.log("Requiring " .. module)
local args = table.pack(...)
if package.preloaded[module] then
return package.preloaded[module]
@@ -50,7 +48,7 @@ function _G.package.preload(module)
_G[module] = nil
end
require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools.
require("/halyde/kernel/datatools.lua") -- If this is not imported BEFORE modload gets run, modload requires filesystem which requires computer which requires datatools. TODO: When VFS is implemented, make the pre-VFS loading of filesystem load a more basic version. And remove this.
require("/halyde/kernel/modload.lua")
package.preload("component")
+1 -1
View File
@@ -30,7 +30,7 @@ while true do
if print then
print("\n\27[91mCoroutine "..tostring(#tsched.tasks).." killed.")
end
tsched.tasks[#tsched.tasks] = nil
table.remove(tsched.tasks, #tsched.tasks)
end
elseif args[2] == "key_up" then
local keycode = args[5]
+3 -8
View File
@@ -1,19 +1,16 @@
local fs = require("filesystem")
local ocelot = require("component").ocelot
local modulePath = "/halyde/kernel/modules"
local modules = fs.list(modulePath)
local modules = assert(fs.list(modulePath))
local moduleTypes = {}
local function loadModule(modName)
ocelot.log("Checking module " .. modName)
local moduleData = require(fs.concat(modulePath, modName))
local moduleData = assert(require(fs.concat(modulePath, modName)), "Module did not return anything!") -- TODO: Make this not actually throw an error, rather put something in the log and move on
table.remove(modules, table.find(modules, modName))
if not moduleData.check() then
return
end
ocelot.log("Loading module " .. modName)
if moduleData.dependencies then
for _, dependency in pairs(moduleData.dependencies) do
if table.find(modules, dependency) then
@@ -37,7 +34,7 @@ local function loadModule(modName)
end
for _, modName in pairs(modules) do -- Get all the module types
local moduleData = require(fs.concat(modulePath, modName))
local moduleData = assert(require(fs.concat(modulePath, modName)), "Module did not return anything!") -- TODO: Make this not actually throw an error, rather put something in the log and move on
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
@@ -49,5 +46,3 @@ while modules[1] do
loadModule(modules[1])
end
end
ocelot.log("Finished loading modules!")
+112 -2
View File
@@ -1,15 +1,125 @@
local module = {}
function module.check()
return true -- This module should always be loaded
return true -- IPC should always be loaded
end
function module.init()
_G.ipc = {}
_G.ipc.shared = {}
_PUBLIC.ipc = {}
function _PUBLIC.ipc.shareWithAll()
local shareTable = {}
setmetatable(shareTable, {["__newindex"] = function(_, key, value)
local currentPID = _PUBLIC.tsched.getCurrentTask().id
if not _G.ipc.shared[currentPID] then
_G.ipc.shared[currentPID] = {} -- TODO: Add some kind of cleanup routine since these IPC shares can just keep piling up
end
local globalTable
for _, tab in pairs(_G.ipc.shared[currentPID]) do
if tab.sharedWith == "all" then
globalTable = tab
end
end
if not globalTable then
globalTable = {["sharedWith"] = "all"}
table.insert(_G.ipc.shared[currentPID], globalTable)
end
if not globalTable.vars then
globalTable.vars = {}
end
globalTable.vars[key] = value
end, ["__index"] = function(_, key)
local currentPID = _PUBLIC.tsched.getCurrentTask().id
if not _G.ipc.shared[currentPID] then
return nil
end
local globalTable
for _, tab in pairs(_G.ipc.shared[currentPID]) do
if tab.sharedWith == "all" then
globalTable = tab
end
end
if not globalTable then
return nil
end
if not globalTable.vars then
return nil
end
return globalTable.vars[key]
end})
return shareTable
end
function _PUBLIC.ipc.shareWith(pid)
checkArg(1, pid, "number")
local shareTable = {}
setmetatable(shareTable, {["__newindex"] = function(_, key, value)
local currentPID = _PUBLIC.tsched.getCurrentTask().id
if not _G.ipc.shared[currentPID] then
_G.ipc.shared[currentPID] = {} -- TODO: Add some kind of cleanup routine since these IPC shares can just keep piling up
end
local globalTable
for _, tab in pairs(_G.ipc.shared[currentPID]) do
if tab.sharedWith == "all" then
globalTable = tab
end
end
if not globalTable then
globalTable = {["sharedWith"] = pid}
table.insert(_G.ipc.shared[currentPID], globalTable)
end
if not globalTable.vars then
globalTable.vars = {}
end
globalTable.vars[key] = value
end, ["__index"] = function(_, key)
local currentPID = _PUBLIC.tsched.getCurrentTask().id
if not _G.ipc.shared[currentPID] then
return nil
end
local globalTable
for _, tab in pairs(_G.ipc.shared[currentPID]) do
if tab.sharedWith == pid then
globalTable = tab
end
end
if not globalTable then
return nil
end
if not globalTable.vars then
return nil
end
return globalTable.vars[key]
end})
return shareTable
end
_PUBLIC.ipc.shared = {}
setmetatable(_PUBLIC.ipc.shared, {["__index"] = function(_, pid)
local currentPID = _PUBLIC.tsched.getCurrentTask().id
local returnTable = {}
for _, shareTable in pairs(ipc.shared[pid] or {}) do
if shareTable.sharedWith == currentPID then
for key, value in pairs(shareTable.vars) do
returnTable[key] = table.copy(value)
end
elseif shareTable.sharedWith == "all" then
for key, value in pairs(shareTable.vars) do
if not returnTable[key] then
returnTable[key] = table.copy(value)
end
end
end
end
return returnTable
end})
end
function module.exit()
_G.ipc = nil
_PUBLIC.ipc = nil
end
return module
+12 -6
View File
@@ -1,3 +1,5 @@
local idCounter = 1
_G._PUBLIC.tsched = {}
_G.tsched = {}
_G.tsched.tasks = {}
@@ -9,8 +11,6 @@ local computer = require("computer")
local filesystem = require("filesystem")
local json = require("json")
local gpu = component.gpu
local ocelot = component.ocelot
function _G._PUBLIC.tsched.runAsTask(path,...)
local args = {...}
local function taskFunction()
@@ -48,15 +48,21 @@ function _G._PUBLIC.tsched.runAsTask(path,...)
end
function _G._PUBLIC.tsched.addTask(func, name)
ocelot.log("Added task " .. name)
local task = coroutine.create(func)
table.insert(tsched.tasks, {["task"] = task, ["name"] = name})
table.insert(tsched.tasks, {["task"] = task, ["name"] = name, ["id"] = idCounter})
idCounter = idCounter + 1
return task
end
function _G._PUBLIC.tsched.removeTask(id)
-- TODO: Check for user permissions before running
table.remove(_G.tsched.tasks, id)
for index, task in pairs(tsched.tasks) do
if task.id == id then
table.remove(tsched.tasks, index)
return true
end
end
return false
end
function handleError(errormsg)
@@ -76,7 +82,7 @@ local function runTasks()
handleError(errorMessage)
end
if coroutine.status(tsched.tasks[i].task) == "dead" then
_PUBLIC.tsched.removeTask(i)
_PUBLIC.tsched.removeTask(tsched.tasks[i].id)
--ocelot.log("Removed coroutine")
i = i - 1
end