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 | bool repeated : 1; | 114 | bool repeated : 1; |
| 115 | bool mouse_move : 1; | 115 | bool mouse_move : 1; |
| 116 | bool canceled : 1; | 116 | bool canceled : 1; |
| 117 | bool coalesce : 1; | ||
| 117 | int mouse_x, mouse_y; | 118 | int mouse_x, mouse_y; |
| 118 | struct mp_cmd *queue_next; | 119 | struct mp_cmd *queue_next; |
| 119 | double scale; // for scaling numeric arguments | 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 | param = bstr0("no"); | 737 | param = bstr0("no"); |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | if (flags & M_SETOPT_FROM_CONFIG_FILE) | ||
| 741 | co->coalesce = true; | ||
| 742 | |||
| 740 | // This is the only mandatory function | 743 | // This is the only mandatory function |
| 741 | mp_assert(co->opt->type->parse); | 744 | mp_assert(co->opt->type->parse); |
| 742 | 745 | ||
| @@ -49,6 +49,7 @@ struct m_config_option { · 48 unmodified lines | |||
| 49 | bool is_set_from_config : 1; // Set by a config file | 49 | bool is_set_from_config : 1; // Set by a config file |
| 50 | bool is_set_locally : 1; // Has a backup entry | 50 | bool is_set_locally : 1; // Has a backup entry |
| 51 | bool warning_was_printed : 1; | 51 | bool warning_was_printed : 1; |
| 52 | bool coalesce : 1; // Property changes should be coalesced | ||
| 52 | int32_t opt_id; // For some m_config APIs | 53 | int32_t opt_id; // For some m_config APIs |
| 53 | const char *name; // Full name (ie option-subopt) | 54 | const char *name; // Full name (ie option-subopt) |
| 54 | const struct m_option *opt; // Option description | 55 | const struct m_option *opt; // Option description |
| @@ -147,6 +147,8 @@ struct m_property { · 146 unmodified lines | |||
| 147 | void *priv; | 147 | void *priv; |
| 148 | // Special-case: mark options for which command.c uses the option-bridge | 148 | // Special-case: mark options for which command.c uses the option-bridge |
| 149 | bool is_option; | 149 | bool is_option; |
| 150 | // Special-case: option-bridge properties should be coalesced | ||
| 151 | bool coalesce; | ||
| 150 | }; | 152 | }; |
| 151 | 153 | ||
| 152 | struct m_property *m_property_list_find(const struct m_property *list, | 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 | m_option_copy(opt->opt, arg, opt->data); | 434 | m_option_copy(opt->opt, arg, opt->data); |
| 435 | return M_PROPERTY_OK; | 435 | return M_PROPERTY_OK; |
| 436 | case M_PROPERTY_SET: | 436 | case M_PROPERTY_SET: |
| 437 | opt->coalesce = prop->coalesce; | ||
| 437 | if (m_config_set_option_raw(mpctx->mconfig, opt, arg, 0) < 0) | 438 | if (m_config_set_option_raw(mpctx->mconfig, opt, arg, 0) < 0) |
| 438 | return M_PROPERTY_ERROR; | 439 | return M_PROPERTY_ERROR; |
| 439 | return M_PROPERTY_OK; | 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 | static void change_property_cmd(struct mp_cmd_ctx *cmd, | 5220 | static void change_property_cmd(struct mp_cmd_ctx *cmd, |
| 5220 | const char *name, int action, void *arg) | 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 | int r = mp_property_do(name, action, arg, cmd->mpctx); | 5230 | int r = mp_property_do(name, action, arg, cmd->mpctx); |
| 5223 | show_property_status(cmd, name, r); | 5231 | show_property_status(cmd, name, r); |
| 5232 | if (prop) | ||
| 5233 | prop->coalesce = false; | ||
| 5224 | } | 5234 | } |
| 5225 | 5235 | ||
| 5226 | static void cmd_cycle_values(void *p) | 5236 | static void cmd_cycle_values(void *p) |
| @@ -7657,6 +7667,7 @@ void run_command_opts(struct MPContext *mpctx) · 2430 unmodified lines | |||
| 7657 | for (int i = 0; opts->input_commands[i]; i++) { | 7667 | for (int i = 0; opts->input_commands[i]; i++) { |
| 7658 | struct mp_cmd *cmd = mp_input_parse_cmd(mpctx->input, bstr0(opts->input_commands[i]), | 7668 | struct mp_cmd *cmd = mp_input_parse_cmd(mpctx->input, bstr0(opts->input_commands[i]), |
| 7659 | "the command line"); | 7669 | "the command line"); |
| 7670 | cmd->coalesce = true; | ||
| 7660 | mp_input_queue_cmd(mpctx->input, cmd); | 7671 | mp_input_queue_cmd(mpctx->input, cmd); |
| 7661 | } | 7672 | } |
| 7662 | ctx->command_opts_processed = true; | 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 | if (self_update) | 7726 | if (self_update) |
| 7716 | return; | 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 | // Coalesce redundant updates and only keep the newest one. | 7736 | // Coalesce redundant updates and only keep the newest one. |
| 7719 | bool drop = false; | 7737 | bool drop = false; |
| 7720 | for (int i = 0; i < mpctx->num_option_callbacks; i++) { | 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 | struct MPOpts *opts = mpctx->opts; | 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 | void *opt_ptr = co ? co->data : NULL; | 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 | if (flags & UPDATE_TERM) | 7765 | if (flags & UPDATE_TERM) |
| 7748 | mp_update_logging(mpctx, false); | 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 | void mp_option_change_callback(void *ctx, struct m_config_option *co, uint64_t flags, | 88 | void mp_option_change_callback(void *ctx, struct m_config_option *co, uint64_t flags, |
| 89 | bool self_update); | 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 | void mp_notify(struct MPContext *mpctx, int event, void *arg); | 92 | void mp_notify(struct MPContext *mpctx, int event, void *arg); |
| 93 | void mp_notify_property(struct MPContext *mpctx, const char *property); | 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 | void handle_option_callbacks(struct MPContext *mpctx) | 125 | void handle_option_callbacks(struct MPContext *mpctx) |
| 126 | { | 126 | { |
| 127 | for (int i = 0; i < mpctx->num_option_callbacks; i++) | 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 | mpctx->num_option_callbacks = 0; | 129 | mpctx->num_option_callbacks = 0; |
| 130 | } | 130 | } |
| 131 | 131 | ||