This relaxes what bbac628a1b01261766459c6556e36d2443a42534 introduced. Although it is rare, there may be scripts out there that depend on the old timing. We'd still like to process config files in a sane manner and not cause OOMs so keep the general coalescing mechanism in place but use it selectively. There is one special case with the --input-commands option. We want this coalesced as well so some special handling needs to be added for that.
Unified · Split
| @@ -114,6 +114,7 @@ typedef struct mp_cmd { · 113 unmodified lines | ||
| 114 | 114 | bool repeated : 1; |
| 115 | 115 | bool mouse_move : 1; |
| 116 | 116 | bool canceled : 1; |
| 117 | + bool coalesce : 1; | |
| 117 | 118 | int mouse_x, mouse_y; |
| 118 | 119 | struct mp_cmd *queue_next; |
| 119 | 120 | double scale; // for scaling numeric arguments |
| @@ -737,6 +737,9 @@ int m_config_set_option_cli(struct m_config *config, struct bstr name, · 736 unmodified lines | ||
| 737 | 737 | param = bstr0("no"); |
| 738 | 738 | } |
| 739 | 739 | |
| 740 | + if (flags & M_SETOPT_FROM_CONFIG_FILE) | |
| 741 | + co->coalesce = true; | |
| 742 | + | |
| 740 | 743 | // This is the only mandatory function |
| 741 | 744 | mp_assert(co->opt->type->parse); |
| 742 | 745 | |
| @@ -49,6 +49,7 @@ struct m_config_option { · 48 unmodified lines | ||
| 49 | 49 | bool is_set_from_config : 1; // Set by a config file |
| 50 | 50 | bool is_set_locally : 1; // Has a backup entry |
| 51 | 51 | bool warning_was_printed : 1; |
| 52 | + bool coalesce : 1; // Property changes should be coalesced | |
| 52 | 53 | int32_t opt_id; // For some m_config APIs |
| 53 | 54 | const char *name; // Full name (ie option-subopt) |
| 54 | 55 | const struct m_option *opt; // Option description |
| @@ -147,6 +147,8 @@ struct m_property { · 146 unmodified lines | ||
| 147 | 147 | void *priv; |
| 148 | 148 | // Special-case: mark options for which command.c uses the option-bridge |
| 149 | 149 | bool is_option; |
| 150 | + // Special-case: option-bridge properties should be coalesced | |
| 151 | + bool coalesce; | |
| 150 | 152 | }; |
| 151 | 153 | |
| 152 | 154 | struct m_property *m_property_list_find(const struct m_property *list, |
| @@ -434,6 +434,7 @@ static int mp_property_generic_option(void *ctx, struct m_property *prop, · 433 unmodified lines | ||
| 434 | 434 | m_option_copy(opt->opt, arg, opt->data); |
| 435 | 435 | return M_PROPERTY_OK; |
| 436 | 436 | case M_PROPERTY_SET: |
| 437 | + opt->coalesce = prop->coalesce; | |
| 437 | 438 | if (m_config_set_option_raw(mpctx->mconfig, opt, arg, 0) < 0) |
| 438 | 439 | return M_PROPERTY_ERROR; |
| 439 | 440 | return M_PROPERTY_OK; |
| @@ -5219,8 +5220,17 @@ static void show_property_status(struct mp_cmd_ctx *cmd, const char *name, int r · 4779 unmodified lines | ||
| 5219 | 5220 | static void change_property_cmd(struct mp_cmd_ctx *cmd, |
| 5220 | 5221 | const char *name, int action, void *arg) |
| 5221 | 5222 | { |
| 5223 | + struct m_property *prop = NULL; | |
| 5224 | + if (cmd->cmd->coalesce) { | |
| 5225 | + struct command_ctx *ctx = cmd->mpctx->command_ctx; | |
| 5226 | + prop = m_property_list_find(ctx->properties, name); | |
| 5227 | + if (prop) | |
| 5228 | + prop->coalesce = true; | |
| 5229 | + } | |
| 5222 | 5230 | int r = mp_property_do(name, action, arg, cmd->mpctx); |
| 5223 | 5231 | show_property_status(cmd, name, r); |
| 5232 | + if (prop) | |
| 5233 | + prop->coalesce = false; | |
| 5224 | 5234 | } |
| 5225 | 5235 | |
| 5226 | 5236 | static void cmd_cycle_values(void *p) |
| @@ -7657,6 +7667,7 @@ void run_command_opts(struct MPContext *mpctx) · 2430 unmodified lines | ||
| 7657 | 7667 | for (int i = 0; opts->input_commands[i]; i++) { |
| 7658 | 7668 | struct mp_cmd *cmd = mp_input_parse_cmd(mpctx->input, bstr0(opts->input_commands[i]), |
| 7659 | 7669 | "the command line"); |
| 7670 | + cmd->coalesce = true; | |
| 7660 | 7671 | mp_input_queue_cmd(mpctx->input, cmd); |
| 7661 | 7672 | } |
| 7662 | 7673 | ctx->command_opts_processed = true; |
| @@ -7715,6 +7726,13 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, uint64_t f · 52 unmodified lines | ||
| 7715 | 7726 | if (self_update) |
| 7716 | 7727 | return; |
| 7717 | 7728 | |
| 7729 | + // Run these immediately. | |
| 7730 | + if (co && !co->coalesce) { | |
| 7731 | + struct mp_option_callback callback = {.co = co, .flags = flags}; | |
| 7732 | + mp_option_run_callback(mpctx, &callback); | |
| 7733 | + return; | |
| 7734 | + } | |
| 7735 | + | |
| 7718 | 7736 | // Coalesce redundant updates and only keep the newest one. |
| 7719 | 7737 | bool drop = false; |
| 7720 | 7738 | for (int i = 0; i < mpctx->num_option_callbacks; i++) { |
| @@ -7737,12 +7755,12 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, uint64_t f · 16 unmodified lines | ||
| 7737 | 7755 | } |
| 7738 | 7756 | } |
| 7739 | 7757 | |
| 7740 | −void mp_option_run_callback(struct MPContext *mpctx, int index) | |
| 7758 | +void mp_option_run_callback(struct MPContext *mpctx, struct mp_option_callback *callback) | |
| 7741 | 7759 | { |
| 7742 | 7760 | struct MPOpts *opts = mpctx->opts; |
| 7743 | − struct m_config_option *co = mpctx->option_callbacks[index].co; | |
| 7761 | + struct m_config_option *co = callback->co; | |
| 7744 | 7762 | void *opt_ptr = co ? co->data : NULL; |
| 7745 | − uint64_t flags = mpctx->option_callbacks[index].flags; | |
| 7763 | + uint64_t flags = callback->flags; | |
| 7746 | 7764 | |
| 7747 | 7765 | if (flags & UPDATE_TERM) |
| 7748 | 7766 | mp_update_logging(mpctx, false); |
| @@ -87,7 +87,7 @@ int mp_property_do(const char* name, int action, void* val, · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | void mp_option_change_callback(void *ctx, struct m_config_option *co, uint64_t flags, |
| 89 | 89 | bool self_update); |
| 90 | −void mp_option_run_callback(struct MPContext *mpctx, int index); | |
| 90 | +void mp_option_run_callback(struct MPContext *mpctx, struct mp_option_callback *callback); | |
| 91 | 91 | |
| 92 | 92 | void mp_notify(struct MPContext *mpctx, int event, void *arg); |
| 93 | 93 | void mp_notify_property(struct MPContext *mpctx, const char *property); |
| @@ -125,7 +125,7 @@ static void mp_process_input(struct MPContext *mpctx) · 124 unmodified lines | ||
| 125 | 125 | void handle_option_callbacks(struct MPContext *mpctx) |
| 126 | 126 | { |
| 127 | 127 | for (int i = 0; i < mpctx->num_option_callbacks; i++) |
| 128 | − mp_option_run_callback(mpctx, i); | |
| 128 | + mp_option_run_callback(mpctx, &mpctx->option_callbacks[i]); | |
| 129 | 129 | mpctx->num_option_callbacks = 0; |
| 130 | 130 | } |
| 131 | 131 | |