implemented the 'consume' mode

Consume mode removes each song played
This commit is contained in:
Romain Bignon 2009-03-30 00:01:02 +02:00
parent 7d9380fd91
commit e81f683a18
8 changed files with 105 additions and 17 deletions

View File

@ -222,6 +222,12 @@
<returnvalue>0 or 1</returnvalue>
</para>
</listitem>
<listitem>
<para>
<varname>consume</varname>:
<returnvalue>0 or 1</returnvalue>
</para>
</listitem>
<listitem>
<para>
<varname>playlist</varname>:
@ -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>

View File

@ -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),
@ -1113,6 +1116,24 @@ handle_single(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
return COMMAND_RETURN_OK;
}
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[])
{
@ -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 },

View File

@ -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;

View File

@ -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);

View File

@ -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 */
}
playPlaylistOrderNumber(playlist, next_order);
}
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);
/* Consume mode removes each played songs. */
if(playlist->queue.consume)
deleteFromPlaylist(playlist, queue_order_to_position(&playlist->queue, current));
}
void previousSongInPlaylist(struct playlist *playlist)

View File

@ -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
(&

View File

@ -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]) *

View File

@ -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;