mirror of
https://github.com/zenith391/OCEmu.git
synced 2025-10-17 19:11:18 -04:00

Add some more checks into component.connect Add component.disconnect Send signals component_added/removed when adding/removing components, except on boot Add some checks to eeprom component Add checks to filesystem component Add checks to gpu component Add checks to screen component Remove showWindow, causing issues in linux and doing nothing in windows Remove a useless renderchange calculation Fix internet.request for response codes 400 and above, oppm now works Add a ocemu component, which will be used to control the emulator from inside Add a basic configuration program, allowing to insert and delete components Add ocemu component to the list
176 lines
4.2 KiB
Lua
176 lines
4.2 KiB
Lua
local env = ...
|
|
|
|
local r = math.random
|
|
function gen_uuid()
|
|
return string.format("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
|
r(0,255),r(0,255),r(0,255),r(0,255),
|
|
r(0,255),r(0,255),
|
|
r(64,79),r(0,255),
|
|
r(128,191),r(0,255),
|
|
r(0,255),r(0,255),r(0,255),r(0,255),r(0,255),r(0,255))
|
|
end
|
|
|
|
local proxylist = {}
|
|
local slotlist = {}
|
|
local emuicc = {}
|
|
local doclist = {}
|
|
|
|
component = {}
|
|
|
|
function component.connect(...)
|
|
local address
|
|
local info = table.pack(...)
|
|
checkArg(2,info[2],"string","number")
|
|
if type(info[2]) == "string" then
|
|
address = info[2]
|
|
else
|
|
math.randomseed(info[2])
|
|
address = gen_uuid()
|
|
end
|
|
if proxylist[address] ~= nil then
|
|
return nil, "component already at address"
|
|
end
|
|
info[2] = address
|
|
local fn, err = elsa.filesystem.load("component/" .. info[1] .. ".lua")
|
|
if not fn then
|
|
return nil, err
|
|
end
|
|
local proxy, cec, doc = fn(table.unpack(info,2))
|
|
if not proxy then
|
|
return nil, cec or "no component added"
|
|
end
|
|
proxy.address = address
|
|
proxy.type = proxy.type or info[1]
|
|
proxylist[address] = proxy
|
|
emuicc[address] = cec
|
|
doclist[address] = doc
|
|
slotlist[address] = info[3]
|
|
if boot_machine then
|
|
table.insert(machine.signals,{"component_added",address,proxy.type})
|
|
end
|
|
return true
|
|
end
|
|
function component.disconnect(address)
|
|
checkArg(1,address,"string")
|
|
if proxylist[address] == nil then
|
|
return nil, "no component at address"
|
|
end
|
|
local thetype = proxylist[address].type
|
|
proxylist[address] = nil
|
|
emuicc[address] = nil
|
|
doclist[address] = nil
|
|
slotlist[address] = nil
|
|
table.insert(machine.signals,{"component_removed",address,thetype})
|
|
return true
|
|
end
|
|
function component.exists(address)
|
|
checkArg(1,address,"string")
|
|
if proxylist[address] ~= nil then
|
|
return proxylist[address].type
|
|
end
|
|
end
|
|
function component.list(filter, exact)
|
|
checkArg(1,filter,"string","nil")
|
|
local data = {}
|
|
local tbl = {}
|
|
for k,v in pairs(proxylist) do
|
|
if filter == nil or (exact and v.type == filter) or (not exact and v.type:find(filter, nil, true)) then
|
|
data[#data + 1] = k
|
|
data[#data + 1] = v.type
|
|
tbl[k] = v.type
|
|
end
|
|
end
|
|
local place = 1
|
|
return setmetatable(tbl,{__call = function()
|
|
local addr,type = data[place], data[place + 1]
|
|
place = place + 2
|
|
return addr,type
|
|
end})
|
|
end
|
|
function component.invoke(address, method, ...)
|
|
checkArg(1,address,"string")
|
|
checkArg(2,method,"string")
|
|
if proxylist[address] ~= nil then
|
|
if proxylist[address][method] == nil then
|
|
error("no such method",2)
|
|
end
|
|
return proxylist[address][method](...)
|
|
end
|
|
end
|
|
function component.cecinvoke(address, method, ...)
|
|
checkArg(1,address,"string")
|
|
checkArg(2,method,"string")
|
|
if emuicc[address] ~= nil then
|
|
if emuicc[address][method] == nil then
|
|
error("no such method",2)
|
|
end
|
|
return emuicc[address][method](...)
|
|
end
|
|
end
|
|
|
|
-- Load components
|
|
local components = conf.components
|
|
for k,v in pairs(components) do
|
|
v[2] = v[2] or k
|
|
component.connect(table.unpack(v))
|
|
end
|
|
|
|
env.component = {list = component.list}
|
|
|
|
function env.component.type(address)
|
|
checkArg(1,address,"string")
|
|
if proxylist[address] ~= nil then
|
|
return proxylist[address].type
|
|
end
|
|
return nil, "no such component"
|
|
end
|
|
|
|
function env.component.slot(address)
|
|
checkArg(1,address,"string")
|
|
if proxylist[address] ~= nil then
|
|
return slotlist[address] or -1
|
|
end
|
|
return nil, "no such component"
|
|
end
|
|
|
|
function env.component.methods(address)
|
|
checkArg(1,address,"string")
|
|
if proxylist[address] ~= nil then
|
|
local methods = {}
|
|
for k,v in pairs(proxylist[address]) do
|
|
if type(v) == "function" then
|
|
methods[k] = {direct=true} -- TODO: getter, setter?
|
|
end
|
|
end
|
|
return methods
|
|
end
|
|
return nil, "no such component"
|
|
end
|
|
|
|
function env.component.invoke(address, method, ...)
|
|
checkArg(1,address,"string")
|
|
checkArg(2,method,"string")
|
|
if proxylist[address] ~= nil then
|
|
if proxylist[address][method] == nil then
|
|
error("no such method",2)
|
|
end
|
|
return true, proxylist[address][method](...)
|
|
end
|
|
return nil, "no such component"
|
|
end
|
|
|
|
function env.component.doc(address, method)
|
|
checkArg(1,address,"string")
|
|
checkArg(2,method,"string")
|
|
if proxylist[address] ~= nil then
|
|
if proxylist[address][method] == nil then
|
|
return nil
|
|
end
|
|
if doclist[address] ~= nil then
|
|
return doclist[address][method]
|
|
end
|
|
return nil
|
|
end
|
|
return nil, "no such component"
|
|
end
|