Bug Summary

File:player/player.cpp
Location:line 93, column 3
Description:This statement is never executed

Annotated Source Code

1// This file is part of Playslave-C++.
2// Playslave-C++ is licenced under the MIT license: see LICENSE.txt.
3
4/**
5 * @file player/player.cpp
6 * Main implementation file for the Player class.
7 * @see player/player.hpp
8 * @see player/player_position.cpp
9 * @see player/player_state.cpp
10 */
11
12#include <cassert>
13#include <sstream>
14#include <stdexcept>
15#include <string>
16
17#include "../audio/audio_system.hpp"
18#include "../audio/audio.hpp"
19#include "../errors.hpp"
20#include "../io/io_response.hpp"
21#include "../messages.h"
22#include "player_state.hpp"
23#include "player.hpp"
24
25Player::Player(const AudioSystem &audio_system, const Player::TP &time_parser)
26 : file(audio_system),
27 position(),
28 state(),
29 time_parser(time_parser),
30 end_sink(nullptr)
31{
32}
33
34bool Player::Update()
35{
36 if (CurrentStateIn(PlayerState::AUDIO_PLAYING_STATES)) {
37 PlaybackUpdate();
38 }
39 if (CurrentStateIn(PlayerState::AUDIO_LOADED_STATES)) {
40 this->file.Update();
41 }
42 return IsRunning();
43}
44
45void Player::PlaybackUpdate()
46{
47 if (this->file.IsStopped()) {
48 if (this->end_sink != nullptr) {
49 this->end_sink->Respond(ResponseCode::END, "");
50 }
51 Stop();
52 Seek("0");
53 } else {
54 UpdatePosition();
55 }
56}
57
58void Player::WelcomeClient(ResponseSink &client) const
59{
60 client.Respond(ResponseCode::OHAI, MSG_OHAI);
61 client.Respond(ResponseCode::FEATURES, MSG_FEATURES);
62 this->file.Emit(client);
63 this->position.Emit(client);
64 this->state.Emit(client);
65}
66
67void Player::SetResponseSink(ResponseSink &sink)
68{
69 this->file.SetResponseSink(sink);
70 this->position.SetResponseSink(sink);
71 this->state.SetResponseSink(sink);
72 this->end_sink = &sink;
73}
74
75//
76// Commands
77//
78
79bool Player::Eject()
80{
81 if (CurrentStateIn(PlayerState::AUDIO_LOADED_STATES)) {
82 this->file.Eject();
83 SetState(PlayerState::State::EJECTED);
84 return true;
85 }
86 return false;
87}
88
89bool Player::Load(const std::string &path)
90{
91 bool valid = !path.empty();
92 if (valid) {
93 try
This statement is never executed
94 {
95 this->file.Load(path);
96 ResetPosition();
97 Debug() << "Loaded " << path << std::endl;
98 SetState(PlayerState::State::STOPPED);
99 }
100 catch (FileError &)
101 {
102 // File errors aren't fatal, so catch them here.
103 Eject();
104 valid = false;
105 }
106 catch (Error &)
107 {
108 // Ensure a load failure doesn't leave a corrupted track
109 // loaded.
110 Eject();
111 throw;
112 }
113 }
114 return valid;
115}
116
117bool Player::Play()
118{
119 if (CurrentStateIn({ PlayerState::State::STOPPED })) {
120 this->file.Start();
121 SetState(PlayerState::State::PLAYING);
122 return true;
123 }
124 return false;
125}
126
127bool Player::Quit()
128{
129 Eject();
130 SetState(PlayerState::State::QUITTING);
131
132 return true; // Always a valid command.
133}
134
135bool Player::Seek(const std::string &time_str)
136{
137 if (CurrentStateIn(PlayerState::AUDIO_LOADED_STATES)) {
138 bool success = true;
139 std::chrono::microseconds position(0);
140
141 try
142 {
143 position = this->time_parser.Parse(time_str);
144 }
145 catch (std::out_of_range)
146 {
147 success = false;
148 }
149
150 if (success) {
151 this->file.SeekToPosition(position);
152 this->ResetPosition();
153 this->UpdatePosition();
154 }
155 return success;
156 }
157 return false;
158}
159
160bool Player::Stop()
161{
162 if (CurrentStateIn(PlayerState::AUDIO_PLAYING_STATES)) {
163 this->file.Stop();
164 SetState(PlayerState::State::STOPPED);
165 return true;
166 }
167 return false;
168}