diff options
author | wm4 <wm4@nowhere> | 2013-07-31 20:44:16 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-07-31 20:53:00 +0200 |
commit | 0656411e97afd5710b02563ee0b28423443592e9 (patch) | |
tree | 36375cff0a58d33e4c0b0ab788e878db334b4e13 | |
parent | 42f06fb915856722d2e263aa72d0acaf1e00271c (diff) | |
download | mpv-0656411e97afd5710b02563ee0b28423443592e9.tar.bz2 mpv-0656411e97afd5710b02563ee0b28423443592e9.tar.xz |
m_config: store file local backup options differently
File local options need to backup the global option value while a file
is played. Instead of keeping a pointer in m_config_option for the
backup value, put it into a separate list. This reduces per-option
overhead for a rarely used obscure feature. (This implementation would
have been a bit dumb in pre-mpv m_config, because there local options
were the default, and _all_ options were backed up when starting
playback of a file. This is not the case anymore, and normally only
a very small number of options are backed up by default.)
-rw-r--r-- | core/m_config.c | 43 | ||||
-rw-r--r-- | core/m_config.h | 4 |
2 files changed, 31 insertions, 16 deletions
diff --git a/core/m_config.c b/core/m_config.c index 414d397049..7faca24497 100644 --- a/core/m_config.c +++ b/core/m_config.c @@ -47,6 +47,13 @@ struct m_profile { char **opts; }; +// In the file local case, this contains the old global value. +struct m_opt_backup { + struct m_opt_backup *next; + struct m_config_option *co; + void *backup; +}; + static int parse_include(struct m_config *config, struct bstr param, bool set) { if (param.len == 0) @@ -175,14 +182,14 @@ static void add_options(struct m_config *config, static int config_destroy(void *p) { struct m_config *config = p; + if (config->file_local_mode) + m_config_leave_file_local(config); for (struct m_config_option *copt = config->opts; copt; copt = copt->next) { if (copt->alias_owner) continue; if (copt->opt->type->flags & M_OPT_TYPE_DYNAMIC) { m_option_free(copt->opt, copt->data); } - if (copt->global_backup) - m_option_free(copt->opt, copt->global_backup); } return 0; } @@ -246,18 +253,26 @@ int m_config_initialize_obj(struct m_config *config, struct m_obj_desc *desc, static void ensure_backup(struct m_config *config, struct m_config_option *co) { - while (co->alias_owner) - co = co->alias_owner; if (!config->file_local_mode) return; if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) return; if (co->opt->flags & M_OPT_GLOBAL) return; - if (co->global_backup) + if (!co->data) return; - co->global_backup = talloc_zero_size(co, co->opt->type->size); - m_option_copy(co->opt, co->global_backup, co->data); + for (struct m_opt_backup *cur = config->backup_opts; cur; cur = cur->next) { + if (cur->co->data == co->data) // comparing data ptr catches aliases + return; + } + struct m_opt_backup *bc = talloc_ptrtype(NULL, bc); + *bc = (struct m_opt_backup) { + .co = co, + .backup = talloc_zero_size(bc, co->opt->type->size), + }; + m_option_copy(co->opt, bc->backup, co->data); + bc->next = config->backup_opts; + config->backup_opts = bc; } void m_config_enter_file_local(struct m_config *config) @@ -274,13 +289,13 @@ void m_config_leave_file_local(struct m_config *config) { assert(config->file_local_mode); config->file_local_mode = false; - for (struct m_config_option *co = config->opts; co; co = co->next) { - if (co->global_backup) { - m_option_copy(co->opt, co->data, co->global_backup); - m_option_free(co->opt, co->global_backup); - talloc_free(co->global_backup); - co->global_backup = NULL; - } + while (config->backup_opts) { + struct m_opt_backup *bc = config->backup_opts; + config->backup_opts = bc->next; + + m_option_copy(bc->co->opt, bc->co->data, bc->backup); + m_option_free(bc->co->opt, bc->backup); + talloc_free(bc); } } diff --git a/core/m_config.h b/core/m_config.h index c48a4f1281..1ee7ecf1c0 100644 --- a/core/m_config.h +++ b/core/m_config.h @@ -44,8 +44,6 @@ struct m_config_option { const struct m_option *opt; // Raw value of the option. void *data; - // Raw value of the backup of the global value (or NULL). - void *global_backup; // If this is a suboption, the option that contains this option. struct m_config_option *parent; // If this option aliases another, more important option. The alias_owner @@ -70,6 +68,8 @@ typedef struct m_config { // Depth when recursively including profiles. int profile_depth; + struct m_opt_backup *backup_opts; + bool use_profiles; int (*includefunc)(struct m_config *conf, char *filename); |