local PeripheralAPIFake = {} PeripheralAPIFake.__index = PeripheralAPIFake local expect = require("cc.expect").expect local function isPeripheral(peripheral) if type(peripheral) ~= "table" then return false end local meta = getmetatable(peripheral) if type(meta) ~= "table" then return false end if meta.__name ~= "peripheral" then return false end if type(meta.name) ~= "string" then return false end if type(meta.type) ~= "string" then return false end if type(meta.types) ~= "table" then return false end for _, ty in ipairs(meta.types) do if not meta.types[ty] then return false end end return true end -- TODO: Add descriptive error messages to asserts local function expectPeripheral(index, peripheral) if not isPeripheral(peripheral) then error(("bad argument #%d (table is not a peripheral)"):format(index), 3) end end --- Performs a deep clone of a table. local function cloneTable(t) local mt = getmetatable(t) setmetatable(t, nil) local cloned = {} for k, v in pairs(t) do if type(v) == "table" then cloned[k] = cloneTable(v) else cloned[k] = v end end setmetatable(t, mt) return cloned end local function doesTableContain(t, value) for _, v in pairs(t) do if v == value then return true end end return false end local function getPeripheralName(peripheral) return getmetatable(peripheral).name end local function getPeripheralTypes(peripheral) return getmetatable(peripheral).types end function PeripheralAPIFake.new(peripherals) expect(1, peripherals, "table", "nil") local self = setmetatable({}, PeripheralAPIFake) self.peripherals = {} if peripherals then for _, peripheral in ipairs(peripherals) do self:addPeripehral(peripheral) end end return self end function PeripheralAPIFake:newExternalAPI() local api = {} function api.call(name, method, ...) expect(1, name, "string") expect(2, method, "string") local peripheral = self.peripherals[name] if not peripheral then return end local func = peripheral[method] if type(func) ~= "function" then error(("No such method %s"):format(method), 2) end return func(...) end function api.find(ty, filter) expect(1, ty, "string") expect(2, filter, "function", "nil") local peripherals = {} for name, peripheral in pairs(self.peripherals) do local types = getPeripheralTypes(peripheral) if doesTableContain(types, ty) then local wrapped = api.wrap(name) if not filter or filter(name, wrapped) then table.insert(peripherals, wrapped) end end end return peripherals end function api.getMethods(name) expect(1, name, "string") local peripheral = self:getPeripheral(name) if not peripheral then return end local methods = {} for methodName, method in pairs(peripheral) do if type(method) == "function" then table.insert(methods, methodName) end end return methods end function api.getName(peripheral) expect(1, peripheral, "table", "string") expectPeripheral(1, peripheral) return getPeripheralName(peripheral) end function api.getNames() return self:listPeripherals() end function api.getType(peripheral) expect(1, peripheral, "table", "string") if type(peripheral) == "table" then expectPeripheral(1, peripheral) end local p = self:getPeripheral(peripheral) return table.unpack(getPeripheralTypes(p)) end function api.hasType(peripheral, peripheral_type) expect(1, peripheral, "table", "string") if type(peripheral) == "table" then expectPeripheral(1, peripheral) end expect(2, peripheral_type, "string") local p = self:getPeripheral(peripheral) if not p then return end local types = getPeripheralTypes(peripheral) return doesTableContain(types, peripheral_type) end function api.isPresent(name) expect(1, name, "string") return self:hasPeripheral(name) end function api.wrap(name) expect(1, name, "string") local peripheral = self.peripherals[name] if not peripheral then return end return cloneTable(peripheral) end return api end function PeripheralAPIFake:addPeripehral(peripheral) expect(1, peripheral, "table") expectPeripheral(1, peripheral) local name = getPeripheralName(peripheral) assert(not self.peripherals[name], "Expected peripheral name to be unique, it's not unique") assert(not self:hasPeripheral(peripheral), "Peripheral already added to system") self.peripherals[name] = peripheral end function PeripheralAPIFake:removePeripheral(peripheral) expect(1, peripheral, "table", "string") if type(peripheral) == "string" then self.peripherals[peripheral] = nil else expectPeripheral(1, peripheral) local name = getPeripheralName(peripheral) self.peripherals[name] = nil end end function PeripheralAPIFake:hasPeripheral(peripheral) expect(1, peripheral, "table", "string") return self:getPeripheral(peripheral) ~= nil end function PeripheralAPIFake:getPeripheral(peripheral) expect(1, peripheral, "table", "string") if type(peripheral) == "string" then return self.peripherals[peripheral] else expectPeripheral(1, peripheral) local name = getPeripheralName(peripheral) return self.peripherals[name] end end function PeripheralAPIFake:getPeripheralName(peripheral) return getPeripheralName(self:getPeripheral(peripheral)) end function PeripheralAPIFake:listPeripherals() local names = {} for _, peripheral in pairs(self.peripherals) do table.insert(names, getPeripheralName(peripheral)) end return names end return PeripheralAPIFake