From f0678afba010cfd13418641036309b3724cb9f66 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 10 May 2018 14:33:10 +0200 Subject: [PATCH] client API: add returning of data from async commands This was not done sooner out of laziness. --- DOCS/client-api-changes.rst | 3 +++ libmpv/client.h | 27 ++++++++++++++++++++------- player/client.c | 15 ++++++++++----- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/DOCS/client-api-changes.rst b/DOCS/client-api-changes.rst index cb80d0a698..75484c390a 100644 --- a/DOCS/client-api-changes.rst +++ b/DOCS/client-api-changes.rst @@ -33,6 +33,9 @@ API changes :: --- mpv 0.29.0 --- + 1.102 - redo handling of async commands + - add mpv_event_command and make it possible to return values from + commands issued with mpv_command_async() or mpv_command_node_async() 1.101 - add MPV_RENDER_PARAM_ADVANCED_CONTROL and related API - add MPV_RENDER_PARAM_NEXT_FRAME_INFO and related symbols - add MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME diff --git a/libmpv/client.h b/libmpv/client.h index b276c54390..f9c9f3686b 100644 --- a/libmpv/client.h +++ b/libmpv/client.h @@ -223,7 +223,7 @@ extern "C" { * relational operators (<, >, <=, >=). */ #define MPV_MAKE_VERSION(major, minor) (((major) << 16) | (minor) | 0UL) -#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 101) +#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 102) /** * The API user is allowed to "#define MPV_ENABLE_DEPRECATED 0" before @@ -967,10 +967,11 @@ int mpv_command_string(mpv_handle *ctx, const char *args); * Same as mpv_command, but run the command asynchronously. * * Commands are executed asynchronously. You will receive a - * MPV_EVENT_COMMAND_REPLY event. (This event will also have an - * error code set if running the command failed.) + * MPV_EVENT_COMMAND_REPLY event. This event will also have an + * error code set if running the command failed. For commands that + * return data, the data is put into mpv_event_command.result. * - * * Safe to be called from mpv render API threads. + * Safe to be called from mpv render API threads. * * @param reply_userdata the value mpv_event.reply_userdata of the reply will * be set to (see section about asynchronous calls) @@ -985,8 +986,7 @@ int mpv_command_async(mpv_handle *ctx, uint64_t reply_userdata, * function is to mpv_command_node() what mpv_command_async() is to * mpv_command(). * - * See mpv_command_async() for details. Retrieving the result is not - * supported yet. + * See mpv_command_async() for details. * * Safe to be called from mpv render API threads. * @@ -1211,7 +1211,8 @@ typedef enum mpv_event_id { */ MPV_EVENT_SET_PROPERTY_REPLY = 4, /** - * Reply to a mpv_command_async() request. + * Reply to a mpv_command_async() or mpv_command_node_async() request. + * See also mpv_event and mpv_event_command. */ MPV_EVENT_COMMAND_REPLY = 5, /** @@ -1558,6 +1559,17 @@ typedef struct mpv_event_hook { uint64_t id; } mpv_event_hook; +// Since API version 1.102. +typedef struct mpv_event_command { + /** + * Result data of the command. Note that success/failure is signaled + * separately via mpv_event.error. This field is only for result data + * in case of success. Most commands leave it at MPV_FORMAT_NONE. Set + * to MPV_FORMAT_NONE on failure. + */ + mpv_node result; +} mpv_event_command; + typedef struct mpv_event { /** * One of mpv_event. Keep in mind that later ABI compatible releases might @@ -1595,6 +1607,7 @@ typedef struct mpv_event { * MPV_EVENT_CLIENT_MESSAGE: mpv_event_client_message* * MPV_EVENT_END_FILE: mpv_event_end_file* * MPV_EVENT_HOOK: mpv_event_hook* + * MPV_EVENT_COMMAND_REPLY* mpv_event_command* * other: NULL * * Note: future enhancements might add new event structs for existing or new diff --git a/player/client.c b/player/client.c index 21bb069413..e26ebbd5d9 100644 --- a/player/client.c +++ b/player/client.c @@ -1108,7 +1108,6 @@ int mpv_command_string(mpv_handle *ctx, const char *args) struct async_cmd_request { struct MPContext *mpctx; struct mp_cmd *cmd; - int status; struct mpv_handle *reply_ctx; uint64_t userdata; }; @@ -1117,11 +1116,17 @@ static void async_cmd_complete(struct mp_cmd_ctx *cmd) { struct async_cmd_request *req = cmd->on_completion_priv; - req->status = cmd->success ? 0 : MPV_ERROR_COMMAND; + struct mpv_event_command *data = talloc_zero(NULL, struct mpv_event_command); + data->result = cmd->result; + cmd->result = (mpv_node){0}; + talloc_steal(data, node_get_alloc(&data->result)); - // Async command invocation - send a reply message. - status_reply(req->reply_ctx, MPV_EVENT_COMMAND_REPLY, - req->userdata, req->status); + struct mpv_event reply = { + .event_id = MPV_EVENT_COMMAND_REPLY, + .data = data, + .error = cmd->success ? 0 : MPV_ERROR_COMMAND, + }; + send_reply(req->reply_ctx, req->userdata, &reply); talloc_free(req); }