From 05c91082e3de0b0078c26ddb9da68fd00da8c90e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 4 Jan 2013 20:50:00 +0100 Subject: playlist: convert to C++ --- src/playlist.c | 449 --------------------------------------------------------- 1 file changed, 449 deletions(-) delete mode 100644 src/playlist.c (limited to 'src/playlist.c') diff --git a/src/playlist.c b/src/playlist.c deleted file mode 100644 index 2532d9d46..000000000 --- a/src/playlist.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright (C) 2003-2011 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "playlist_internal.h" -#include "player_control.h" -#include "song.h" -#include "conf.h" -#include "idle.h" - -#include - -#include - -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN "playlist" - -void -playlist_increment_version_all(struct playlist *playlist) -{ - queue_modify_all(&playlist->queue); - idle_add(IDLE_PLAYLIST); -} - -void -playlist_tag_changed(struct playlist *playlist) -{ - if (!playlist->playing) - return; - - assert(playlist->current >= 0); - - queue_modify(&playlist->queue, playlist->current); - idle_add(IDLE_PLAYLIST); -} - -void -playlist_init(struct playlist *playlist) -{ - queue_init(&playlist->queue, - config_get_positive(CONF_MAX_PLAYLIST_LENGTH, - DEFAULT_PLAYLIST_MAX_LENGTH)); - - playlist->queued = -1; - playlist->current = -1; -} - -void -playlist_finish(struct playlist *playlist) -{ - queue_finish(&playlist->queue); -} - -/** - * Queue a song, addressed by its order number. - */ -static void -playlist_queue_song_order(struct playlist *playlist, struct player_control *pc, - unsigned order) -{ - char *uri; - - assert(queue_valid_order(&playlist->queue, order)); - - playlist->queued = order; - - struct song *song = - song_dup_detached(queue_get_order(&playlist->queue, order)); - - uri = song_get_uri(song); - g_debug("queue song %i:\"%s\"", playlist->queued, uri); - g_free(uri); - - pc_enqueue_song(pc, song); -} - -/** - * Called if the player thread has started playing the "queued" song. - */ -static void -playlist_song_started(struct playlist *playlist, struct player_control *pc) -{ - assert(pc->next_song == NULL); - assert(playlist->queued >= -1); - - /* 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) - playlist_delete(playlist, pc, - queue_order_to_position(&playlist->queue, - current)); - - idle_add(IDLE_PLAYER); -} - -const struct song * -playlist_get_queued_song(struct playlist *playlist) -{ - if (!playlist->playing || playlist->queued < 0) - return NULL; - - return queue_get_order(&playlist->queue, playlist->queued); -} - -void -playlist_update_queued_song(struct playlist *playlist, - struct player_control *pc, - const struct song *prev) -{ - int next_order; - const struct song *next_song; - - if (!playlist->playing) - return; - - assert(!queue_is_empty(&playlist->queue)); - assert((playlist->queued < 0) == (prev == NULL)); - - next_order = playlist->current >= 0 - ? queue_next_order(&playlist->queue, playlist->current) - : 0; - - if (next_order == 0 && playlist->queue.random && - !playlist->queue.single) { - /* shuffle the song order again, so we get a different - order each time the playlist is played - completely */ - unsigned current_position = - queue_order_to_position(&playlist->queue, - playlist->current); - - queue_shuffle_order(&playlist->queue); - - /* make sure that the playlist->current still points to - the current song, after the song order has been - shuffled */ - playlist->current = - queue_position_to_order(&playlist->queue, - current_position); - } - - if (next_order >= 0) - next_song = queue_get_order(&playlist->queue, next_order); - else - next_song = NULL; - - if (prev != NULL && next_song != prev) { - /* clear the currently queued song */ - pc_cancel(pc); - playlist->queued = -1; - } - - if (next_order >= 0) { - if (next_song != prev) - playlist_queue_song_order(playlist, pc, next_order); - else - playlist->queued = next_order; - } -} - -void -playlist_play_order(struct playlist *playlist, struct player_control *pc, - int orderNum) -{ - char *uri; - - playlist->playing = true; - playlist->queued = -1; - - struct song *song = - song_dup_detached(queue_get_order(&playlist->queue, orderNum)); - - uri = song_get_uri(song); - g_debug("play %i:\"%s\"", orderNum, uri); - g_free(uri); - - pc_play(pc, song); - playlist->current = orderNum; -} - -static void -playlist_resume_playback(struct playlist *playlist, struct player_control *pc); - -/** - * This is the "PLAYLIST" event handler. It is invoked by the player - * thread whenever it requests a new queued song, or when it exits. - */ -void -playlist_sync(struct playlist *playlist, struct player_control *pc) -{ - if (!playlist->playing) - /* this event has reached us out of sync: we aren't - playing anymore; ignore the event */ - return; - - player_lock(pc); - enum player_state pc_state = pc_get_state(pc); - const struct song *pc_next_song = pc->next_song; - player_unlock(pc); - - if (pc_state == PLAYER_STATE_STOP) - /* the player thread has stopped: check if playback - should be restarted with the next song. That can - happen if the playlist isn't filling the queue fast - enough */ - playlist_resume_playback(playlist, pc); - else { - /* check if the player thread has already started - playing the queued song */ - if (pc_next_song == NULL && playlist->queued != -1) - playlist_song_started(playlist, pc); - - player_lock(pc); - pc_next_song = pc->next_song; - player_unlock(pc); - - /* make sure the queued song is always set (if - possible) */ - if (pc_next_song == NULL && playlist->queued < 0) - playlist_update_queued_song(playlist, pc, NULL); - } -} - -/** - * The player has stopped for some reason. Check the error, and - * decide whether to re-start playback - */ -static void -playlist_resume_playback(struct playlist *playlist, struct player_control *pc) -{ - enum player_error error; - - assert(playlist->playing); - assert(pc_get_state(pc) == PLAYER_STATE_STOP); - - error = pc_get_error_type(pc); - if (error == PLAYER_ERROR_NONE) - playlist->error_count = 0; - else - ++playlist->error_count; - - if ((playlist->stop_on_error && error != PLAYER_ERROR_NONE) || - error == PLAYER_ERROR_OUTPUT || - playlist->error_count >= queue_length(&playlist->queue)) - /* too many errors, or critical error: stop - playback */ - playlist_stop(playlist, pc); - else - /* continue playback at the next song */ - playlist_next(playlist, pc); -} - -bool -playlist_get_repeat(const struct playlist *playlist) -{ - return playlist->queue.repeat; -} - -bool -playlist_get_random(const struct playlist *playlist) -{ - return playlist->queue.random; -} - -bool -playlist_get_single(const struct playlist *playlist) -{ - return playlist->queue.single; -} - -bool -playlist_get_consume(const struct playlist *playlist) -{ - return playlist->queue.consume; -} - -void -playlist_set_repeat(struct playlist *playlist, struct player_control *pc, - bool status) -{ - if (status == playlist->queue.repeat) - return; - - struct queue *queue = &playlist->queue; - - queue->repeat = status; - - pc_set_border_pause(pc, queue->single && !queue->repeat); - - /* if the last song is currently being played, the "next song" - might change when repeat mode is toggled */ - playlist_update_queued_song(playlist, pc, - playlist_get_queued_song(playlist)); - - idle_add(IDLE_OPTIONS); -} - -static void -playlist_order(struct playlist *playlist) -{ - if (playlist->current >= 0) - /* update playlist.current, order==position now */ - playlist->current = queue_order_to_position(&playlist->queue, - playlist->current); - - queue_restore_order(&playlist->queue); -} - -void -playlist_set_single(struct playlist *playlist, struct player_control *pc, - bool status) -{ - if (status == playlist->queue.single) - return; - - struct queue *queue = &playlist->queue; - - queue->single = status; - - pc_set_border_pause(pc, queue->single && !queue->repeat); - - /* if the last song is currently being played, the "next song" - might change when single mode is toggled */ - playlist_update_queued_song(playlist, pc, - playlist_get_queued_song(playlist)); - - idle_add(IDLE_OPTIONS); -} - -void -playlist_set_consume(struct playlist *playlist, bool status) -{ - if (status == playlist->queue.consume) - return; - - playlist->queue.consume = status; - idle_add(IDLE_OPTIONS); -} - -void -playlist_set_random(struct playlist *playlist, struct player_control *pc, - bool status) -{ - const struct song *queued; - - if (status == playlist->queue.random) - return; - - queued = playlist_get_queued_song(playlist); - - playlist->queue.random = status; - - if (playlist->queue.random) { - /* shuffle the queue order, but preserve - playlist->current */ - - int current_position = - playlist->playing && playlist->current >= 0 - ? (int)queue_order_to_position(&playlist->queue, - playlist->current) - : -1; - - queue_shuffle_order(&playlist->queue); - - if (current_position >= 0) { - /* make sure the current song is the first in - the order list, so the whole rest of the - playlist is played after that */ - unsigned current_order = - queue_position_to_order(&playlist->queue, - current_position); - queue_swap_order(&playlist->queue, 0, current_order); - playlist->current = 0; - } else - playlist->current = -1; - } else - playlist_order(playlist); - - playlist_update_queued_song(playlist, pc, queued); - - idle_add(IDLE_OPTIONS); -} - -int -playlist_get_current_song(const struct playlist *playlist) -{ - if (playlist->current >= 0) - return queue_order_to_position(&playlist->queue, - playlist->current); - - return -1; -} - -int -playlist_get_next_song(const struct playlist *playlist) -{ - if (playlist->current >= 0) - { - if (playlist->queue.single == 1 && playlist->queue.repeat == 1) - return queue_order_to_position(&playlist->queue, - playlist->current); - else if (playlist->current + 1 < (int)queue_length(&playlist->queue)) - return queue_order_to_position(&playlist->queue, - playlist->current + 1); - else if (playlist->queue.repeat == 1) - return queue_order_to_position(&playlist->queue, 0); - } - - return -1; -} - -unsigned long -playlist_get_version(const struct playlist *playlist) -{ - return playlist->queue.version; -} - -int -playlist_get_length(const struct playlist *playlist) -{ - return queue_length(&playlist->queue); -} - -unsigned -playlist_get_song_id(const struct playlist *playlist, unsigned song) -{ - return queue_position_to_id(&playlist->queue, song); -} -- cgit v1.2.3