1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 01:22:30 +00:00

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.)
This commit is contained in:
wm4 2019-12-20 14:21:16 +01:00
parent db1e28f175
commit 478a321dcc
2 changed files with 70 additions and 16 deletions

View File

@ -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::

View File

@ -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
local function read_options(options, identifier)
-- compares the given option values for equality
local function opt_equal(val1, val2)
return val1 == val2
end
local function read_options(options, identifier, on_update)
if identifier == nil then
identifier = mp.get_script_name()
end
@ -88,25 +97,63 @@ 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.."-"
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 options[key] == nil then
if option_types[key] == nil then
msg.warn("script-opts: unknown key " .. key .. ", ignoring")
else
local convval = typeconv(options[key], val)
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