A script can use this to easily get runtime updates. (Even if script-opts is sort of clunky.)
Showing the changes to player/lua/options.lua (1 of 2 files). Show all
Unified · Split
| @@ -29,8 +29,17 @@ local function typeconv(desttypeval, val) · 28 unmodified lines | ||
| 29 | 29 | return val |
| 30 | 30 | end |
| 31 | 31 | |
| 32 | +-- performs a deep-copy of the given option value | |
| 33 | +local function opt_copy(val) | |
| 34 | + return val -- no tables currently | |
| 35 | +end | |
| 36 | + | |
| 37 | +-- compares the given option values for equality | |
| 38 | +local function opt_equal(val1, val2) | |
| 39 | + return val1 == val2 | |
| 40 | +end | |
| 32 | 41 | |
| 33 | −local function read_options(options, identifier) | |
| 42 | +local function read_options(options, identifier, on_update) | |
| 34 | 43 | if identifier == nil then |
| 35 | 44 | identifier = mp.get_script_name() |
| 36 | 45 | end |
| @@ -88,24 +97,62 @@ local function read_options(options, identifier) · 51 unmodified lines | ||
| 88 | 97 | end |
| 89 | 98 | |
| 90 | 99 | --parse command-line options |
| 91 | − for key, val in pairs(mp.get_property_native("options/script-opts")) do | |
| 92 | − local prefix = identifier.."-" | |
| 93 | − if not (string.find(key, prefix, 1, true) == nil) then | |
| 94 | − key = string.sub(key, string.len(prefix)+1) | |
| 95 | − | |
| 96 | − -- match found values with defaults | |
| 97 | − if options[key] == nil then | |
| 98 | − msg.warn("script-opts: unknown key " .. key .. ", ignoring") | |
| 99 | − else | |
| 100 | − local convval = typeconv(options[key], val) | |
| 101 | − if convval == nil then | |
| 102 | − msg.error("script-opts: error converting value '" .. val .. | |
| 103 | − "' for key '" .. key .. "'") | |
| 100 | + local prefix = identifier.."-" | |
| 101 | + | |
| 102 | + local option_types = {} | |
| 103 | + for key, value in pairs(options) do | |
| 104 | + option_types[key] = opt_copy(value) | |
| 105 | + end | |
| 106 | + | |
| 107 | + local function parse_opts(full, options) | |
| 108 | + local changelist = {} | |
| 109 | + for key, val in pairs(full) do | |
| 110 | + if not (string.find(key, prefix, 1, true) == nil) then | |
| 111 | + key = string.sub(key, string.len(prefix)+1) | |
| 112 | + | |
| 113 | + -- match found values with defaults | |
| 114 | + if option_types[key] == nil then | |
| 115 | + msg.warn("script-opts: unknown key " .. key .. ", ignoring") | |
| 104 | 116 | else |
| 105 | − options[key] = convval | |
| 117 | + 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 | 127 | end |
| 107 | 128 | end |
| 108 | 129 | 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 | 156 | end |
| 110 | 157 | |
| 111 | 158 | end |