2014-05-23 11:14:17 +00:00
|
|
|
local msg = require 'mp.msg'
|
|
|
|
|
|
|
|
local function val2str(val)
|
|
|
|
if type(val) == "boolean" then
|
|
|
|
if val then val = "yes" else val = "no" end
|
|
|
|
end
|
|
|
|
return val
|
|
|
|
end
|
|
|
|
|
|
|
|
-- converts val to type of desttypeval
|
|
|
|
local function typeconv(desttypeval, val)
|
|
|
|
if type(desttypeval) == "boolean" then
|
|
|
|
if val == "yes" then
|
|
|
|
val = true
|
|
|
|
elseif val == "no" then
|
|
|
|
val = false
|
|
|
|
else
|
2021-08-10 08:00:18 +00:00
|
|
|
msg.error("Error: Can't convert '" .. val .. "' to boolean!")
|
2014-05-23 11:14:17 +00:00
|
|
|
val = nil
|
|
|
|
end
|
|
|
|
elseif type(desttypeval) == "number" then
|
|
|
|
if not (tonumber(val) == nil) then
|
|
|
|
val = tonumber(val)
|
|
|
|
else
|
2021-08-10 08:00:18 +00:00
|
|
|
msg.error("Error: Can't convert '" .. val .. "' to number!")
|
2014-05-23 11:14:17 +00:00
|
|
|
val = nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return val
|
|
|
|
end
|
|
|
|
|
2019-12-20 13:21:16 +00:00
|
|
|
-- performs a deep-copy of the given option value
|
|
|
|
local function opt_copy(val)
|
|
|
|
return val -- no tables currently
|
|
|
|
end
|
|
|
|
|
|
|
|
-- compares the given option values for equality
|
|
|
|
local function opt_equal(val1, val2)
|
|
|
|
return val1 == val2
|
|
|
|
end
|
2014-05-23 11:14:17 +00:00
|
|
|
|
2019-12-22 11:30:53 +00:00
|
|
|
-- performs a deep-copy of an entire option table
|
|
|
|
local function opt_table_copy(opts)
|
|
|
|
local copy = {}
|
|
|
|
for key, value in pairs(opts) do
|
|
|
|
copy[key] = opt_copy(value)
|
|
|
|
end
|
|
|
|
return copy
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2019-12-20 13:21:16 +00:00
|
|
|
local function read_options(options, identifier, on_update)
|
2019-12-22 11:30:53 +00:00
|
|
|
local option_types = opt_table_copy(options)
|
2014-05-23 11:14:17 +00:00
|
|
|
if identifier == nil then
|
|
|
|
identifier = mp.get_script_name()
|
|
|
|
end
|
2014-09-16 15:19:22 +00:00
|
|
|
msg.debug("reading options for " .. identifier)
|
2014-05-23 11:14:17 +00:00
|
|
|
|
|
|
|
-- read config file
|
2017-12-13 17:37:42 +00:00
|
|
|
local conffilename = "script-opts/" .. identifier .. ".conf"
|
2014-05-23 11:14:17 +00:00
|
|
|
local conffile = mp.find_config_file(conffilename)
|
2017-12-13 17:37:42 +00:00
|
|
|
if conffile == nil then
|
2019-11-01 00:52:05 +00:00
|
|
|
msg.debug(conffilename .. " not found.")
|
2017-12-13 17:37:42 +00:00
|
|
|
conffilename = "lua-settings/" .. identifier .. ".conf"
|
|
|
|
conffile = mp.find_config_file(conffilename)
|
|
|
|
if conffile then
|
|
|
|
msg.warn("lua-settings/ is deprecated, use directory script-opts/")
|
|
|
|
end
|
|
|
|
end
|
2014-05-23 11:14:17 +00:00
|
|
|
local f = conffile and io.open(conffile,"r")
|
|
|
|
if f == nil then
|
|
|
|
-- config not found
|
2019-11-01 00:52:05 +00:00
|
|
|
msg.debug(conffilename .. " not found.")
|
2014-05-23 11:14:17 +00:00
|
|
|
else
|
|
|
|
-- config exists, read values
|
2019-11-01 00:52:05 +00:00
|
|
|
msg.verbose("Opened config file " .. conffilename .. ".")
|
2014-05-23 11:14:17 +00:00
|
|
|
local linecounter = 1
|
|
|
|
for line in f:lines() do
|
2020-05-27 13:01:39 +00:00
|
|
|
if line:sub(#line) == "\r" then
|
|
|
|
line = line:sub(1, #line - 1)
|
|
|
|
end
|
2014-05-23 11:14:17 +00:00
|
|
|
if string.find(line, "#") == 1 then
|
|
|
|
|
|
|
|
else
|
|
|
|
local eqpos = string.find(line, "=")
|
|
|
|
if eqpos == nil then
|
|
|
|
|
|
|
|
else
|
|
|
|
local key = string.sub(line, 1, eqpos-1)
|
|
|
|
local val = string.sub(line, eqpos+1)
|
|
|
|
|
|
|
|
-- match found values with defaults
|
2019-12-22 11:30:53 +00:00
|
|
|
if option_types[key] == nil then
|
2014-05-23 11:14:17 +00:00
|
|
|
msg.warn(conffilename..":"..linecounter..
|
2021-08-10 08:00:18 +00:00
|
|
|
" unknown key '" .. key .. "', ignoring")
|
2014-05-23 11:14:17 +00:00
|
|
|
else
|
2019-12-22 11:30:53 +00:00
|
|
|
local convval = typeconv(option_types[key], val)
|
2014-05-23 11:14:17 +00:00
|
|
|
if convval == nil then
|
|
|
|
msg.error(conffilename..":"..linecounter..
|
|
|
|
" error converting value '" .. val ..
|
|
|
|
"' for key '" .. key .. "'")
|
|
|
|
else
|
|
|
|
options[key] = convval
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
linecounter = linecounter + 1
|
|
|
|
end
|
|
|
|
io.close(f)
|
|
|
|
end
|
|
|
|
|
2014-05-23 11:24:27 +00:00
|
|
|
--parse command-line options
|
2019-12-20 13:21:16 +00:00
|
|
|
local prefix = identifier.."-"
|
2019-12-22 11:30:53 +00:00
|
|
|
-- command line options are always applied on top of these
|
|
|
|
local conf_and_default_opts = opt_table_copy(options)
|
2019-12-20 13:21:16 +00:00
|
|
|
|
|
|
|
local function parse_opts(full, options)
|
|
|
|
for key, val in pairs(full) do
|
|
|
|
if not (string.find(key, prefix, 1, true) == nil) then
|
|
|
|
key = string.sub(key, string.len(prefix)+1)
|
|
|
|
|
|
|
|
-- match found values with defaults
|
|
|
|
if option_types[key] == nil then
|
|
|
|
msg.warn("script-opts: unknown key " .. key .. ", ignoring")
|
2014-05-23 11:14:17 +00:00
|
|
|
else
|
2019-12-20 13:21:16 +00:00
|
|
|
local convval = typeconv(option_types[key], val)
|
|
|
|
if convval == nil then
|
|
|
|
msg.error("script-opts: error converting value '" .. val ..
|
|
|
|
"' for key '" .. key .. "'")
|
|
|
|
else
|
2019-12-22 11:30:53 +00:00
|
|
|
options[key] = convval
|
2019-12-20 13:21:16 +00:00
|
|
|
end
|
2014-05-23 11:14:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-12-20 13:21:16 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
--initial
|
|
|
|
parse_opts(mp.get_property_native("options/script-opts"), options)
|
|
|
|
|
|
|
|
--runtime updates
|
|
|
|
if on_update then
|
2019-12-22 11:30:53 +00:00
|
|
|
local last_opts = opt_table_copy(options)
|
2019-12-20 13:21:16 +00:00
|
|
|
|
|
|
|
mp.observe_property("options/script-opts", "native", function(name, val)
|
2019-12-22 11:30:53 +00:00
|
|
|
local new_opts = opt_table_copy(conf_and_default_opts)
|
|
|
|
parse_opts(val, new_opts)
|
|
|
|
local changelist = {}
|
|
|
|
for key, val in pairs(new_opts) do
|
|
|
|
if not opt_equal(last_opts[key], val) then
|
|
|
|
-- copy to user
|
|
|
|
options[key] = opt_copy(val)
|
|
|
|
changelist[key] = true
|
|
|
|
end
|
2019-12-20 13:21:16 +00:00
|
|
|
end
|
2019-12-22 11:30:53 +00:00
|
|
|
last_opts = new_opts
|
2020-01-27 14:07:02 +00:00
|
|
|
if next(changelist) ~= nil then
|
2019-12-20 13:21:16 +00:00
|
|
|
on_update(changelist)
|
|
|
|
end
|
|
|
|
end)
|
2014-05-23 11:14:17 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2015-05-29 13:50:09 +00:00
|
|
|
-- backwards compatibility with broken read_options export
|
|
|
|
_G.read_options = read_options
|
2014-05-23 11:14:17 +00:00
|
|
|
|
2015-05-29 13:50:09 +00:00
|
|
|
return {
|
|
|
|
read_options = read_options,
|
|
|
|
}
|