summaryrefslogtreecommitdiffstats
path: root/input
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-13 16:47:30 +0200
committerwm4 <wm4@nowhere>2014-09-13 16:47:30 +0200
commit893f4a0feebde98247141855700173011bdeb353 (patch)
tree8c5c2a0579a8e438df57accbb418026a3d38b4cc /input
parent2e91d44e2031c299de0d879e2656024d701c27da (diff)
downloadmpv-893f4a0feebde98247141855700173011bdeb353.tar.bz2
mpv-893f4a0feebde98247141855700173011bdeb353.tar.xz
input: distinguish playlist navigation and quit commands for abort
Refine the ugly hack from the previous commit, and let the "quit" command and some others abort playback immediately. For playlist_next/playlist_prev, still use the old hack, because we can't know if they would stop playback or not.
Diffstat (limited to 'input')
-rw-r--r--input/cmd_list.c33
-rw-r--r--input/cmd_list.h4
-rw-r--r--input/input.c28
3 files changed, 37 insertions, 28 deletions
diff --git a/input/cmd_list.c b/input/cmd_list.c
index 88e5b78f91..08b9ea5735 100644
--- a/input/cmd_list.c
+++ b/input/cmd_list.c
@@ -251,31 +251,36 @@ bool mp_replace_legacy_cmd(void *t, bstr *s)
return false;
}
-static bool is_abort_cmd(int cmd_id)
+// 0: no, 1: maybe, 2: sure
+static int is_abort_cmd(struct mp_cmd *cmd)
{
- switch (cmd_id) {
+ switch (cmd->id) {
case MP_CMD_QUIT:
case MP_CMD_QUIT_WATCH_LATER:
case MP_CMD_STOP:
+ return 2;
case MP_CMD_PLAYLIST_NEXT:
case MP_CMD_PLAYLIST_PREV:
- return true;
+ return 1;
+ case MP_CMD_COMMAND_LIST:;
+ int r = 0;
+ for (struct mp_cmd *sub = cmd->args[0].v.p; sub; sub = sub->queue_next) {
+ int x = is_abort_cmd(cmd);
+ r = MPMAX(r, x);
+ }
+ return r;
}
- return false;
+ return 0;
+}
+
+bool mp_input_is_maybe_abort_cmd(struct mp_cmd *cmd)
+{
+ return is_abort_cmd(cmd) >= 1;
}
bool mp_input_is_abort_cmd(struct mp_cmd *cmd)
{
- if (is_abort_cmd(cmd->id))
- return true;
- if (cmd->id == MP_CMD_COMMAND_LIST) {
- for (struct mp_cmd *sub = cmd->args[0].v.p; sub; sub = sub->queue_next)
- {
- if (mp_input_is_abort_cmd(sub))
- return true;
- }
- }
- return false;
+ return is_abort_cmd(cmd) >= 2;
}
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd)
diff --git a/input/cmd_list.h b/input/cmd_list.h
index ada1932f8d..b2b8e2a4d2 100644
--- a/input/cmd_list.h
+++ b/input/cmd_list.h
@@ -101,8 +101,10 @@ enum mp_command_type {
MP_CMD_COMMAND_LIST, // list of sub-commands in args[0].v.p
};
-// Executing this command will abort playback (play something else, or quit).
+// Executing this command will maybe abort playback (play something else, or quit).
struct mp_cmd;
+bool mp_input_is_maybe_abort_cmd(struct mp_cmd *cmd);
+// This command will definitely abort playback.
bool mp_input_is_abort_cmd(struct mp_cmd *cmd);
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd);
diff --git a/input/input.c b/input/input.c
index 3e9b40d158..02589e1941 100644
--- a/input/input.c
+++ b/input/input.c
@@ -245,17 +245,6 @@ static int queue_count_cmds(struct cmd_queue *queue)
return res;
}
-static bool has_abort_cmds(struct input_ctx *ictx)
-{
- bool ret = false;
- for (struct mp_cmd *cmd = ictx->cmd_queue.first; cmd; cmd = cmd->queue_next)
- if (mp_input_is_abort_cmd(cmd)) {
- ret = true;
- break;
- }
- return ret;
-}
-
static void queue_remove(struct cmd_queue *queue, struct mp_cmd *cmd)
{
struct mp_cmd **p_prev = &queue->first;
@@ -794,12 +783,25 @@ static void adjust_max_wait_time(struct input_ctx *ictx, double *time)
}
}
+static bool test_abort_cmd(struct input_ctx *ictx, struct mp_cmd *new)
+{
+ if (!mp_input_is_maybe_abort_cmd(new))
+ return false;
+ if (mp_input_is_abort_cmd(new))
+ return true;
+ // Abort only if there are going to be at least 2 commands in the queue.
+ for (struct mp_cmd *cmd = ictx->cmd_queue.first; cmd; cmd = cmd->queue_next) {
+ if (mp_input_is_maybe_abort_cmd(cmd))
+ return true;
+ }
+ return false;
+}
+
int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd)
{
input_lock(ictx);
if (cmd) {
- // Abort only if there are going to be at least 2 commands in the queue.
- if (ictx->cancel && mp_input_is_abort_cmd(cmd) && has_abort_cmds(ictx))
+ if (ictx->cancel && test_abort_cmd(ictx, cmd))
mp_cancel_trigger(ictx->cancel);
queue_add_tail(&ictx->cmd_queue, cmd);
mp_input_wakeup(ictx);