diff --git a/DOCS/client-api-changes.rst b/DOCS/client-api-changes.rst index 2ccbc24e76..136e6a832e 100644 --- a/DOCS/client-api-changes.rst +++ b/DOCS/client-api-changes.rst @@ -36,6 +36,7 @@ API changes 1.108 - Deprecate MPV_EVENT_IDLE - add mpv_event_start_file, mpv_event_end_file.playlist_entry_id - add mpv_event_to_node() + - add mpv_client_id() 1.107 - Remove the deprecated qthelper.hpp. This was obviously not part of the libmpv API, only an "additionally" provided helper, thus this is not considered an API change. If you are maintaining a project that relies diff --git a/libmpv/client.h b/libmpv/client.h index 4fe8ea1866..4889e75f49 100644 --- a/libmpv/client.h +++ b/libmpv/client.h @@ -391,6 +391,24 @@ void mpv_free(void *data); */ const char *mpv_client_name(mpv_handle *ctx); +/** + * Return the ID of this client handle. Every client has its own unique ID. This + * ID is never reused by the core, even if the mpv_handle at hand gets destroyed + * and new handles get allocated. + * + * IDs are never 0 or negative. + * + * Some mpv APIs (not necessarily all) accept a name in the form "@" in + * addition of the proper mpv_client_name(), where "" is the ID in decimal + * form (e.g. "@123"). For example, the "script-message-to" command takes the + * client name as first argument, but also accepts the client ID formatted in + * this manner. + * + * @return The client name. The string is read-only and is valid until the + * mpv_handle is destroyed. + */ +int64_t mpv_client_id(mpv_handle *ctx); + /** * Create a new mpv instance and an associated client API handle to control * the mpv instance. This instance is in a pre-initialized state, diff --git a/libmpv/mpv.def b/libmpv/mpv.def index 6e20a668de..50a713531f 100644 --- a/libmpv/mpv.def +++ b/libmpv/mpv.def @@ -1,5 +1,6 @@ mpv_abort_async_command mpv_client_api_version +mpv_client_id mpv_client_name mpv_command mpv_command_async diff --git a/player/client.c b/player/client.c index 648ff1173c..41645b5d95 100644 --- a/player/client.c +++ b/player/client.c @@ -77,6 +77,7 @@ struct mp_client_api { // used to safely unlock mp_client_api.lock while iterating the list of // clients. uint64_t clients_list_change_ts; + int64_t id_alloc; struct mp_custom_protocol *custom_protocols; int num_custom_protocols; @@ -111,6 +112,7 @@ struct mpv_handle { struct mp_log *log; struct MPContext *mpctx; struct mp_client_api *clients; + int64_t id; // -- not thread-safe struct mpv_event *cur_event; @@ -223,13 +225,32 @@ bool mp_clients_all_initialized(struct MPContext *mpctx) return all_ok; } +static struct mpv_handle *find_client_id(struct mp_client_api *clients, int64_t id) +{ + for (int n = 0; n < clients->num_clients; n++) { + if (clients->clients[n]->id == id) + return clients->clients[n]; + } + return NULL; +} + static struct mpv_handle *find_client(struct mp_client_api *clients, const char *name) { + if (name[0] == '@') { + char *end; + errno = 0; + long long int id = strtoll(name + 1, &end, 10); + if (errno || end[0]) + return NULL; + return find_client_id(clients, id); + } + for (int n = 0; n < clients->num_clients; n++) { if (strcmp(clients->clients[n]->name, name) == 0) return clients->clients[n]; } + return NULL; } @@ -271,6 +292,7 @@ struct mpv_handle *mp_new_client(struct mp_client_api *clients, const char *name .log = mp_log_new(client, clients->mpctx->log, nname), .mpctx = clients->mpctx, .clients = clients, + .id = ++(clients->id_alloc), .cur_event = talloc_zero(client, struct mpv_event), .events = talloc_array(client, mpv_event, num_events), .max_events = num_events, @@ -308,6 +330,11 @@ const char *mpv_client_name(mpv_handle *ctx) return ctx->name; } +int64_t mpv_client_id(mpv_handle *ctx) +{ + return ctx->id; +} + struct mp_log *mp_client_get_log(struct mpv_handle *ctx) { return ctx->log;