player/Control: Play*() returns Error information

This commit is contained in:
Max Kellermann 2015-11-11 19:57:37 +01:00
parent 2065e32904
commit fb547260d1
9 changed files with 82 additions and 54 deletions

View File

@ -123,20 +123,20 @@ struct Partition final : private PlayerListener, private MixerListener {
playlist.Stop(pc);
}
void PlayPosition(int position) {
playlist.PlayPosition(pc, position);
bool PlayPosition(int position, Error &error) {
return playlist.PlayPosition(pc, position, error);
}
void PlayId(int id) {
playlist.PlayId(pc, id);
bool PlayId(int id, Error &error) {
return playlist.PlayId(pc, id, error);
}
void PlayNext() {
playlist.PlayNext(pc);
bool PlayNext(Error &error) {
return playlist.PlayNext(pc, error);
}
void PlayPrevious() {
playlist.PlayPrevious(pc);
bool PlayPrevious(Error &error) {
return playlist.PlayPrevious(pc, error);
}
bool SeekSongPosition(unsigned song_position,

View File

@ -60,16 +60,22 @@ CommandResult
handle_play(Client &client, Request args, gcc_unused Response &r)
{
int song = args.ParseOptional(0, -1);
client.partition.PlayPosition(song);
return CommandResult::OK;
Error error;
return client.partition.PlayPosition(song, error)
? CommandResult::OK
: print_error(r, error);
}
CommandResult
handle_playid(Client &client, Request args, gcc_unused Response &r)
{
int id = args.ParseOptional(0, -1);
client.partition.PlayId(id);
return CommandResult::OK;
Error error;
return client.partition.PlayId(id, error)
? CommandResult::OK
: print_error(r, error);
}
CommandResult
@ -212,18 +218,24 @@ handle_next(Client &client, gcc_unused Request args, gcc_unused Response &r)
const bool single = playlist.queue.single;
playlist.queue.single = false;
client.partition.PlayNext();
Error error;
bool success = client.partition.PlayNext(error);
playlist.queue.single = single;
return CommandResult::OK;
return success
? CommandResult::OK
: print_error(r, error);
}
CommandResult
handle_previous(Client &client, gcc_unused Request args,
gcc_unused Response &r)
{
client.partition.PlayPrevious();
return CommandResult::OK;
Error error;
return client.partition.PlayPrevious(error)
? CommandResult::OK
: print_error(r, error);
}
CommandResult

View File

@ -49,18 +49,20 @@ PlayerControl::~PlayerControl()
delete tagged_song;
}
void
PlayerControl::Play(DetachedSong *song)
bool
PlayerControl::Play(DetachedSong *song, Error &error_r)
{
assert(song != nullptr);
const ScopeLock protect(mutex);
SeekLocked(song, SongTime::zero(), IgnoreError());
bool success = SeekLocked(song, SongTime::zero(), error_r);
if (state == PlayerState::PAUSE)
if (success && state == PlayerState::PAUSE)
/* if the player was paused previously, we need to
unpause it */
PauseLocked();
return success;
}
void

View File

@ -311,7 +311,7 @@ public:
* @param song the song to be queued; the given instance will
* be owned and freed by the player
*/
void Play(DetachedSong *song);
bool Play(DetachedSong *song, Error &error);
/**
* see PlayerCommand::CANCEL

View File

@ -152,8 +152,8 @@ playlist::UpdateQueuedSong(PlayerControl &pc, const DetachedSong *prev)
}
}
void
playlist::PlayOrder(PlayerControl &pc, int order)
bool
playlist::PlayOrder(PlayerControl &pc, int order, Error &error)
{
playing = true;
queued = -1;
@ -162,10 +162,14 @@ playlist::PlayOrder(PlayerControl &pc, int order)
FormatDebug(playlist_domain, "play %i:\"%s\"", order, song.GetURI());
pc.Play(new DetachedSong(song));
current = order;
if (!pc.Play(new DetachedSong(song), error))
return false;
SongStarted();
return true;
}
void
@ -224,7 +228,8 @@ playlist::ResumePlayback(PlayerControl &pc)
Stop(pc);
else
/* continue playback at the next song */
PlayNext(pc);
/* TODO: log error? */
PlayNext(pc, IgnoreError());
}
void

View File

@ -262,15 +262,15 @@ public:
void Stop(PlayerControl &pc);
void PlayPosition(PlayerControl &pc, int position);
bool PlayPosition(PlayerControl &pc, int position, Error &error);
void PlayOrder(PlayerControl &pc, int order);
bool PlayOrder(PlayerControl &pc, int order, Error &error);
void PlayId(PlayerControl &pc, int id);
bool PlayId(PlayerControl &pc, int id, Error &error);
void PlayNext(PlayerControl &pc);
bool PlayNext(PlayerControl &pc, Error &error);
void PlayPrevious(PlayerControl &pc);
bool PlayPrevious(PlayerControl &pc, Error &error);
bool SeekSongOrder(PlayerControl &pc,
unsigned song_order,

View File

@ -56,8 +56,8 @@ playlist::Stop(PlayerControl &pc)
}
}
void
playlist::PlayPosition(PlayerControl &pc, int song)
bool
playlist::PlayPosition(PlayerControl &pc, int song, Error &error)
{
pc.LockClearError();
@ -66,13 +66,13 @@ playlist::PlayPosition(PlayerControl &pc, int song)
/* play any song ("current" song, or the first song */
if (queue.IsEmpty())
return;
return true;
if (playing) {
/* already playing: unpause playback, just in
case it was paused, and return */
pc.LockSetPause(false);
return;
return true;
}
/* select a song: "current" song, or the first one */
@ -102,29 +102,30 @@ playlist::PlayPosition(PlayerControl &pc, int song)
stop_on_error = false;
error_count = 0;
PlayOrder(pc, i);
return PlayOrder(pc, i, error);
}
void
playlist::PlayId(PlayerControl &pc, int id)
bool
playlist::PlayId(PlayerControl &pc, int id, Error &error)
{
if (id == -1) {
PlayPosition(pc, id);
return;
}
if (id == -1)
return PlayPosition(pc, id, error);
int song = queue.IdToPosition(id);
if (song < 0)
throw PlaylistError::NoSuchSong();
return PlayPosition(pc, song);
return PlayPosition(pc, song, error);
}
void
playlist::PlayNext(PlayerControl &pc)
bool
playlist::PlayNext(PlayerControl &pc, Error &error)
{
if (!playing)
return;
if (!playing) {
error.Set(playlist_domain, int(PlaylistResult::NOT_PLAYING),
"Not playing");
return true;
}
assert(!queue.IsEmpty());
assert(queue.IsValidOrder(current));
@ -158,19 +159,25 @@ playlist::PlayNext(PlayerControl &pc)
discard them anyway */
}
PlayOrder(pc, next_order);
if (!PlayOrder(pc, next_order, error))
return false;
}
/* Consume mode removes each played songs. */
if (queue.consume)
DeleteOrder(pc, old_current);
return true;
}
void
playlist::PlayPrevious(PlayerControl &pc)
bool
playlist::PlayPrevious(PlayerControl &pc, Error &error)
{
if (!playing)
return;
if (!playing) {
error.Set(playlist_domain, int(PlaylistResult::NOT_PLAYING),
"Not playing");
return true;
}
assert(!queue.IsEmpty());
@ -187,7 +194,7 @@ playlist::PlayPrevious(PlayerControl &pc)
order = current;
}
PlayOrder(pc, order);
return PlayOrder(pc, order, error);
}
bool

View File

@ -239,7 +239,8 @@ playlist::DeleteInternal(PlayerControl &pc,
if (current >= 0 && !paused)
/* play the song after the deleted one */
PlayOrder(pc, current);
/* TODO: log error? */
PlayOrder(pc, current, IgnoreError());
else {
/* stop the player */

View File

@ -196,7 +196,8 @@ playlist_state_restore(const char *line, TextFile &file,
if (state == PlayerState::STOP /* && config_option */)
playlist.current = current;
else if (seek_time.count() == 0)
playlist.PlayPosition(pc, current);
/* TODO: log error? */
playlist.PlayPosition(pc, current, IgnoreError());
else
playlist.SeekSongPosition(pc, current, seek_time,
IgnoreError());