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> <returnvalue>0 or 1</returnvalue>
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<varname>consume</varname>:
<returnvalue>0 or 1</returnvalue>
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<varname>playlist</varname>: <varname>playlist</varname>:
@ -352,6 +358,21 @@
<section> <section>
<title>Playback options</title> <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> <variablelist>
<varlistentry id="command_crossfade"> <varlistentry id="command_crossfade">
<term> <term>

View File

@ -60,6 +60,7 @@
#define COMMAND_STATUS_STATE "state" #define COMMAND_STATUS_STATE "state"
#define COMMAND_STATUS_REPEAT "repeat" #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_RANDOM "random"
#define COMMAND_STATUS_PLAYLIST "playlist" #define COMMAND_STATUS_PLAYLIST "playlist"
#define COMMAND_STATUS_PLAYLIST_LENGTH "playlistlength" #define COMMAND_STATUS_PLAYLIST_LENGTH "playlistlength"
@ -471,6 +472,7 @@ handle_status(struct client *client,
COMMAND_STATUS_REPEAT ": %i\n" COMMAND_STATUS_REPEAT ": %i\n"
COMMAND_STATUS_RANDOM ": %i\n" COMMAND_STATUS_RANDOM ": %i\n"
COMMAND_STATUS_SINGLE ": %i\n" COMMAND_STATUS_SINGLE ": %i\n"
COMMAND_STATUS_CONSUME ": %i\n"
COMMAND_STATUS_PLAYLIST ": %li\n" COMMAND_STATUS_PLAYLIST ": %li\n"
COMMAND_STATUS_PLAYLIST_LENGTH ": %i\n" COMMAND_STATUS_PLAYLIST_LENGTH ": %i\n"
COMMAND_STATUS_CROSSFADE ": %i\n" COMMAND_STATUS_CROSSFADE ": %i\n"
@ -479,6 +481,7 @@ handle_status(struct client *client,
getPlaylistRepeatStatus(&g_playlist), getPlaylistRepeatStatus(&g_playlist),
getPlaylistRandomStatus(&g_playlist), getPlaylistRandomStatus(&g_playlist),
getPlaylistSingleStatus(&g_playlist), getPlaylistSingleStatus(&g_playlist),
getPlaylistConsumeStatus(&g_playlist),
getPlaylistVersion(&g_playlist), getPlaylistVersion(&g_playlist),
getPlaylistLength(&g_playlist), getPlaylistLength(&g_playlist),
(int)(getPlayerCrossFade() + 0.5), (int)(getPlayerCrossFade() + 0.5),
@ -1113,6 +1116,24 @@ handle_single(struct client *client, G_GNUC_UNUSED int argc, char *argv[])
return COMMAND_RETURN_OK; 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 static enum command_return
handle_random(struct client *client, G_GNUC_UNUSED int argc, char *argv[]) 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 }, { "clearerror", PERMISSION_CONTROL, 0, 0, handle_clearerror },
{ "close", PERMISSION_NONE, -1, -1, handle_close }, { "close", PERMISSION_NONE, -1, -1, handle_close },
{ "commands", PERMISSION_NONE, 0, 0, handle_commands }, { "commands", PERMISSION_NONE, 0, 0, handle_commands },
{ "consume", PERMISSION_CONTROL, 1, 1, handle_consume },
{ "count", PERMISSION_READ, 2, -1, handle_count }, { "count", PERMISSION_READ, 2, -1, handle_count },
{ "crossfade", PERMISSION_CONTROL, 1, 1, handle_crossfade }, { "crossfade", PERMISSION_CONTROL, 1, 1, handle_crossfade },
{ "currentsong", PERMISSION_READ, 0, 0, handle_currentsong }, { "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, /* queued song has started: copy queued to current,
and notify the clients */ and notify the clients */
int current = playlist->current;
playlist->current = playlist->queued; playlist->current = playlist->queued;
playlist->queued = -1; playlist->queued = -1;
if(playlist->queue.consume)
deleteFromPlaylist(playlist, queue_order_to_position(&playlist->queue, current));
idle_add(IDLE_PLAYER); idle_add(IDLE_PLAYER);
} }
} }
@ -267,6 +271,12 @@ getPlaylistSingleStatus(const struct playlist *playlist)
return playlist->queue.single; return playlist->queue.single;
} }
bool
getPlaylistConsumeStatus(const struct playlist *playlist)
{
return playlist->queue.consume;
}
void setPlaylistRepeatStatus(struct playlist *playlist, bool status) void setPlaylistRepeatStatus(struct playlist *playlist, bool status)
{ {
if (status == playlist->queue.repeat) if (status == playlist->queue.repeat)
@ -307,6 +317,15 @@ void setPlaylistSingleStatus(struct playlist *playlist, bool status)
idle_add(IDLE_OPTIONS); 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) void setPlaylistRandomStatus(struct playlist *playlist, bool status)
{ {
const struct song *queued; const struct song *queued;

View File

@ -184,6 +184,11 @@ getPlaylistSingleStatus(const struct playlist *playlist);
void setPlaylistSingleStatus(struct playlist *playlist, bool status); 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 getPlaylistCurrentSong(const struct playlist *playlist);
int getPlaylistNextSong(const struct playlist *playlist); int getPlaylistNextSong(const struct playlist *playlist);

View File

@ -139,6 +139,7 @@ void
nextSongInPlaylist(struct playlist *playlist) nextSongInPlaylist(struct playlist *playlist)
{ {
int next_order; int next_order;
int current;
if (!playlist->playing) if (!playlist->playing)
return; return;
@ -146,6 +147,7 @@ nextSongInPlaylist(struct playlist *playlist)
assert(!queue_is_empty(&playlist->queue)); assert(!queue_is_empty(&playlist->queue));
assert(queue_valid_order(&playlist->queue, playlist->current)); assert(queue_valid_order(&playlist->queue, playlist->current));
current = playlist->current;
playlist->stop_on_error = false; playlist->stop_on_error = false;
/* determine the next song from the queue's order list */ /* determine the next song from the queue's order list */
@ -156,9 +158,9 @@ nextSongInPlaylist(struct playlist *playlist)
playlist->queue.single = false; playlist->queue.single = false;
/* no song after this one: stop playback */ /* no song after this one: stop playback */
stopPlaylist(playlist); stopPlaylist(playlist);
return;
} }
else
{
if (next_order == 0 && playlist->queue.random) { if (next_order == 0 && playlist->queue.random) {
/* The queue told us that the next song is the first /* The queue told us that the next song is the first
song. This means we are in repeat mode. Shuffle song. This means we are in repeat mode. Shuffle
@ -176,6 +178,11 @@ nextSongInPlaylist(struct playlist *playlist)
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) void previousSongInPlaylist(struct playlist *playlist)
{ {
static time_t lastTime; static time_t lastTime;

View File

@ -35,6 +35,7 @@
#define PLAYLIST_STATE_FILE_RANDOM "random: " #define PLAYLIST_STATE_FILE_RANDOM "random: "
#define PLAYLIST_STATE_FILE_REPEAT "repeat: " #define PLAYLIST_STATE_FILE_REPEAT "repeat: "
#define PLAYLIST_STATE_FILE_SINGLE "single: " #define PLAYLIST_STATE_FILE_SINGLE "single: "
#define PLAYLIST_STATE_FILE_CONSUME "consume: "
#define PLAYLIST_STATE_FILE_CURRENT "current: " #define PLAYLIST_STATE_FILE_CURRENT "current: "
#define PLAYLIST_STATE_FILE_TIME "time: " #define PLAYLIST_STATE_FILE_TIME "time: "
#define PLAYLIST_STATE_FILE_CROSSFADE "crossfade: " #define PLAYLIST_STATE_FILE_CROSSFADE "crossfade: "
@ -74,6 +75,8 @@ playlist_state_save(FILE *fp, const struct playlist *playlist)
playlist->queue.repeat); playlist->queue.repeat);
fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_SINGLE, fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_SINGLE,
playlist->queue.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, fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE,
(int)(getPlayerCrossFade())); (int)(getPlayerCrossFade()));
fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN); fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN);
@ -146,6 +149,13 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
setPlaylistSingleStatus(playlist, true); setPlaylistSingleStatus(playlist, true);
} else } else
setPlaylistSingleStatus(playlist, false); 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)) { } else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CROSSFADE)) {
setPlayerCrossFade(atoi setPlayerCrossFade(atoi
(& (&

View File

@ -283,6 +283,7 @@ queue_init(struct queue *queue, unsigned max_length)
queue->repeat = false; queue->repeat = false;
queue->random = false; queue->random = false;
queue->single = false; queue->single = false;
queue->consume = false;
queue->items = g_new(struct queue_item, max_length); queue->items = g_new(struct queue_item, max_length);
queue->order = g_malloc(sizeof(queue->order[0]) * queue->order = g_malloc(sizeof(queue->order[0]) *

View File

@ -84,6 +84,9 @@ struct queue {
/** play only current song. */ /** play only current song. */
bool single; bool single;
/** remove each played files. */
bool consume;
/** play back songs in random order? */ /** play back songs in random order? */
bool random; bool random;