From e81f683a1805871fa671485dc2a6327763ef1cf0 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Mon, 30 Mar 2009 00:01:02 +0200 Subject: implemented the 'consume' mode Consume mode removes each song played --- doc/protocol.xml | 21 +++++++++++++++++++++ src/command.c | 24 +++++++++++++++++++++++- src/playlist.c | 19 +++++++++++++++++++ src/playlist.h | 5 +++++ src/playlist_control.c | 35 +++++++++++++++++++++-------------- src/playlist_state.c | 10 ++++++++++ src/queue.c | 1 + src/queue.h | 3 +++ 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 @@ -222,6 +222,12 @@ 0 or 1 + + + consume: + 0 or 1 + + playlist: @@ -352,6 +358,21 @@
Playback options + + + + consume + STATE + + + + + Sets consume state to STATE, + STATE should be 0 or 1. + When consume is activated, each song played is removed from playlist. + + + 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), @@ -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 }, 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; -- cgit v1.2.3