ipc: allow sending commands with named arguments

This has been part of the libmpv for a while, so the implementation in
the IPC code is quite simple: just pass the mpv_node representing the
value of the "command" field without further checks to
mpv_command_node().

The only problem are the IPC-specific commands, which essentially have
their own dispatch mechanism. They expect an array. I'm not going to
rewrite the dispatch mechanism, so these still work only with an array.
I decided make the other case explicit with cmd==NULL. (I could also
have set cmd=="", which would have avoided changing each if condition
since "" matches no existing command, but that felt dirty.)
This commit is contained in:
wm4 2020-02-24 00:31:46 +01:00
parent 67311af05f
commit c418aa3807
2 changed files with 33 additions and 23 deletions

View File

@ -202,6 +202,17 @@ commands that finished execution immediately.
Cancellation of asynchronous commands is available in the libmpv API, but has Cancellation of asynchronous commands is available in the libmpv API, but has
not yet been implemented in the IPC protocol. not yet been implemented in the IPC protocol.
Commands with named arguments
-----------------------------
If the ``command`` field is a JSON object, named arguments are expected. This
is described in the C API ``mpv_command_node()`` documentation (the
``MPV_FORMAT_NODE_MAP`` case). In some cases, this may make commands more
readable, while some obscure commands basically require using named arguments.
Currently, only "proper" commands (as listed by `List of Input Commands`_)
support named arguments.
Commands Commands
-------- --------

View File

@ -254,35 +254,34 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
} }
mpv_node *cmd_node = node_map_get(&msg_node, "command"); mpv_node *cmd_node = node_map_get(&msg_node, "command");
if (!cmd_node || if (!cmd_node) {
(cmd_node->format != MPV_FORMAT_NODE_ARRAY) ||
!cmd_node->u.list->num)
{
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
goto error; goto error;
} }
mpv_node *cmd_str_node = mpv_node_array_get(cmd_node, 0); if (cmd_node->format == MPV_FORMAT_NODE_ARRAY) {
if (!cmd_str_node || (cmd_str_node->format != MPV_FORMAT_STRING)) { mpv_node *cmd_str_node = mpv_node_array_get(cmd_node, 0);
rc = MPV_ERROR_INVALID_PARAMETER; if (!cmd_str_node || (cmd_str_node->format != MPV_FORMAT_STRING)) {
goto error; rc = MPV_ERROR_INVALID_PARAMETER;
goto error;
}
cmd = cmd_str_node->u.string;
} }
cmd = cmd_str_node->u.string; if (cmd && !strcmp("client_name", cmd)) {
if (!strcmp("client_name", cmd)) {
const char *client_name = mpv_client_name(client); const char *client_name = mpv_client_name(client);
mpv_node_map_add_string(ta_parent, &reply_node, "data", client_name); mpv_node_map_add_string(ta_parent, &reply_node, "data", client_name);
rc = MPV_ERROR_SUCCESS; rc = MPV_ERROR_SUCCESS;
} else if (!strcmp("get_time_us", cmd)) { } else if (cmd && !strcmp("get_time_us", cmd)) {
int64_t time_us = mpv_get_time_us(client); int64_t time_us = mpv_get_time_us(client);
mpv_node_map_add_int64(ta_parent, &reply_node, "data", time_us); mpv_node_map_add_int64(ta_parent, &reply_node, "data", time_us);
rc = MPV_ERROR_SUCCESS; rc = MPV_ERROR_SUCCESS;
} else if (!strcmp("get_version", cmd)) { } else if (cmd && !strcmp("get_version", cmd)) {
int64_t ver = mpv_client_api_version(); int64_t ver = mpv_client_api_version();
mpv_node_map_add_int64(ta_parent, &reply_node, "data", ver); mpv_node_map_add_int64(ta_parent, &reply_node, "data", ver);
rc = MPV_ERROR_SUCCESS; rc = MPV_ERROR_SUCCESS;
} else if (!strcmp("get_property", cmd)) { } else if (cmd && !strcmp("get_property", cmd)) {
mpv_node result_node; mpv_node result_node;
if (cmd_node->u.list->num != 2) { if (cmd_node->u.list->num != 2) {
@ -301,7 +300,7 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
mpv_node_map_add(ta_parent, &reply_node, "data", &result_node); mpv_node_map_add(ta_parent, &reply_node, "data", &result_node);
mpv_free_node_contents(&result_node); mpv_free_node_contents(&result_node);
} }
} else if (!strcmp("get_property_string", cmd)) { } else if (cmd && !strcmp("get_property_string", cmd)) {
if (cmd_node->u.list->num != 2) { if (cmd_node->u.list->num != 2) {
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
goto error; goto error;
@ -320,8 +319,8 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
} else { } else {
mpv_node_map_add_null(ta_parent, &reply_node, "data"); mpv_node_map_add_null(ta_parent, &reply_node, "data");
} }
} else if (!strcmp("set_property", cmd) || } else if (cmd && (!strcmp("set_property", cmd) ||
!strcmp("set_property_string", cmd)) !strcmp("set_property_string", cmd)))
{ {
if (cmd_node->u.list->num != 3) { if (cmd_node->u.list->num != 3) {
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
@ -335,7 +334,7 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
rc = mpv_set_property(client, cmd_node->u.list->values[1].u.string, rc = mpv_set_property(client, cmd_node->u.list->values[1].u.string,
MPV_FORMAT_NODE, &cmd_node->u.list->values[2]); MPV_FORMAT_NODE, &cmd_node->u.list->values[2]);
} else if (!strcmp("observe_property", cmd)) { } else if (cmd && !strcmp("observe_property", cmd)) {
if (cmd_node->u.list->num != 3) { if (cmd_node->u.list->num != 3) {
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
goto error; goto error;
@ -355,7 +354,7 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
cmd_node->u.list->values[1].u.int64, cmd_node->u.list->values[1].u.int64,
cmd_node->u.list->values[2].u.string, cmd_node->u.list->values[2].u.string,
MPV_FORMAT_NODE); MPV_FORMAT_NODE);
} else if (!strcmp("observe_property_string", cmd)) { } else if (cmd && !strcmp("observe_property_string", cmd)) {
if (cmd_node->u.list->num != 3) { if (cmd_node->u.list->num != 3) {
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
goto error; goto error;
@ -375,7 +374,7 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
cmd_node->u.list->values[1].u.int64, cmd_node->u.list->values[1].u.int64,
cmd_node->u.list->values[2].u.string, cmd_node->u.list->values[2].u.string,
MPV_FORMAT_STRING); MPV_FORMAT_STRING);
} else if (!strcmp("unobserve_property", cmd)) { } else if (cmd && !strcmp("unobserve_property", cmd)) {
if (cmd_node->u.list->num != 2) { if (cmd_node->u.list->num != 2) {
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
goto error; goto error;
@ -388,7 +387,7 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
rc = mpv_unobserve_property(client, rc = mpv_unobserve_property(client,
cmd_node->u.list->values[1].u.int64); cmd_node->u.list->values[1].u.int64);
} else if (!strcmp("request_log_messages", cmd)) { } else if (cmd && !strcmp("request_log_messages", cmd)) {
if (cmd_node->u.list->num != 2) { if (cmd_node->u.list->num != 2) {
rc = MPV_ERROR_INVALID_PARAMETER; rc = MPV_ERROR_INVALID_PARAMETER;
goto error; goto error;
@ -401,8 +400,8 @@ static char *json_execute_command(struct mpv_handle *client, void *ta_parent,
rc = mpv_request_log_messages(client, rc = mpv_request_log_messages(client,
cmd_node->u.list->values[1].u.string); cmd_node->u.list->values[1].u.string);
} else if (!strcmp("enable_event", cmd) || } else if (cmd && (!strcmp("enable_event", cmd) ||
!strcmp("disable_event", cmd)) !strcmp("disable_event", cmd)))
{ {
bool enable = !strcmp("enable_event", cmd); bool enable = !strcmp("enable_event", cmd);