diff --git a/src/lua/core/component.lua b/src/lua/core/component.lua index 764348b..a34324b 100644 --- a/src/lua/core/component.lua +++ b/src/lua/core/component.lua @@ -1,9 +1,124 @@ local component = {} local api = {} +local components = {} + component.api = api +component.components = components + +local componentCallback = { + __call = function(self, ...) return components[self.address].rawproxy[self.name](...) end, + __tostring = function(self) return (components[self.address] ~= nil and components[self.address].doc[self.name] ~= nil) and components[self.address].doc[self.name] or "function" end +} function component.prepare() - print("Assembling initial component tree") + print("Assembling initial component tree") +end + +function api.register(address, ctype, proxy, doc) + checkArg(2, ctype, "string") + checkArg(3, proxy, "table") + if type(address) ~= "string" then + address = random.uuid() + end + if components[address] ~= nil then + return nil, "component already at address" + end + components[address] = {address = address, type = ctype, doc = doc or {}} + components[address].rawproxy = proxy + components[address].proxy = {} + for k,v in pairs(proxy) do + if type(v) == "function" then + components[address].proxy = setmetatable({name=k,address=address}, componentCallback) + else + components[address].proxy = v + end + end + computer.pushSignal("component_added", address, ctype) + return true +end + +function api.unregister(address) + checkArg(1, address, "string") + if components[address] == nil then + return nil, "no component at address" + end + local ctype = components[address].type + components[address] = nil + computer.pushSignal("component_removed", address, ctype) + return true +end + +function api.doc(address, method) + checkArg(1, address, "string") + checkArg(2, method, "string") + if not components[address] then + error("No such component") + end + return components[address].doc[method] +end + +function api.invoke(address, method, ...) + checkArg(1, address, "string") + checkArg(2, method, "string") + if not components[address] then + error("No such component") + end + if not components[address].rawproxy[method] then + error("No such method") + end + return components[address].rawproxy[method](...) +end + +function api.list(filter, exact) + checkArg(1, filter, "string", "nil") + local list = {} + for addr, c in pairs(components) do + if not filter or ((exact and c.type or c.type:sub(1, #filter)) == filter) then + list[addr] = c.type + end + end + local key = nil + return setmetatable(list, {__call=function() + key = next(list, key) + if key then + return key, list[key] + end + end}) +end + +function api.methods(address) + checkArg(1, address, "string") + if not components[address] then + return nil, "No such component" + end + local list = {} + for k, v in pairs(components[address].rawproxy) do + if type(v) == "function" then + list[k] = true + end + end + return list +end + +function api.fields(address) + checkArg(1, address, "string") + if not components[address] then + return nil, "No such component" + end + local list = {} + for k, v in pairs(components[address].rawproxy) do + if type(v) ~= "function" then + list[k] = true + end + end + return list +end + +function api.proxy(address) + if not components[address] then + return nil, "No such component" + end + return components[address].proxy end return component diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index 8b13789..4b3d230 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -1 +1,7 @@ +local computer = {} +function computer.prepare( ... ) + +end + +return computer \ No newline at end of file diff --git a/src/lua/core/init.lua b/src/lua/core/init.lua index cdfe173..d12af33 100644 --- a/src/lua/core/init.lua +++ b/src/lua/core/init.lua @@ -1,3 +1,21 @@ +local function checkArg(n, have, ...) + have = type(have) + local function check(want, ...) + if not want then + return false + else + return have == want or check(...) + end + end + if not check(...) then + local msg = string.format("bad argument #%d (%s expected, got %s)", + n, table.concat({...}, " or "), have) + error(msg, 3) + end +end + +------------------------------------------------------------------------------- + print("LuPI L1 INIT") modules = {} @@ -8,7 +26,12 @@ local function loadModule(name) if not moduleCode[name] then error("No code for module " .. tostring(name)) end - modules[name] = load(moduleCode[name])() + local code, reason = load(moduleCode[name]) + if not code then + print("Failed loading module " .. name .. ": " .. reason) + else + modules[name] = code() + end end --Load modules @@ -20,5 +43,6 @@ loadModule("boot") --Setup core modules modules.component.prepare() +modules.computer.prepare() modules.boot.boot()