summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-12-20 14:21:16 +0100
committerwm4 <wm4@nowhere>2019-12-20 14:21:16 +0100
commit478a321dcc62345a09acfd34740dc6d0783ade88 (patch)
treef4dfe2c02d4692df6d9da0466c22bb6a9bf9e817
parentdb1e28f175f94ea44d226f061d81098a2c2cb8ba (diff)
downloadmpv-478a321dcc62345a09acfd34740dc6d0783ade88.tar.bz2
mpv-478a321dcc62345a09acfd34740dc6d0783ade88.tar.xz
lua: add a helper for runtime script option changes
A script can use this to easily get runtime updates. (Even if script-opts is sort of clunky.)
-rw-r--r--DOCS/man/lua.rst11
-rw-r--r--player/lua/options.lua77
2 files changed, 71 insertions, 17 deletions
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst
index 45fbfd62d0..6c6904c8b3 100644
--- a/DOCS/man/lua.rst
+++ b/DOCS/man/lua.rst
@@ -566,14 +566,21 @@ command-line. All you have to do is to supply a table with default options to
the read_options function. The function will overwrite the default values
with values found in the config-file and the command-line (in that order).
-``options.read_options(table [, identifier])``
+``options.read_options(table [, identifier [, on_update]])``
A ``table`` with key-value pairs. The type of the default values is
important for converting the values read from the config file or
command-line back. Do not use ``nil`` as a default value!
The ``identifier`` is used to identify the config-file and the command-line
options. These needs to unique to avoid collisions with other scripts.
- Defaults to ``mp.get_script_name()``.
+ Defaults to ``mp.get_script_name()`` if the parameter is ``nil`` or missing.
+
+ The ``on_update`` parameter enables run-time updates of all matching option
+ values via the ``script-opts`` option/property. If any of the matching
+ options changes, the values in the ``table`` (which was originally passed to
+ 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.
Example implementation::
diff --git a/player/lua/options.lua b/player/lua/options.lua
index a23417ae7d..3a05c08ea8 100644
--- a/player/lua/options.lua
+++ b/player/lua/options.lua
@@ -29,8 +29,17 @@ local function typeconv(desttypeval, val)
return val
end
+-- 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
-local function read_options(options, identifier)
+local function read_options(options, identifier, on_update)
if identifier == nil then
identifier = mp.get_script_name()
end
@@ -88,24 +97,62 @@ local function read_options(options, identifier)
end
--parse command-line options
- for key, val in pairs(mp.get_property_native("options/script-opts")) do
- local prefix = identifier.."-"
- if not (string.find(key, prefix, 1, true) == nil) then
- key = string.sub(key, string.len(prefix)+1)
-
- -- match found values with defaults
- if options[key] == nil then
- msg.warn("script-opts: unknown key " .. key .. ", ignoring")
- else
- local convval = typeconv(options[key], val)
- if convval == nil then
- msg.error("script-opts: error converting value '" .. val ..
- "' for key '" .. key .. "'")
+ local prefix = identifier.."-"
+
+ local option_types = {}
+ for key, value in pairs(options) do
+ option_types[key] = opt_copy(value)
+ end
+
+ 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)
+
+ -- match found values with defaults
+ if option_types[key] == nil then
+ msg.warn("script-opts: unknown key " .. key .. ", ignoring")
else
- options[key] = convval
+ local convval = typeconv(option_types[key], val)
+ if convval == nil then
+ 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
+ end
end
end
end
+ return changelist
+ end
+
+ --initial
+ parse_opts(mp.get_property_native("options/script-opts"), options)
+
+ --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
+
+ 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])
+ end
+ if #changelist then
+ on_update(changelist)
+ end
+ end)
end
end