Files
Halyde/lib/component.lua
2026-06-15 19:37:48 +03:00

141 lines
3.8 KiB
Lua

local computer
if require then
-- libcomponent can get loaded early enough in the boot process where require is not present
computer = require("computer")
else
computer = _G.computer
end
local compLib
local LLcomponent
if table.copy then
compLib = table.copy(component)
LLcomponent = table.copy(component)
else
compLib = {}
LLcomponent = component
end
-- local ocelot = LLcomponent.proxy(LLcomponent.list("ocelot")())
-- ocelot.log("loaded")
_G.componentlib = { ["additions"] = {}, ["removals"] = {} }
compLib.virtual = {}
function compLib.virtual.add(address, componentType, proxy)
checkArg(1, address, "string")
checkArg(2, componentType, "string")
checkArg(3, proxy, "table")
proxy["address"] = address
local proc
if _PUBLIC.tsched then
proc = _PUBLIC.tsched.getCurrentTask()
end
componentlib.additions[address] = { ["componentType"] = componentType, ["proxy"] = proxy, ["proc"] = proc }
if componentlib.removals[address] then
componentlib.removals[address] = nil
end
computer.pushSignal("component_added", address, componentType)
end
function compLib.virtual.remove(address)
checkArg(1, address, "string")
if componentlib.additions[address] then
computer.pushSignal("component_removed", address, componentlib.additions[address].componentType)
componentlib.additions[address] = nil
else
local componentTypeOutput = compLib.type(address)
computer.pushSignal("component_removed", address, componentTypeOutput or "unknown")
table.insert(componentlib.removals, address)
end
end
function compLib.virtual.check(address)
checkArg(1, address, "string")
if _G.componentlib.additions[address] then
return true, _G.componentlib.additions[address].proc
else
return false
end
end
function compLib.list(componentType)
checkArg(1, componentType, "string", "nil")
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
end
end
for _, address in pairs(componentlib.removals) do
componentList[address] = nil
end
local i, value
setmetatable(componentList, {
__call = function(self)
i, value = next(self, i)
return i, value
end,
})
return componentList
end
function compLib.proxy(address)
if componentlib.additions[address] then
--ocelot.log("vcomponent")
return componentlib.additions[address].proxy
else
return LLcomponent.proxy(address)
end
end
function compLib.invoke(address, funcName, ...)
--ocelot.log("Invoking " .. funcName .. " from " .. address)
if componentlib.additions[address] then
--ocelot.log("vcomponent")
if not componentlib.additions[address].proxy[funcName] then
error("no such method")
end
return componentlib.additions[address].proxy[funcName](...)
else
return LLcomponent.invoke(address, funcName, ...)
end
end
function compLib.get(address)
checkArg(1, address, "string")
if #address < 3 then
return nil, "abbreviated address must be at least 3 characters long"
end
for currentAddress, name in compLib.list() do
if currentAddress:find("^" .. address) then
return currentAddress
end
end
return nil, "full address not found"
end
function compLib.isAvailable(componentType)
checkArg(1, componentType, "string")
if LLcomponent.list(componentType)() then
return true
else
return false
end
end
-- Add main component proxies to the library
setmetatable(compLib, {
["__index"] = function(_, item)
if LLcomponent.list(item)() then
return compLib.proxy(compLib.list(item)())
else
-- Why did I ever fucking write this??
-- return compLib[item]
return nil
end
end,
})
return compLib