summaryrefslogtreecommitdiffstats
path: root/options/m_config.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-11-28 21:19:41 +0100
committerwm4 <wm4@nowhere>2019-11-29 12:14:43 +0100
commit591494b271f17c4bfae0cfb860ae12bdad98a2ca (patch)
tree90278cadcea4fb2e79a7d05ce159784f36be5361 /options/m_config.h
parent1e6c57d4e437b403eab89d07ab61b872253b2c35 (diff)
downloadmpv-591494b271f17c4bfae0cfb860ae12bdad98a2ca.tar.bz2
mpv-591494b271f17c4bfae0cfb860ae12bdad98a2ca.tar.xz
m_config: add fine-grained option reporting mechanism
This adds m_config_cache_get_next_changed() and the change_flags field in m_config_cache. Both can be used to determine whether specific options changed (rather than the entire sub-group). Not sure if I'm very happy with that. The former rather compact update_options() is now a bit of a mess, because it needs to be incremental. m_config_cache_get_next_changed() will not be too nice to use, and change_flags still relies on global "allocation" of change flags (see UPDATE_* defines in m_option.h). If C weren't such a primitive language that smells like grandpa, it would be nice to define per-option change callbacks or so. This compares options by value to determine whether they have changed. This makes it slower in theory, but in practice it probably doesn't matter (options are rarely changed after initialization). The alternative would have been per-option change counters (wastes too much memory; not a practical problem but too ugly), or keep all m_config_caches in a global list and have bitmaps with per-option change bits (sounds complicated). I guess the current way is OK. Technically, this changes semantics slightly by ignoring setting an option to the same value. Technically this wasn't a no-op, although the effect was almost almost no-op. Some code would actually become cleaner by ignoring such redundant change events, and them being no-op is probably also what the user would normally assume.
Diffstat (limited to 'options/m_config.h')
-rw-r--r--options/m_config.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/options/m_config.h b/options/m_config.h
index 42734e8000..e2dcc0e51c 100644
--- a/options/m_config.h
+++ b/options/m_config.h
@@ -266,6 +266,14 @@ struct m_config_cache {
// The struct as indicated by m_config_cache_alloc's group parameter.
// (Internally the same as internal->gdata[0]->udata.)
void *opts;
+ // Accumulated change flags. The user can set this to 0 to unset all flags.
+ // They are set when calling any of the update functions. A flag is only set
+ // once the new value is visible in ->opts.
+ uint64_t change_flags;
+
+ // Set to non-NULL for logging all option changes as they are retrieved
+ // with one of the update functions (like m_config_cache_update()).
+ struct mp_log *debug;
// Do not access.
struct config_cache *internal;
@@ -277,6 +285,9 @@ struct m_config_cache {
// Keep in mind that a m_config_cache object is not thread-safe; it merely
// provides thread-safe access to the global options. All API functions for
// the same m_config_cache object must synchronized, unless otherwise noted.
+// This does not create an initial change event (m_config_cache_update() will
+// return false), but note that a change might be asynchronously signaled at any
+// time.
// ta_parent: parent for the returned allocation
// global: option data source
// group: the option group to return. This can be GLOBAL_CONFIG for the global
@@ -307,8 +318,26 @@ void m_config_cache_set_dispatch_change_cb(struct m_config_cache *cache,
// some options have changed).
// Keep in mind that while the cache->opts pointer does not change, the option
// data itself will (e.g. string options might be reallocated).
+// New change flags are or-ed into cache->change_flags with this call (if you
+// use them, you should probably do cache->change_flags=0 before this call).
bool m_config_cache_update(struct m_config_cache *cache);
+// Check for changes and return fine grained change information.
+// Warning: this conflicts with m_config_cache_update(). If you call
+// m_config_cache_update(), all options will be marked as "not changed",
+// and this function will return false. Also, calling this function and
+// then m_config_cache_update() is not supported, and may skip updating
+// some fields.
+// This returns true as long as there is a changed option, and false if all
+// changed options have been returned.
+// If multiple options have changed, the new option value is visible only once
+// this function has returned the change for it.
+// out_ptr: pointer to a void*, which is set to the cache->opts field associated
+// with the changed option if the function returns true; set to NULL
+// if no option changed.
+// returns: *out_ptr!=NULL (true if there was a changed option)
+bool m_config_cache_get_next_changed(struct m_config_cache *cache, void **out_ptr);
+
// Like m_config_cache_alloc(), but return the struct (m_config_cache->opts)
// directly, with no way to update the config. Basically this returns a copy
// with a snapshot of the current option values.