From 445e82be759c28aae97594f447fba4007e26a4e3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 9 Nov 2016 12:31:23 +0100 Subject: [PATCH] output/Multiple: migrate from class Error to C++ exceptions --- src/output/MultipleOutputs.cxx | 44 +++++++++--------------- src/output/MultipleOutputs.hxx | 12 +++---- src/player/Thread.cxx | 61 +++++++++++++++++----------------- 3 files changed, 53 insertions(+), 64 deletions(-) diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx index 4251d8237..0d4e7c61e 100644 --- a/src/output/MultipleOutputs.cxx +++ b/src/output/MultipleOutputs.cxx @@ -58,14 +58,8 @@ try { AudioOutput *output = audio_output_new(event_loop, block, mixer_listener, pc, error); - if (output == nullptr) { - if (block.line > 0) - FormatFatalError("line %i: %s", - block.line, - error.GetMessage()); - else - FatalError(error); - } + if (output == nullptr) + throw std::runtime_error(error.GetMessage()); return output; } catch (const std::runtime_error &e) { @@ -192,32 +186,27 @@ MultipleOutputs::SetReplayGainMode(ReplayGainMode mode) ao->SetReplayGainMode(mode); } -bool -MultipleOutputs::Play(MusicChunk *chunk, Error &error) +void +MultipleOutputs::Play(MusicChunk *chunk) { assert(buffer != nullptr); assert(pipe != nullptr); assert(chunk != nullptr); assert(chunk->CheckFormat(input_audio_format)); - if (!Update()) { + if (!Update()) /* TODO: obtain real error */ - error.Set(output_domain, "Failed to open audio output"); - return false; - } + throw std::runtime_error("Failed to open audio output"); pipe->Push(chunk); for (auto ao : outputs) ao->LockPlay(); - - return true; } -bool +void MultipleOutputs::Open(const AudioFormat audio_format, - MusicBuffer &_buffer, - Error &error) + MusicBuffer &_buffer) { bool ret = false, enabled = false; @@ -251,17 +240,16 @@ MultipleOutputs::Open(const AudioFormat audio_format, ret = true; } - if (!enabled) - error.Set(output_domain, "All audio outputs are disabled"); - else if (!ret) - /* TODO: obtain real error */ - error.Set(output_domain, "Failed to open audio output"); - - if (!ret) + if (!enabled) { /* close all devices if there was an error */ Close(); - - return ret; + throw std::runtime_error("All audio outputs are disabled"); + } else if (!ret) { + /* close all devices if there was an error */ + Close(); + /* TODO: obtain real error */ + throw std::runtime_error("Failed to open audio output"); + } } /** diff --git a/src/output/MultipleOutputs.hxx b/src/output/MultipleOutputs.hxx index b0d838a5b..538c86e1b 100644 --- a/src/output/MultipleOutputs.hxx +++ b/src/output/MultipleOutputs.hxx @@ -118,13 +118,13 @@ public: /** * Opens all audio outputs which are not disabled. * + * Throws #std::runtime_error on error. + * * @param audio_format the preferred audio format * @param _buffer the #music_buffer where consumed #MusicChunk objects * should be returned - * @return true on success, false on failure */ - bool Open(const AudioFormat audio_format, MusicBuffer &_buffer, - Error &error); + void Open(const AudioFormat audio_format, MusicBuffer &_buffer); /** * Closes all audio outputs. @@ -143,11 +143,11 @@ public: * Enqueue a #MusicChunk object for playing, i.e. pushes it to a * #MusicPipe. * + * Throws #std::runtime_error on error (all closed then). + * * @param chunk the #MusicChunk object to be played - * @return true on success, false if no audio output was able to play - * (all closed then) */ - bool Play(MusicChunk *chunk, Error &error); + void Play(MusicChunk *chunk); /** * Checks if the output devices have drained their music pipe, and diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 9acc091a3..42f3d8d4e 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -37,6 +37,8 @@ #include "thread/Name.hxx" #include "Log.hxx" +#include + #include static constexpr Domain player_domain("player"); @@ -443,20 +445,10 @@ Player::OpenOutput() assert(pc.state == PlayerState::PLAY || pc.state == PlayerState::PAUSE); - Error error; - if (pc.outputs.Open(play_audio_format, buffer, error)) { - output_open = true; - paused = false; - - pc.Lock(); - pc.state = PlayerState::PLAY; - pc.Unlock(); - - idle_add(IDLE_PLAYER); - - return true; - } else { - LogError(error); + try { + pc.outputs.Open(play_audio_format, buffer); + } catch (const std::runtime_error &e) { + LogError(e); output_open = false; @@ -465,7 +457,7 @@ Player::OpenOutput() paused = true; pc.Lock(); - pc.SetError(PlayerError::OUTPUT, std::move(error)); + pc.SetError(PlayerError::OUTPUT, std::current_exception()); pc.state = PlayerState::PAUSE; pc.Unlock(); @@ -473,6 +465,17 @@ Player::OpenOutput() return false; } + + output_open = true; + paused = false; + + pc.Lock(); + pc.state = PlayerState::PLAY; + pc.Unlock(); + + idle_add(IDLE_PLAYER); + + return true; } bool @@ -556,9 +559,10 @@ Player::SendSilence() chunk->length = num_frames * frame_size; PcmSilence({chunk->data, chunk->length}, play_audio_format.format); - Error error; - if (!pc.outputs.Play(chunk, error)) { - LogError(error); + try { + pc.outputs.Play(chunk); + } catch (const std::runtime_error &e) { + LogError(e); buffer.Return(chunk); return false; } @@ -770,12 +774,11 @@ update_song_tag(PlayerControl &pc, DetachedSong &song, const Tag &new_tag) * * Player lock is not held. */ -static bool +static void play_chunk(PlayerControl &pc, DetachedSong &song, MusicChunk *chunk, MusicBuffer &buffer, - const AudioFormat format, - Error &error) + const AudioFormat format) { assert(chunk->CheckFormat(format)); @@ -784,7 +787,7 @@ play_chunk(PlayerControl &pc, if (chunk->IsEmpty()) { buffer.Return(chunk); - return true; + return; } pc.Lock(); @@ -793,12 +796,9 @@ play_chunk(PlayerControl &pc, /* send the chunk to the audio outputs */ - if (!pc.outputs.Play(chunk, error)) - return false; - + pc.outputs.Play(chunk); pc.total_play_time += (double)chunk->length / format.GetTimeToSize(); - return true; } inline bool @@ -899,15 +899,16 @@ Player::PlayNextChunk() /* play the current chunk */ - Error error; - if (!play_chunk(pc, *song, chunk, buffer, play_audio_format, error)) { - LogError(error); + try { + play_chunk(pc, *song, chunk, buffer, play_audio_format); + } catch (const std::runtime_error &e) { + LogError(e); buffer.Return(chunk); pc.Lock(); - pc.SetError(PlayerError::OUTPUT, std::move(error)); + pc.SetError(PlayerError::OUTPUT, std::current_exception()); /* pause: the user may resume playback as soon as an audio output becomes available */