aboutsummaryrefslogtreecommitdiffstats
path: root/src/Playlist.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Playlist.cxx')
-rw-r--r--src/Playlist.cxx349
1 files changed, 0 insertions, 349 deletions
diff --git a/src/Playlist.cxx b/src/Playlist.cxx
deleted file mode 100644
index 526f35298..000000000
--- a/src/Playlist.cxx
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 2003-2013 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.hxx"
-#include "PlaylistError.hxx"
-#include "PlayerControl.hxx"
-#include "Song.hxx"
-#include "tag/Tag.hxx"
-#include "Idle.hxx"
-#include "Log.hxx"
-
-#include <assert.h>
-
-void
-playlist::TagModified(Song &&song)
-{
- if (!playing || song.tag == nullptr)
- return;
-
- assert(current >= 0);
-
- Song &current_song = queue.GetOrder(current);
- if (SongEquals(song, current_song))
- current_song.ReplaceTag(std::move(*song.tag));
-
- queue.ModifyAtOrder(current);
- queue.IncrementVersion();
- idle_add(IDLE_PLAYLIST);
-}
-
-/**
- * Queue a song, addressed by its order number.
- */
-static void
-playlist_queue_song_order(playlist &playlist, PlayerControl &pc,
- unsigned order)
-{
- assert(playlist.queue.IsValidOrder(order));
-
- playlist.queued = order;
-
- Song *song = playlist.queue.GetOrder(order).DupDetached();
-
- {
- const auto uri = song->GetURI();
- FormatDebug(playlist_domain, "queue song %i:\"%s\"",
- playlist.queued, uri.c_str());
- }
-
- pc.EnqueueSong(song);
-}
-
-/**
- * Called if the player thread has started playing the "queued" song.
- */
-static void
-playlist_song_started(playlist &playlist, PlayerControl &pc)
-{
- assert(pc.next_song == nullptr);
- 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.DeleteOrder(pc, current);
-
- idle_add(IDLE_PLAYER);
-}
-
-const Song *
-playlist::GetQueuedSong() const
-{
- return playing && queued >= 0
- ? &queue.GetOrder(queued)
- : nullptr;
-}
-
-void
-playlist::UpdateQueuedSong(PlayerControl &pc, const Song *prev)
-{
- if (!playing)
- return;
-
- if (prev == nullptr && bulk_edit)
- /* postponed until CommitBulk() to avoid always
- queueing the first song that is being added (in
- random mode) */
- return;
-
- assert(!queue.IsEmpty());
- assert((queued < 0) == (prev == nullptr));
-
- const int next_order = current >= 0
- ? queue.GetNextOrder(current)
- : 0;
-
- if (next_order == 0 && queue.random && !queue.single) {
- /* shuffle the song order again, so we get a different
- order each time the playlist is played
- completely */
- const unsigned current_position =
- queue.OrderToPosition(current);
-
- queue.ShuffleOrder();
-
- /* make sure that the current still points to
- the current song, after the song order has been
- shuffled */
- current = queue.PositionToOrder(current_position);
- }
-
- const Song *const next_song = next_order >= 0
- ? &queue.GetOrder(next_order)
- : nullptr;
-
- if (prev != nullptr && next_song != prev) {
- /* clear the currently queued song */
- pc.Cancel();
- queued = -1;
- }
-
- if (next_order >= 0) {
- if (next_song != prev)
- playlist_queue_song_order(*this, pc, next_order);
- else
- queued = next_order;
- }
-}
-
-void
-playlist::PlayOrder(PlayerControl &pc, int order)
-{
- playing = true;
- queued = -1;
-
- Song *song = queue.GetOrder(order).DupDetached();
-
- {
- const auto uri = song->GetURI();
- FormatDebug(playlist_domain, "play %i:\"%s\"",
- order, uri.c_str());
- }
-
- pc.Play(song);
- current = order;
-}
-
-static void
-playlist_resume_playback(playlist &playlist, PlayerControl &pc);
-
-void
-playlist::SyncWithPlayer(PlayerControl &pc)
-{
- if (!playing)
- /* this event has reached us out of sync: we aren't
- playing anymore; ignore the event */
- return;
-
- pc.Lock();
- const PlayerState pc_state = pc.GetState();
- const Song *pc_next_song = pc.next_song;
- pc.Unlock();
-
- if (pc_state == PlayerState::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(*this, pc);
- else {
- /* check if the player thread has already started
- playing the queued song */
- if (pc_next_song == nullptr && queued != -1)
- playlist_song_started(*this, pc);
-
- pc.Lock();
- pc_next_song = pc.next_song;
- pc.Unlock();
-
- /* make sure the queued song is always set (if
- possible) */
- if (pc_next_song == nullptr && queued < 0)
- UpdateQueuedSong(pc, nullptr);
- }
-}
-
-/**
- * The player has stopped for some reason. Check the error, and
- * decide whether to re-start playback
- */
-static void
-playlist_resume_playback(playlist &playlist, PlayerControl &pc)
-{
- assert(playlist.playing);
- assert(pc.GetState() == PlayerState::STOP);
-
- const auto error = pc.GetErrorType();
- if (error == PlayerError::NONE)
- playlist.error_count = 0;
- else
- ++playlist.error_count;
-
- if ((playlist.stop_on_error && error != PlayerError::NONE) ||
- error == PlayerError::OUTPUT ||
- playlist.error_count >= playlist.queue.GetLength())
- /* too many errors, or critical error: stop
- playback */
- playlist.Stop(pc);
- else
- /* continue playback at the next song */
- playlist.PlayNext(pc);
-}
-
-void
-playlist::SetRepeat(PlayerControl &pc, bool status)
-{
- if (status == queue.repeat)
- return;
-
- queue.repeat = status;
-
- pc.SetBorderPause(queue.single && !queue.repeat);
-
- /* if the last song is currently being played, the "next song"
- might change when repeat mode is toggled */
- UpdateQueuedSong(pc, GetQueuedSong());
-
- idle_add(IDLE_OPTIONS);
-}
-
-static void
-playlist_order(playlist &playlist)
-{
- if (playlist.current >= 0)
- /* update playlist.current, order==position now */
- playlist.current = playlist.queue.OrderToPosition(playlist.current);
-
- playlist.queue.RestoreOrder();
-}
-
-void
-playlist::SetSingle(PlayerControl &pc, bool status)
-{
- if (status == queue.single)
- return;
-
- queue.single = status;
-
- pc.SetBorderPause(queue.single && !queue.repeat);
-
- /* if the last song is currently being played, the "next song"
- might change when single mode is toggled */
- UpdateQueuedSong(pc, GetQueuedSong());
-
- idle_add(IDLE_OPTIONS);
-}
-
-void
-playlist::SetConsume(bool status)
-{
- if (status == queue.consume)
- return;
-
- queue.consume = status;
- idle_add(IDLE_OPTIONS);
-}
-
-void
-playlist::SetRandom(PlayerControl &pc, bool status)
-{
- if (status == queue.random)
- return;
-
- const Song *const queued_song = GetQueuedSong();
-
- queue.random = status;
-
- if (queue.random) {
- /* shuffle the queue order, but preserve current */
-
- const int current_position = playing
- ? GetCurrentPosition()
- : -1;
-
- queue.ShuffleOrder();
-
- 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.PositionToOrder(current_position);
- queue.SwapOrders(0, current_order);
- current = 0;
- } else
- current = -1;
- } else
- playlist_order(*this);
-
- UpdateQueuedSong(pc, queued_song);
-
- idle_add(IDLE_OPTIONS);
-}
-
-int
-playlist::GetCurrentPosition() const
-{
- return current >= 0
- ? queue.OrderToPosition(current)
- : -1;
-}
-
-int
-playlist::GetNextPosition() const
-{
- if (current < 0)
- return -1;
-
- if (queue.single && queue.repeat)
- return queue.OrderToPosition(current);
- else if (queue.IsValidOrder(current + 1))
- return queue.OrderToPosition(current + 1);
- else if (queue.repeat)
- return queue.OrderToPosition(0);
-
- return -1;
-}