Пример #1
0
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;
	}
}
static void
playlist_delete_internal(struct playlist *playlist, unsigned song,
			 const struct song **queued_p)
{
	unsigned songOrder;

	assert(song < queue_length(&playlist->queue));

	songOrder = queue_position_to_order(&playlist->queue, song);

	if (playlist->playing && playlist->current == (int)songOrder) {
		bool paused = pc_get_state() == PLAYER_STATE_PAUSE;

		/* the current song is going to be deleted: stop the player */

		pc_stop();
		playlist->playing = false;

		/* see which song is going to be played instead */

		playlist->current = queue_next_order(&playlist->queue,
						     playlist->current);
		if (playlist->current == (int)songOrder)
			playlist->current = -1;

		if (playlist->current >= 0 && !paused)
			/* play the song after the deleted one */
			playlist_play_order(playlist, playlist->current);
		else
			/* no songs left to play, stop playback
			   completely */
			playlist_stop(playlist);

		*queued_p = NULL;
	} else if (playlist->current == (int)songOrder)
		/* there's a "current song" but we're not playing
		   currently - clear "current" */
		playlist->current = -1;

	/* now do it: remove the song */

	if (!song_in_database(queue_get(&playlist->queue, song)))
		pc_song_deleted(queue_get(&playlist->queue, song));

	queue_delete(&playlist->queue, song);

	/* update the "current" and "queued" variables */

	if (playlist->current > (int)songOrder) {
		playlist->current--;
	}
}
void
playlist_next(struct playlist *playlist, struct player_control *pc)
{
	int next_order;
	int current;

	if (!playlist->playing)
		return;

	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 */

	next_order = queue_next_order(&playlist->queue, playlist->current);
	if (next_order < 0) {
		/* no song after this one: stop playback */
		playlist_stop(playlist, pc);

		/* reset "current song" */
		playlist->current = -1;
	}
	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 playlist_play_order() will
			   discard them anyway */
		}

		playlist_play_order(playlist, pc, next_order);
	}

	/* Consume mode removes each played songs. */
	if(playlist->queue.consume)
		playlist_delete(playlist, pc,
				queue_order_to_position(&playlist->queue,
							current));
}