Configuration update

Centralize all of the configuration settings and defaults into one file
Move the available components into the configuration
Move the verbose debugging into the configuration

Also start work on a modem component

Also fix configuration not saving on computer shutdown
This commit is contained in:
gamax92 2015-06-25 20:45:08 -06:00
parent 95405445d9
commit dd2daa2554
8 changed files with 219 additions and 64 deletions

View File

@ -17,9 +17,11 @@ local doclist = {}
component = {} component = {}
function component.connect(...) function component.connect(info, ...)
local address local address
local info = table.pack(...) if type(info) ~= "table" then
info = table.pack(info, ...)
end
checkArg(2,info[2],"string","number") checkArg(2,info[2],"string","number")
if type(info[2]) == "string" then if type(info[2]) == "string" then
address = info[2] address = info[2]
@ -109,10 +111,10 @@ function component.cecinvoke(address, method, ...)
end end
-- Load components -- Load components
local components = conf.components local components = settings.components
for k,v in pairs(components) do for k,v in pairs(components) do
v[2] = v[2] or k v[2] = v[2] or k
component.connect(table.unpack(v)) component.connect(v)
end end
env.component = {list = component.list} env.component = {list = component.list}

View File

@ -35,12 +35,12 @@ end
function env.computer.freeMemory() function env.computer.freeMemory()
--STUB --STUB
cprint("computer.freeMemory") cprint("computer.freeMemory")
return 10000 return machine.totalMemory
end end
function env.computer.totalMemory() function env.computer.totalMemory()
--STUB --STUB
cprint("computer.totalMemory") cprint("computer.totalMemory")
return 10000 return machine.totalMemory
end end
function env.computer.pushSignal(name, ...) function env.computer.pushSignal(name, ...)
cprint("computer.pushSignal", name, ...) cprint("computer.pushSignal", name, ...)
@ -73,6 +73,7 @@ function env.computer.energy()
return math.huge return math.huge
end end
function env.computer.maxEnergy() function env.computer.maxEnergy()
-- TODO: What is this ...
cprint("computer.maxEnergy") cprint("computer.maxEnergy")
return config.get("power.buffer.computer",500) return 1500
end end

View File

@ -4,9 +4,9 @@ env.system = {}
function env.system.allowBytecode() function env.system.allowBytecode()
cprint("system.allowBytecode") cprint("system.allowBytecode")
return config.get("computer.lua.allowBytecode",false) return settings.allowBytecode
end end
function env.system.timeout() function env.system.timeout()
cprint("system.timeout") cprint("system.timeout")
return config.get("computer.timeout",5) return settings.timeout
end end

View File

@ -38,18 +38,18 @@ end
function obj.isTcpEnabled() -- Returns whether TCP connections can be made (config setting). function obj.isTcpEnabled() -- Returns whether TCP connections can be made (config setting).
cprint("internet.isTcpEnabled") cprint("internet.isTcpEnabled")
return config.get("internet.enableTcp",true) return settings.tcpEnabled
end end
function obj.isHttpEnabled() -- Returns whether HTTP requests can be made (config setting). function obj.isHttpEnabled() -- Returns whether HTTP requests can be made (config setting).
cprint("internet.isHttpEnabled") cprint("internet.isHttpEnabled")
return config.get("internet.enableHttp",true) return settings.httpEnabled
end end
function obj.connect(address, port) -- Opens a new TCP connection. Returns the handle of the connection. function obj.connect(address, port) -- Opens a new TCP connection. Returns the handle of the connection.
cprint("internet.connect",address, port) cprint("internet.connect",address, port)
if port == nil then port = -1 end if port == nil then port = -1 end
compCheckArg(1,address,"string") compCheckArg(1,address,"string")
compCheckArg(2,port,"number") compCheckArg(2,port,"number")
if not config.get("internet.enableTcp",true) then if not settings.tcpEnabled then
return nil, "tcp connections are unavailable" return nil, "tcp connections are unavailable"
end end
-- TODO Check for too many connections -- TODO Check for too many connections
@ -120,7 +120,7 @@ end
function obj.request(url, postData) -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals. function obj.request(url, postData) -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.
cprint("internet.request",url, postData) cprint("internet.request",url, postData)
compCheckArg(1,url,"string") compCheckArg(1,url,"string")
if not config.get("internet.enableHttp",true) then if not settings.httpEnabled then
return nil, "http requests are unavailable" return nil, "http requests are unavailable"
end end
-- TODO: Check for too many connections -- TODO: Check for too many connections

107
src/component/modem.lua Normal file
View File

@ -0,0 +1,107 @@
local address, _, wireless = ...
compCheckArg(1,wireless,"boolean")
local wakeMessage
local strength
if wireless then
strength = settings.maxWirelessRange
end
local function checkPort(port)
if port < 1 and port >= 65536 then
error("invalid port number",4)
end
return math.floor(port)
end
-- modem component
local obj = {}
function obj.send(address, port, ...) -- Sends the specified data to the specified target.
--STUB
cprint("modem.send",address, port, ...)
compCheckArg(1,address,"string")
compCheckArg(2,port,"number")
port=checkPort(port)
return true
end
function obj.getWakeMessage() -- Get the current wake-up message.
--STUB
cprint("modem.getWakeMessage")
return wakeMessage
end
function obj.setWakeMessage(message) -- Set the wake-up message.
--STUB
cprint("modem.setWakeMessage",message)
compCheckArg(1,message,"string","nil")
wakeMessage = message
end
function obj.close(port) -- Closes the specified port (default: all ports). Returns true if ports were closed.
--STUB
cprint("modem.close",port)
compCheckArg(1,port,"number","nil")
if port ~= nil then
port=checkPort(port)
end
return false
end
function obj.maxPacketSize() -- Gets the maximum packet size (config setting).
cprint("modem.maxPacketSize")
return settings.maxNetworkPacketSize
end
if wireless then
function obj.getStrength() -- Get the signal strength (range) used when sending messages.
--STUB
cprint("modem.getStrength")
return strength
end
function obj.setStrength(newstrength) -- Set the signal strength (range) used when sending messages.
--STUB
cprint("modem.setStrength",newstrength)
compCheckArg(1,newstrength,"number")
strength = newstrength
end
end
function obj.isOpen(port) -- Whether the specified port is open.
--STUB
cprint("modem.isOpen",port)
compCheckArg(1,port,"number")
return false
end
function obj.open(port) -- Opens the specified port. Returns true if the port was opened.
--STUB
cprint("modem.open",port)
compCheckArg(1,port,"number")
port=checkPort(port)
return false
end
function obj.isWireless() -- Whether this is a wireless network card.
--STUB
cprint("modem.isWireless")
return wireless
end
function obj.broadcast(port, ...) -- Broadcasts the specified data on the specified port.
--STUB
cprint("modem.broadcast",port, ...)
compCheckArg(1,port,"number")
port=checkPort(port)
return true
end
local cec = {}
local doc = {
["send"]="function(address:string, port:number, data...) -- Sends the specified data to the specified target.",
["getWakeMessage"]="function():string -- Get the current wake-up message.",
["setWakeMessage"]="function(message:string):string -- Set the wake-up message.",
["close"]="function([port:number]):boolean -- Closes the specified port (default: all ports). Returns true if ports were closed.",
["maxPacketSize"]="function():number -- Gets the maximum packet size (config setting).",
["getStrength"]="function():number -- Get the signal strength (range) used when sending messages.",
["setStrength"]="function(strength:number):number -- Set the signal strength (range) used when sending messages.",
["isOpen"]="function(port:number):boolean -- Whether the specified port is open.",
["open"]="function(port:number):boolean -- Opens the specified port. Returns true if the port was opened.",
["isWireless"]="function():boolean -- Whether this is a wireless network card.",
["broadcast"]="function(port:number, data...) -- Broadcasts the specified data on the specified port.",
}
return obj,cec,doc

View File

@ -6,15 +6,21 @@ local comments = {
["computer.lua"]="Settings specific to the Lua architecture.", ["computer.lua"]="Settings specific to the Lua architecture.",
["computer.lua.allowBytecode"]="Whether to allow loading precompiled bytecode via Lua's `load` function, or related functions (`loadfile`, `dofile`). Enable this only if you absolutely trust all users on your server and all Lua code you run. This can be a MASSIVE SECURITY RISK, since precompiled code can easily be used for exploits, running arbitrary code on the real server! I cannot stress this enough: only enable this is you know what you're doing.", ["computer.lua.allowBytecode"]="Whether to allow loading precompiled bytecode via Lua's `load` function, or related functions (`loadfile`, `dofile`). Enable this only if you absolutely trust all users on your server and all Lua code you run. This can be a MASSIVE SECURITY RISK, since precompiled code can easily be used for exploits, running arbitrary code on the real server! I cannot stress this enough: only enable this is you know what you're doing.",
["computer.timeout"]="The time in seconds a program may run without yielding before it is forcibly aborted. This is used to avoid stupidly written or malicious programs blocking other computers by locking down the executor threads. Note that changing this won't have any effect on computers that are already running - they'll have to be rebooted for this to take effect.", ["computer.timeout"]="The time in seconds a program may run without yielding before it is forcibly aborted. This is used to avoid stupidly written or malicious programs blocking other computers by locking down the executor threads. Note that changing this won't have any effect on computers that are already running - they'll have to be rebooted for this to take effect.",
["emulator"]="Emulator related settings. Components, accuracy, and debugging.",
["emulator.components"]="Default components available to the computer.",
["emulator.debug"]="Whether to enable the emulator's extremely verbose logging.",
["internet.enableHttp"]="Whether to allow HTTP requests via internet cards. When enabled, the `request` method on internet card components becomes available.", ["internet.enableHttp"]="Whether to allow HTTP requests via internet cards. When enabled, the `request` method on internet card components becomes available.",
["internet.enableTcp"]="Whether to allow TCP connections via internet cards. When enabled, the `connect` method on internet card components becomes available.", ["internet.enableTcp"]="Whether to allow TCP connections via internet cards. When enabled, the `connect` method on internet card components becomes available.",
["misc"]="Other settings that you might find useful to tweak.",
["misc.maxNetworkPacketSize"]="The maximum size of network packets to allow sending via network cards. This has *nothing to do* with real network traffic, it's just a limit for the network cards, mostly to reduce the chance of computer with a lot of RAM killing those with less by sending huge packets. This does not apply to HTTP traffic.",
["misc.maxWirelessRange"]="The maximum distance a wireless message can be sent. In other words, this is the maximum signal strength a wireless network card supports. This is used to limit the search range in which to check for modems, which may or may not lead to performance issues for ridiculous ranges - like, you know, more than the loaded area. See also: `wirelessCostPerRange`.",
} }
local function writeComment(text,file,size) local function writeComment(text,file,size)
file:write(string.rep(" ",size) .. "--") file:write(string.rep(" ",size) .. "--")
local line = "" local line = ""
for word in text:gmatch("[%S]+") do for word in text:gmatch("[%S]+") do
if #line + #word + 1 > 78 then if #line + #word + 1 > 78-size then
line = "" line = ""
file:write("\n" .. string.rep(" ",size) .. "--") file:write("\n" .. string.rep(" ",size) .. "--")
end end
@ -40,10 +46,32 @@ function serialize(tbl,key,path,file,size)
if comments[spath] then if comments[spath] then
writeComment(comments[spath],file,size) writeComment(comments[spath],file,size)
end end
if type(v) == "table" then if spath == "emulator.components" then
file:write(string.rep(" ",size) .. k .. " {\n\n")
for i = 1,#v do
local comp = v[i]
file:write(string.rep(" ",size+2) .. "{")
for i = 1,#comp do
if type(comp[i]) == "string" then
file:write(string.format("%q",comp[i]))
else
file:write(tostring(comp[i]))
end
if i < #comp then
file:write(", ")
end
end
file:write("}")
if i < #v then
file:write(",")
end
file:write("\n")
end
file:write(string.rep(" ",size) .. "}\n")
elseif type(v) == "table" then
local list = true local list = true
for k,l in pairs(v) do for k,l in pairs(v) do
if type(l) ~= "number" then if type(k) ~= "number" or type(l) ~= "number" then
list = false list = false
break break
end end
@ -81,19 +109,19 @@ function config.load()
rawdata = (rawdata .. "\n"):reverse():match("\n+(.*)"):reverse() rawdata = (rawdata .. "\n"):reverse():match("\n+(.*)"):reverse()
local data = "" local data = ""
for line in (rawdata .. "\n"):gmatch("(.-)\n") do for line in (rawdata .. "\n"):gmatch("(.-)\n") do
if line:sub(-2) == " {" then if line:match("{%s-$") then
line = line:sub(1,-3) .. "={" line = line:gsub("{%s-$","={")
end end
if line:sub(-1) == "[" then if line:match("%[%s-$") then
line = line:sub(1,-2) .. "{" line = line:gsub("%[%s-$","{")
end end
if line:sub(-1) == "]" then if line:match("%]%s-$") then
line = line:sub(1,-2) .. "}" line = line:gsub("%]%s-$","}")
end end
if line ~= "" and line:sub(-1) ~= "{" and line:sub(-1) ~= "[" and line:sub(-1) ~= "," then if line:gsub("%s","") ~= "" and not line:match("{%s-$") and not line:match(",%s-$") then
line = line .. "," line = line .. ","
end end
if line == "ocemu={" then if line:match("ocemu%s-=%s-{") then
line = "return {" line = "return {"
end end
data = data .. line .. "\n" data = data .. line .. "\n"

View File

@ -7,45 +7,6 @@ function math.trunc(n)
return n < 0 and math.ceil(n) or math.floor(n) return n < 0 and math.ceil(n) or math.floor(n)
end end
-- load configuration
elsa.filesystem.load("config.lua")()
config.load()
elsa.cleanup = {}
function elsa.quit()
config.save()
for k,v in pairs(elsa.cleanup) do
v()
end
end
conf = {
-- Format: string:type, (string or number or nil):address, (number or nil):slot, component parameters
-- Read component files for parameter documentation
components = {
{"gpu",nil,0,160,50,3},
{"eeprom",nil,9,"lua/bios.lua"},
{"filesystem",nil,7,"loot/OpenOS",true},
{"filesystem",nil,nil,"tmpfs",false},
{"filesystem",nil,5,nil,false},
{"internet"},
{"computer"},
{"ocemu"},
}
}
if elsa.SDL then
table.insert(conf.components, {"screen_sdl2",nil,nil,80,25,3})
table.insert(conf.components, {"keyboard_sdl2"})
else
-- TODO: Alternatives
end
machine = {
starttime = elsa.timer.getTime(),
deadline = elsa.timer.getTime(),
signals = {},
}
local function check(have, want, ...) local function check(have, want, ...)
if not want then if not want then
return false return false
@ -70,7 +31,49 @@ function compCheckArg(n, have, ...)
end end
end end
if true then -- load configuration
elsa.filesystem.load("config.lua")()
config.load()
elsa.filesystem.load("settings.lua")()
elsa.cleanup = {}
function elsa.quit()
config.save()
for k,v in pairs(elsa.cleanup) do
v()
end
end
if settings.components == nil then
-- Format: string:type, (string or number or nil):address, (number or nil):slot, component parameters
-- Read component files for parameter documentation
settings.components = {
{"gpu",nil,0,160,50,3},
{"eeprom",nil,9,"lua/bios.lua"},
{"filesystem",nil,7,"loot/OpenOS",true},
{"filesystem",nil,nil,"tmpfs",false},
{"filesystem",nil,5,nil,false},
{"internet"},
{"computer"},
{"ocemu"},
}
if elsa.SDL then
table.insert(settings.components, {"screen_sdl2",nil,nil,80,25,3})
table.insert(settings.components, {"keyboard_sdl2"})
else
-- TODO: Alternatives
end
config.set("emulator.components",settings.components)
end
machine = {
starttime = elsa.timer.getTime(),
deadline = elsa.timer.getTime(),
signals = {},
totalMemory = 2*1024*1024,
}
if settings.emulatorDebug then
cprint = print cprint = print
else else
cprint = function() end cprint = function() end
@ -292,6 +295,7 @@ function resume_thread(...)
if results[2] then if results[2] then
boot_machine() boot_machine()
else else
elsa.quit()
error("Machine power off",0) error("Machine power off",0)
end end
end end

13
src/settings.lua Normal file
View File

@ -0,0 +1,13 @@
settings = {
allowBytecode = config.get("computer.lua.allowBytecode",false),
timeout = config.get("computer.timeout",5),
components = config.get("emulator.components"),
emulatorDebug = config.get("emulator.debug",true),
httpEnabled = config.get("internet.enableHttp",true),
tcpEnabled = config.get("internet.enableTcp",true),
maxNetworkPacketSize = config.get("misc.maxNetworkPacketSize",8192),
maxWirelessRange = config.get("misc.maxWirelessRange",400),
}