diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index bcc7c0100d..3e449ba81b 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -1189,6 +1189,10 @@ Input Commands that are Possibly Subject to Change the script to finish initialization or not changed multiple times, and the future behavior is left undefined. + On success, returns a ``mpv_node`` with a ``client_id`` field set to the + return value of the ``mpv_client_id()`` API call of the newly created script + handle. + ``change-list `` This command changes list options as described in `List Options`_. The ```` parameter is the normal option name, while ```` is diff --git a/player/client.c b/player/client.c index a72cb0125f..d2a94cc0c9 100644 --- a/player/client.c +++ b/player/client.c @@ -254,14 +254,6 @@ static struct mpv_handle *find_client(struct mp_client_api *clients, return NULL; } -bool mp_client_exists(struct MPContext *mpctx, const char *client_name) -{ - pthread_mutex_lock(&mpctx->clients->lock); - bool r = find_client(mpctx->clients, client_name); - pthread_mutex_unlock(&mpctx->clients->lock); - return r; -} - bool mp_client_id_exists(struct MPContext *mpctx, int64_t id) { pthread_mutex_lock(&mpctx->clients->lock); diff --git a/player/client.h b/player/client.h index 47af084cc5..ddc568e975 100644 --- a/player/client.h +++ b/player/client.h @@ -23,7 +23,6 @@ void mp_shutdown_clients(struct MPContext *mpctx); bool mp_is_shutting_down(struct MPContext *mpctx); bool mp_clients_all_initialized(struct MPContext *mpctx); -bool mp_client_exists(struct MPContext *mpctx, const char *client_name); bool mp_client_id_exists(struct MPContext *mpctx, int64_t id); void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data); int mp_client_send_event(struct MPContext *mpctx, const char *client_name, diff --git a/player/command.c b/player/command.c index 3098e1d9bf..822a54c4a7 100644 --- a/player/command.c +++ b/player/command.c @@ -5538,8 +5538,14 @@ static void cmd_load_script(void *p) struct MPContext *mpctx = cmd->mpctx; char *script = cmd->args[0].v.s; - if (mp_load_user_script(mpctx, script) < 0) + int64_t id = mp_load_user_script(mpctx, script); + if (id > 0) { + struct mpv_node *res = &cmd->result; + node_init(res, MPV_FORMAT_NODE_MAP, NULL); + node_map_add_int64(res, "client_id", id); + } else { cmd->success = false; + } } static void cache_dump_poll(struct MPContext *mpctx) diff --git a/player/core.h b/player/core.h index 5161b07799..9472dfefd3 100644 --- a/player/core.h +++ b/player/core.h @@ -444,6 +444,8 @@ typedef struct MPContext { struct mp_ipc_ctx *ipc_ctx; + int64_t builtin_script_ids[4]; + pthread_mutex_t abort_lock; // --- The following fields are protected by abort_lock @@ -632,7 +634,7 @@ struct mp_scripting { }; bool mp_load_scripts(struct MPContext *mpctx); void mp_load_builtin_scripts(struct MPContext *mpctx); -int mp_load_user_script(struct MPContext *mpctx, const char *fname); +int64_t mp_load_user_script(struct MPContext *mpctx, const char *fname); // sub.c void reset_subtitle_state(struct MPContext *mpctx); diff --git a/player/scripting.c b/player/scripting.c index 81623cb518..840ff3e64a 100644 --- a/player/scripting.c +++ b/player/scripting.c @@ -105,7 +105,7 @@ static void *script_thread(void *p) return NULL; } -static int mp_load_script(struct MPContext *mpctx, const char *fname) +static int64_t mp_load_script(struct MPContext *mpctx, const char *fname) { char *ext = mp_splitext(fname, NULL); if (ext && strcasecmp(ext, "disable") == 0) @@ -183,6 +183,7 @@ static int mp_load_script(struct MPContext *mpctx, const char *fname) mp_client_set_weak(arg->client); arg->log = mp_client_get_log(arg->client); + int64_t id = mpv_client_id(arg->client); MP_DBG(arg, "Loading %s %s...\n", backend->name, fname); @@ -197,13 +198,13 @@ static int mp_load_script(struct MPContext *mpctx, const char *fname) } } - return 0; + return id; } -int mp_load_user_script(struct MPContext *mpctx, const char *fname) +int64_t mp_load_user_script(struct MPContext *mpctx, const char *fname) { char *path = mp_get_user_path(NULL, mpctx->global, fname); - int ret = mp_load_script(mpctx, path); + int64_t ret = mp_load_script(mpctx, path); talloc_free(path); return ret; } @@ -238,33 +239,29 @@ static char **list_script_files(void *talloc_ctx, char *path) return files; } -static void load_builtin_script(struct MPContext *mpctx, bool enable, +static void load_builtin_script(struct MPContext *mpctx, int slot, bool enable, const char *fname) { - void *tmp = talloc_new(NULL); - // (The name doesn't have to match if there were conflicts with other - // scripts, so this is on best-effort basis.) - char *name = script_name_from_filename(tmp, fname); - if (enable != mp_client_exists(mpctx, name)) { + assert(slot < MP_ARRAY_SIZE(mpctx->builtin_script_ids)); + int64_t *pid = &mpctx->builtin_script_ids[slot]; + if (*pid > 0 && !mp_client_id_exists(mpctx, *pid)) + *pid = 0; // died + if ((*pid > 0) != enable) { if (enable) { - mp_load_script(mpctx, fname); + *pid = mp_load_script(mpctx, fname); } else { - // Try to unload it by sending a shutdown event. This can be - // unreliable, because user scripts could have clashing names, or - // disabling and then quickly re-enabling a builtin script might - // detect the still-terminating script as loaded. + char *name = mp_tprintf(22, "@%"PRIi64, *pid); mp_client_send_event(mpctx, name, 0, MPV_EVENT_SHUTDOWN, NULL); } } - talloc_free(tmp); } void mp_load_builtin_scripts(struct MPContext *mpctx) { - load_builtin_script(mpctx, mpctx->opts->lua_load_osc, "@osc.lua"); - load_builtin_script(mpctx, mpctx->opts->lua_load_ytdl, "@ytdl_hook.lua"); - load_builtin_script(mpctx, mpctx->opts->lua_load_stats, "@stats.lua"); - load_builtin_script(mpctx, mpctx->opts->lua_load_console, "@console.lua"); + load_builtin_script(mpctx, 0, mpctx->opts->lua_load_osc, "@osc.lua"); + load_builtin_script(mpctx, 1, mpctx->opts->lua_load_ytdl, "@ytdl_hook.lua"); + load_builtin_script(mpctx, 2, mpctx->opts->lua_load_stats, "@stats.lua"); + load_builtin_script(mpctx, 3, mpctx->opts->lua_load_console, "@console.lua"); } bool mp_load_scripts(struct MPContext *mpctx)