summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-12-22 12:30:53 +0100
committerwm4 <wm4@nowhere>2019-12-22 12:30:53 +0100
commit00af718a9e47a6c7a48f821a93f788c22bdd41a7 (patch)
treea6dd9c46ccb087484d16f75e07c71277d59ed71e
parent9e15e3ad8f5829e86b3a17e4f2de28b62989b756 (diff)
downloadmpv-00af718a9e47a6c7a48f821a93f788c22bdd41a7.tar.bz2
mpv-00af718a9e47a6c7a48f821a93f788c22bdd41a7.tar.xz
lua: change runtime option change behavior
As described in the manpage changes. This makes more sense than the previous approach, where options could "unexpectedly" stick. Although this is still a somewhat arbitrary policy (ask many people and you'd get a number of different expectations on what should happen), I think that it reflects what mpv's builtin stuff does. All the copying is annoying, but let's just hope nobody is stupid enough to change these properties per video frame or something equally ridiculous.
-rw-r--r--DOCS/man/lua.rst6
-rw-r--r--player/lua/options.lua51
2 files changed, 33 insertions, 24 deletions
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst
index 6c6904c8b3..d98edf38a9 100644
--- a/DOCS/man/lua.rst
+++ b/DOCS/man/lua.rst
@@ -581,6 +581,12 @@ with values found in the config-file and the command-line (in that order).
the function) are changed, and ``on_update(list)`` is called. ``list`` is
a table where each updated option has a ``list[option_name] = true`` entry.
There is no initial ``on_update()`` call. This never re-reads the config file.
+ ``script-opts`` is always applied on the original config file, ignoring
+ previous ``script-opts`` values (for example, if an option is removed from
+ ``script-opts`` at runtime, the option will have the value in the config
+ file). ``table`` entries are only written for option values whose values
+ effectively change (this is important if the script changes ``table``
+ entries independently).
Example implementation::
diff --git a/player/lua/options.lua b/player/lua/options.lua
index 3a05c08ea8..31580f8320 100644
--- a/player/lua/options.lua
+++ b/player/lua/options.lua
@@ -39,7 +39,18 @@ local function opt_equal(val1, val2)
return val1 == val2
end
+-- 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
+
+
local function read_options(options, identifier, on_update)
+ local option_types = opt_table_copy(options)
if identifier == nil then
identifier = mp.get_script_name()
end
@@ -76,11 +87,11 @@ local function read_options(options, identifier, on_update)
local val = string.sub(line, eqpos+1)
-- match found values with defaults
- if options[key] == nil then
+ if option_types[key] == nil then
msg.warn(conffilename..":"..linecounter..
" unknown key " .. key .. ", ignoring")
else
- local convval = typeconv(options[key], val)
+ local convval = typeconv(option_types[key], val)
if convval == nil then
msg.error(conffilename..":"..linecounter..
" error converting value '" .. val ..
@@ -98,14 +109,10 @@ local function read_options(options, identifier, on_update)
--parse command-line options
local prefix = identifier.."-"
-
- local option_types = {}
- for key, value in pairs(options) do
- option_types[key] = opt_copy(value)
- end
+ -- command line options are always applied on top of these
+ local conf_and_default_opts = opt_table_copy(options)
local function parse_opts(full, options)
- local changelist = {}
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)
@@ -119,15 +126,11 @@ local function read_options(options, identifier, on_update)
msg.error("script-opts: error converting value '" .. val ..
"' for key '" .. key .. "'")
else
- if not opt_equal(options[key], convval) then
- changelist[key] = true
- options[key] = convval
- end
+ options[key] = convval
end
end
end
end
- return changelist
end
--initial
@@ -135,20 +138,20 @@ local function read_options(options, identifier, on_update)
--runtime updates
if on_update then
- -- Current option state, so that we can detect changes, even if the
- -- caller messes with the options table.
- local cur_opts = {}
-
- for key, value in pairs(options) do
- cur_opts[key] = opt_copy(value)
- end
+ local last_opts = opt_table_copy(options)
mp.observe_property("options/script-opts", "native", function(name, val)
- local changelist = parse_opts(val, cur_opts)
- for key, _ in pairs(changelist) do
- -- copy to user
- options[key] = opt_copy(cur_opts[key])
+ 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
end
+ last_opts = new_opts
if #changelist then
on_update(changelist)
end