History

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.)

wm4 committed 6 years ago

Commit 478a3211 parent db1e28f2 files · +71 −17Browse files

Unified · Split

2 files
  1. DOCS/man/lua.rst +9 −2
  2. player/lua/options.lua +62 −15
DOCS/man/lua.rst+9−2
@@ -566,14 +566,21 @@ command-line. All you have to do is to supply a table with default options to · 565 unmodified lines
566the read_options function. The function will overwrite the default values566the read_options function. The function will overwrite the default values
567with values found in the config-file and the command-line (in that order).567with values found in the config-file and the command-line (in that order).
568 568
569``options.read_options(table [, identifier])``569``options.read_options(table [, identifier [, on_update]])``
570 A ``table`` with key-value pairs. The type of the default values is570 A ``table`` with key-value pairs. The type of the default values is
571 important for converting the values read from the config file or571 important for converting the values read from the config file or
572 command-line back. Do not use ``nil`` as a default value!572 command-line back. Do not use ``nil`` as a default value!
573 573
574 The ``identifier`` is used to identify the config-file and the command-line574 The ``identifier`` is used to identify the config-file and the command-line
575 options. These needs to unique to avoid collisions with other scripts.575 options. These needs to unique to avoid collisions with other scripts.
576 Defaults to ``mp.get_script_name()``.576 Defaults to ``mp.get_script_name()`` if the parameter is ``nil`` or missing.
577
578 The ``on_update`` parameter enables run-time updates of all matching option
579 values via the ``script-opts`` option/property. If any of the matching
580 options changes, the values in the ``table`` (which was originally passed to
581 the function) are changed, and ``on_update(list)`` is called. ``list`` is
582 a table where each updated option has a ``list[option_name] = true`` entry.
583 There is no initial ``on_update()`` call. This never re-reads the config file.
577 584
578 585
579Example implementation::586Example implementation::
player/lua/options.lua+62−15
@@ -29,8 +29,17 @@ local function typeconv(desttypeval, val) · 28 unmodified lines
29 return val29 return val
30end30end
31 31
32-- performs a deep-copy of the given option value
33local function opt_copy(val)
34 return val -- no tables currently
35end
36
37-- compares the given option values for equality
38local function opt_equal(val1, val2)
39 return val1 == val2
40end
32 41
33local function read_options(options, identifier)42local function read_options(options, identifier, on_update)
34 if identifier == nil then43 if identifier == nil then
35 identifier = mp.get_script_name()44 identifier = mp.get_script_name()
36 end45 end
@@ -88,24 +97,62 @@ local function read_options(options, identifier) · 51 unmodified lines
88 end97 end
89 98
90 --parse command-line options99 --parse command-line options
91 for key, val in pairs(mp.get_property_native("options/script-opts")) do100 local prefix = identifier.."-"
92 local prefix = identifier.."-"101
93 if not (string.find(key, prefix, 1, true) == nil) then102 local option_types = {}
94 key = string.sub(key, string.len(prefix)+1)103 for key, value in pairs(options) do
95 104 option_types[key] = opt_copy(value)
96 -- match found values with defaults105 end
97 if options[key] == nil then106
98 msg.warn("script-opts: unknown key " .. key .. ", ignoring")107 local function parse_opts(full, options)
99 else108 local changelist = {}
100 local convval = typeconv(options[key], val)109 for key, val in pairs(full) do
101 if convval == nil then110 if not (string.find(key, prefix, 1, true) == nil) then
102 msg.error("script-opts: error converting value '" .. val ..111 key = string.sub(key, string.len(prefix)+1)
103 "' for key '" .. key .. "'")112
113 -- match found values with defaults
114 if option_types[key] == nil then
115 msg.warn("script-opts: unknown key " .. key .. ", ignoring")
104 else116 else
105 options[key] = convval117 local convval = typeconv(option_types[key], val)
118 if convval == nil then
119 msg.error("script-opts: error converting value '" .. val ..
120 "' for key '" .. key .. "'")
121 else
122 if not opt_equal(options[key], convval) then
123 changelist[key] = true
124 options[key] = convval
125 end
126 end
106 end127 end
107 end128 end
108 end129 end
130 return changelist
131 end
132
133 --initial
134 parse_opts(mp.get_property_native("options/script-opts"), options)
135
136 --runtime updates
137 if on_update then
138 -- Current option state, so that we can detect changes, even if the
139 -- caller messes with the options table.
140 local cur_opts = {}
141
142 for key, value in pairs(options) do
143 cur_opts[key] = opt_copy(value)
144 end
145
146 mp.observe_property("options/script-opts", "native", function(name, val)
147 local changelist = parse_opts(val, cur_opts)
148 for key, _ in pairs(changelist) do
149 -- copy to user
150 options[key] = opt_copy(cur_opts[key])
151 end
152 if #changelist then
153 on_update(changelist)
154 end
155 end)
109 end156 end
110 157
111end158end

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t