Commit e81f683a authored by Romain Bignon's avatar Romain Bignon

implemented the 'consume' mode

Consume mode removes each song played
parent 7d9380fd
......@@ -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>
......
......@@ -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 },
......
......@@ -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;
......
......@@ -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);
......
......@@ -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)
......
......@@ -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
(&
......
......@@ -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]) *
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment