aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Bignon <romain@peerfuse.org>2009-03-30 00:01:02 +0200
committerRomain Bignon <romain@peerfuse.org>2009-03-30 17:37:55 +0200
commite81f683a1805871fa671485dc2a6327763ef1cf0 (patch)
treeb2fe3b82caf9b77dcabf2b475d10f34d20445a69
parent7d9380fd913355b70f846a4adc263363d12813ba (diff)
downloadmpd-e81f683a1805871fa671485dc2a6327763ef1cf0.tar.gz
mpd-e81f683a1805871fa671485dc2a6327763ef1cf0.tar.xz
mpd-e81f683a1805871fa671485dc2a6327763ef1cf0.zip
implemented the 'consume' mode
Consume mode removes each song played
Diffstat (limited to '')
-rw-r--r--doc/protocol.xml21
-rw-r--r--src/command.c24
-rw-r--r--src/playlist.c19
-rw-r--r--src/playlist.h5
-rw-r--r--src/playlist_control.c35
-rw-r--r--src/playlist_state.c10
-rw-r--r--src/queue.c1
-rw-r--r--src/queue.h3
8 files changed, 103 insertions, 15 deletions
diff --git a/doc/protocol.xml b/doc/protocol.xml
index 3dcfedeb5..0096ed672 100644
--- a/doc/protocol.xml
+++ b/doc/protocol.xml
@@ -223,6 +223,12 @@
</para>
</listitem>
<listitem>
+ <para>
+ <varname>consume</varname>:
+ <returnvalue>0 or 1</returnvalue>
+ </para>
+ </listitem>
+ <listitem>
<para>
<varname>playlist</varname>:
<returnvalue>31-bit unsigned integer, the playlist
@@ -352,6 +358,21 @@
<section>
<title>Playback options</title>
+ <varlistentry id="command_consume">
+ <term>
+ <cmdsynopsis>
+ <command>consume</command>
+ <arg choice="req"><replaceable>STATE</replaceable></arg>
+ </cmdsynopsis>
+ </term>
+ <listitem>
+ <para>
+ Sets consume state to <varname>STATE</varname>,
+ <varname>STATE</varname> should be 0 or 1.
+ When consume is activated, each song played is removed from playlist.
+ </para>
+ </listitem>
+ </varlistentry>
<variablelist>
<varlistentry id="command_crossfade">
<term>
diff --git a/src/command.c b/src/command.c
index 69fbe514f..d4363ff65 100644
--- a/src/command.c
+++ b/src/command.c
@@ -59,7 +59,8 @@
#define COMMAND_STATUS_VOLUME "volume"
#define COMMAND_STATUS_STATE "state"
#define COMMAND_STATUS_REPEAT "repeat"
-#define COMMAND_STATUS_SINGLE "single"
+#define COMMAND_STATUS_SINGLE "single"
+#define COMMAND_STATUS_CONSUME "consume"
#define COMMAND_STATUS_RANDOM "random"
#define COMMAND_STATUS_PLAYLIST "playlist"
#define COMMAND_STATUS_PLAYLIST_LENGTH "playlistlength"
@@ -471,6 +472,7 @@ handle_status(struct client *client,
COMMAND_STATUS_REPEAT ": %i\n"
COMMAND_STATUS_RANDOM ": %i\n"
COMMAND_STATUS_SINGLE ": %i\n"
+ COMMAND_STATUS_CONSUME ": %i\n"
COMMAND_STATUS_PLAYLIST ": %li\n"
COMMAND_STATUS_PLAYLIST_LENGTH ": %i\n"
COMMAND_STATUS_CROSSFADE ": %i\n"
@@ -479,6 +481,7 @@ handle_status(struct client *client,
getPlaylistRepeatStatus(&g_playlist),
getPlaylistRandomStatus(&g_playlist),
getPlaylistSingleStatus(&g_playlist),
+ getPlaylistConsumeStatus(&g_playlist),
getPlaylistVersion(&g_playlist),
getPlaylistLength(&g_playlist),
(int)(getPlayerCrossFade() + 0.5),
@@ -1114,6 +1117,24 @@ handle_single(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
}
static enum command_return
+handle_consume(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
+{
+ int status;
+
+ if (!check_int(client, &status, argv[1], need_integer))
+ return COMMAND_RETURN_ERROR;
+
+ if (status != 0 && status != 1) {
+ command_error(client, ACK_ERROR_ARG,
+ "\"%i\" is not 0 or 1", status);
+ return COMMAND_RETURN_ERROR;
+ }
+
+ setPlaylistConsumeStatus(&g_playlist, status);
+ return COMMAND_RETURN_OK;
+}
+
+static enum command_return
handle_random(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
{
int status;
@@ -1573,6 +1594,7 @@ static const struct command commands[] = {
{ "clearerror", PERMISSION_CONTROL, 0, 0, handle_clearerror },
{ "close", PERMISSION_NONE, -1, -1, handle_close },
{ "commands", PERMISSION_NONE, 0, 0, handle_commands },
+ { "consume", PERMISSION_CONTROL, 1, 1, handle_consume },
{ "count", PERMISSION_READ, 2, -1, handle_count },
{ "crossfade", PERMISSION_CONTROL, 1, 1, handle_crossfade },
{ "currentsong", PERMISSION_READ, 0, 0, handle_currentsong },
diff --git a/src/playlist.c b/src/playlist.c
index 776308db0..79f6022a5 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -100,9 +100,13 @@ static void syncPlaylistWithQueue(struct playlist *playlist)
/* queued song has started: copy queued to current,
and notify the clients */
+ int current = playlist->current;
playlist->current = playlist->queued;
playlist->queued = -1;
+ if(playlist->queue.consume)
+ deleteFromPlaylist(playlist, queue_order_to_position(&playlist->queue, current));
+
idle_add(IDLE_PLAYER);
}
}
@@ -267,6 +271,12 @@ getPlaylistSingleStatus(const struct playlist *playlist)
return playlist->queue.single;
}
+bool
+getPlaylistConsumeStatus(const struct playlist *playlist)
+{
+ return playlist->queue.consume;
+}
+
void setPlaylistRepeatStatus(struct playlist *playlist, bool status)
{
if (status == playlist->queue.repeat)
@@ -307,6 +317,15 @@ void setPlaylistSingleStatus(struct playlist *playlist, bool status)
idle_add(IDLE_OPTIONS);
}
+void setPlaylistConsumeStatus(struct playlist *playlist, bool status)
+{
+ if (status == playlist->queue.consume)
+ return;
+
+ playlist->queue.consume = status;
+ idle_add(IDLE_OPTIONS);
+}
+
void setPlaylistRandomStatus(struct playlist *playlist, bool status)
{
const struct song *queued;
diff --git a/src/playlist.h b/src/playlist.h
index 17862b335..4237cea98 100644
--- a/src/playlist.h
+++ b/src/playlist.h
@@ -184,6 +184,11 @@ getPlaylistSingleStatus(const struct playlist *playlist);
void setPlaylistSingleStatus(struct playlist *playlist, bool status);
+bool
+getPlaylistConsumeStatus(const struct playlist *playlist);
+
+void setPlaylistConsumeStatus(struct playlist *playlist, bool status);
+
int getPlaylistCurrentSong(const struct playlist *playlist);
int getPlaylistNextSong(const struct playlist *playlist);
diff --git a/src/playlist_control.c b/src/playlist_control.c
index 9e31c07ab..4f51345c3 100644
--- a/src/playlist_control.c
+++ b/src/playlist_control.c
@@ -139,6 +139,7 @@ void
nextSongInPlaylist(struct playlist *playlist)
{
int next_order;
+ int current;
if (!playlist->playing)
return;
@@ -146,6 +147,7 @@ nextSongInPlaylist(struct playlist *playlist)
assert(!queue_is_empty(&playlist->queue));
assert(queue_valid_order(&playlist->queue, playlist->current));
+ current = playlist->current;
playlist->stop_on_error = false;
/* determine the next song from the queue's order list */
@@ -156,24 +158,29 @@ nextSongInPlaylist(struct playlist *playlist)
playlist->queue.single = false;
/* no song after this one: stop playback */
stopPlaylist(playlist);
- return;
}
+ else
+ {
+ if (next_order == 0 && playlist->queue.random) {
+ /* The queue told us that the next song is the first
+ song. This means we are in repeat mode. Shuffle
+ the queue order, so this time, the user hears the
+ songs in a different than before */
+ assert(playlist->queue.repeat);
+
+ queue_shuffle_order(&playlist->queue);
+
+ /* note that playlist->current and playlist->queued are
+ now invalid, but playPlaylistOrderNumber() will
+ discard them anyway */
+ }
- if (next_order == 0 && playlist->queue.random) {
- /* The queue told us that the next song is the first
- song. This means we are in repeat mode. Shuffle
- the queue order, so this time, the user hears the
- songs in a different than before */
- assert(playlist->queue.repeat);
-
- queue_shuffle_order(&playlist->queue);
-
- /* note that playlist->current and playlist->queued are
- now invalid, but playPlaylistOrderNumber() will
- discard them anyway */
+ playPlaylistOrderNumber(playlist, next_order);
}
- playPlaylistOrderNumber(playlist, next_order);
+ /* Consume mode removes each played songs. */
+ if(playlist->queue.consume)
+ deleteFromPlaylist(playlist, queue_order_to_position(&playlist->queue, current));
}
void previousSongInPlaylist(struct playlist *playlist)
diff --git a/src/playlist_state.c b/src/playlist_state.c
index f5b1456d7..af0f7982b 100644
--- a/src/playlist_state.c
+++ b/src/playlist_state.c
@@ -35,6 +35,7 @@
#define PLAYLIST_STATE_FILE_RANDOM "random: "
#define PLAYLIST_STATE_FILE_REPEAT "repeat: "
#define PLAYLIST_STATE_FILE_SINGLE "single: "
+#define PLAYLIST_STATE_FILE_CONSUME "consume: "
#define PLAYLIST_STATE_FILE_CURRENT "current: "
#define PLAYLIST_STATE_FILE_TIME "time: "
#define PLAYLIST_STATE_FILE_CROSSFADE "crossfade: "
@@ -74,6 +75,8 @@ playlist_state_save(FILE *fp, const struct playlist *playlist)
playlist->queue.repeat);
fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_SINGLE,
playlist->queue.single);
+ fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CONSUME,
+ playlist->queue.consume);
fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE,
(int)(getPlayerCrossFade()));
fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN);
@@ -146,6 +149,13 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
setPlaylistSingleStatus(playlist, true);
} else
setPlaylistSingleStatus(playlist, false);
+ } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CONSUME)) {
+ if (strcmp
+ (&(buffer[strlen(PLAYLIST_STATE_FILE_CONSUME)]),
+ "1") == 0) {
+ setPlaylistConsumeStatus(playlist, true);
+ } else
+ setPlaylistConsumeStatus(playlist, false);
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CROSSFADE)) {
setPlayerCrossFade(atoi
(&
diff --git a/src/queue.c b/src/queue.c
index 21d4884c6..7cc110bc7 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -283,6 +283,7 @@ queue_init(struct queue *queue, unsigned max_length)
queue->repeat = false;
queue->random = false;
queue->single = false;
+ queue->consume = false;
queue->items = g_new(struct queue_item, max_length);
queue->order = g_malloc(sizeof(queue->order[0]) *
diff --git a/src/queue.h b/src/queue.h
index 452084ce8..7dca66406 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -84,6 +84,9 @@ struct queue {
/** play only current song. */
bool single;
+ /** remove each played files. */
+ bool consume;
+
/** play back songs in random order? */
bool random;