- Fixed a bug in Transport where a "PlaybackStopped" event could be triggered erroneously

- Simplified TransportWindow to use PlaybackService.TrackChanged instead of manually querying the DB
This commit is contained in:
casey 2016-06-01 00:03:41 -07:00
parent 9f2a04bf78
commit 9c7fdbdb87
8 changed files with 57 additions and 61 deletions

View File

@ -262,18 +262,22 @@ void Transport::DeletePlayers(std::list<Player*> players) {
void Transport::OnPlaybackFinished(Player* player) {
this->RaiseStreamEvent(Transport::StreamFinished, player);
bool startedNext = false;
bool stopped = false;
{
boost::recursive_mutex::scoped_lock lock(this->stateMutex);
bool startedNext = false;
if (this->nextPlayer) {
this->StartWithPlayer(this->nextPlayer);
startedNext = true;
}
stopped = !startedNext && !this->active.size();
}
if (!startedNext) {
if (stopped) {
this->SetPlaybackState(Transport::PlaybackStopped);
}
@ -282,7 +286,17 @@ void Transport::OnPlaybackFinished(Player* player) {
void Transport::OnPlaybackStopped (Player* player) {
this->RaiseStreamEvent(Transport::StreamStopped, player);
this->SetPlaybackState(Transport::PlaybackStopped);
bool stopped = false;
{
boost::recursive_mutex::scoped_lock lock(this->stateMutex);
stopped = !this->active.size();
}
if (stopped) {
this->SetPlaybackState(Transport::PlaybackStopped);
}
DEFER(&Transport::RemoveActive, player);
}

View File

@ -69,7 +69,7 @@ void LibraryLayout::Layout() {
void LibraryLayout::InitializeWindows() {
this->categoryList.reset(new CategoryListView(this->library, DEFAULT_CATEGORY));
this->trackList.reset(new TrackListView(this->playback, this->library));
this->transportView.reset(new TransportWindow(this->library, this->transport));
this->transportView.reset(new TransportWindow(this->playback));
this->AddWindow(this->categoryList);
this->AddWindow(this->trackList);

View File

@ -20,6 +20,7 @@ using namespace musik::box;
#define URI_AT_INDEX(x) this->playlist.at(x)->URI()
#define PREVIOUS_GRACE_PERIOD 2.0f
#define MESSAGE_STREAM_EVENT 1000
#define MESSAGE_PLAYBACK_EVENT 1001
PlaybackService::PlaybackService(Transport& transport)
: transport(transport) {
@ -30,7 +31,7 @@ PlaybackService::PlaybackService(Transport& transport)
void PlaybackService::ProcessMessage(IMessage &message) {
if (message.Type() == MESSAGE_STREAM_EVENT) {
int eventType = message.UserData1();
int64 eventType = message.UserData1();
if (eventType == Transport::StreamAlmostDone) {
if (this->playlist.size() > this->index + 1) {
@ -49,6 +50,13 @@ void PlaybackService::ProcessMessage(IMessage &message) {
this->TrackChanged(this->index, this->playlist.at(this->index));
}
}
else if (message.Type() == MESSAGE_PLAYBACK_EVENT) {
int64 eventType = message.UserData1();
if (eventType == Transport::PlaybackStopped) {
this->TrackChanged(NO_POSITION, TrackPtr());
}
}
}
bool PlaybackService::Next() {
@ -107,3 +115,8 @@ void PlaybackService::OnStreamEvent(int eventType, std::string uri) {
cursespp::MessageQueue::Instance().Post(
cursespp::Message::Create(this, MESSAGE_STREAM_EVENT, eventType, 0));
}
void PlaybackService::OnPlaybackEvent(int eventType) {
cursespp::MessageQueue::Instance().Post(
cursespp::Message::Create(this, MESSAGE_PLAYBACK_EVENT, eventType, 0));
}

View File

@ -35,6 +35,7 @@ namespace musik {
private:
void OnStreamEvent(int eventType, std::string uri);
void OnPlaybackEvent(int eventType);
musik::core::audio::Transport& transport;
boost::recursive_mutex stateMutex;

View File

@ -18,7 +18,6 @@
#include <iomanip>
#define WINDOW_MESSAGE_QUERY_COMPLETED 1002
#define WINDOW_MESSAGE_REPAINT 1003
using namespace musik::core;
using namespace musik::core::audio;
@ -36,7 +35,6 @@ TrackListView::TrackListView(PlaybackService& playback, LibraryPtr library)
this->SetContentColor(BOX_COLOR_WHITE_ON_BLACK);
this->library = library;
this->library->QueryCompleted.connect(this, &TrackListView::OnQueryCompleted);
this->playback.GetTransport().PlaybackEvent.connect(this, &TrackListView::OnPlaybackEvent);
this->playback.TrackChanged.connect(this, &TrackListView::OnTrackChanged);
this->adapter = new Adapter(*this);
}
@ -78,21 +76,11 @@ void TrackListView::ProcessMessage(IMessage &message) {
this->OnAdapterChanged();
}
}
else if (message.Type() == WINDOW_MESSAGE_REPAINT) {
this->OnAdapterChanged();
}
}
void TrackListView::OnTrackChanged(size_t index, musik::core::TrackPtr track) {
this->playing = track;
this->PostMessage(WINDOW_MESSAGE_REPAINT);
}
void TrackListView::OnPlaybackEvent(int eventType) {
if (eventType == Transport::PlaybackStopped) {
this->playing.reset();
this->PostMessage(WINDOW_MESSAGE_REPAINT);
}
this->OnAdapterChanged();
}
IScrollAdapter& TrackListView::GetScrollAdapter() {

View File

@ -50,7 +50,6 @@ namespace musik {
private:
void OnTrackChanged(size_t index, musik::core::TrackPtr track);
void OnPlaybackEvent(int eventType);
std::shared_ptr<TrackListViewQuery> query;
std::shared_ptr<std::vector<musik::core::TrackPtr> > metadata;

View File

@ -8,20 +8,18 @@
#include <app/util/Text.h>
#include <core/debug.h>
#include <core/library/track/LibraryTrack.h>
#include <core/library/LocalLibraryConstants.h>
#include <core/playback/NonLibraryTrackHelper.h>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/chrono.hpp>
#include <boost/lexical_cast.hpp>
#include <algorithm>
using namespace musik::core;
using namespace musik::core::audio;
using namespace musik::core::library;
using namespace musik::core::query;
using namespace musik::core::db;
using namespace musik::box;
using namespace boost::chrono;
@ -34,16 +32,16 @@ using namespace cursespp;
this->RemoveMessage(REFRESH_TRANSPORT_READOUT); \
this->PostMessage(REFRESH_TRANSPORT_READOUT, 0, 0, x);
TransportWindow::TransportWindow(LibraryPtr library, Transport& transport)
: Window(NULL) {
TransportWindow::TransportWindow(musik::box::PlaybackService& playback)
: Window(NULL)
, playback(playback)
, transport(playback.GetTransport())
{
this->SetContentColor(BOX_COLOR_WHITE_ON_BLACK);
this->SetFrameVisible(false);
this->library = library;
this->library->QueryCompleted.connect(this, &TransportWindow::OnQueryCompleted);
this->transport = &transport;
this->transport->StreamEvent.connect(this, &TransportWindow::OnTransportStreamEvent);
this->transport->VolumeChanged.connect(this, &TransportWindow::OnTransportVolumeChanged);
this->transport->TimeChanged.connect(this, &TransportWindow::OnTransportTimeChanged);
this->playback.TrackChanged.connect(this, &TransportWindow::OnPlaybackServiceTrackChanged);
this->transport.VolumeChanged.connect(this, &TransportWindow::OnTransportVolumeChanged);
this->transport.TimeChanged.connect(this, &TransportWindow::OnTransportTimeChanged);
this->paused = this->focused = false;
}
@ -64,12 +62,9 @@ void TransportWindow::ProcessMessage(IMessage &message) {
}
}
void TransportWindow::OnTransportStreamEvent(int eventType, std::string url) {
if (eventType == Transport::StreamPlaying) {
this->trackQuery.reset(new SingleTrackQuery(url));
this->library->Enqueue(this->trackQuery);
DEBOUNCE_REFRESH(0);
}
void TransportWindow::OnPlaybackServiceTrackChanged(size_t index, TrackPtr track) {
this->currentTrack = track;
DEBOUNCE_REFRESH(0)
}
void TransportWindow::OnTransportVolumeChanged() {
@ -80,13 +75,6 @@ void TransportWindow::OnTransportTimeChanged(double time) {
DEBOUNCE_REFRESH(0)
}
void TransportWindow::OnQueryCompleted(QueryPtr query) {
if (query == this->trackQuery && query->GetStatus() == QueryBase::Finished) {
this->currentTrack = this->trackQuery->GetResult();
DEBOUNCE_REFRESH(0)
}
}
void TransportWindow::Focus() {
this->focused = true;
DEBOUNCE_REFRESH(0)
@ -101,7 +89,7 @@ void TransportWindow::Update() {
this->Clear();
WINDOW *c = this->GetContent();
bool paused = (transport->GetPlaybackState() == Transport::PlaybackPaused);
bool paused = (transport.GetPlaybackState() == Transport::PlaybackPaused);
int64 gb = COLOR_PAIR(this->focused
? BOX_COLOR_RED_ON_BLACK
@ -110,7 +98,7 @@ void TransportWindow::Update() {
/* playing SONG TITLE from ALBUM NAME */
std::string duration = "0";
if (transport->GetPlaybackState() == Transport::PlaybackStopped) {
if (transport.GetPlaybackState() == Transport::PlaybackStopped) {
wattron(c, gb);
wprintw(c, "playback is stopped");
wattroff(c, gb);
@ -145,7 +133,7 @@ void TransportWindow::Update() {
wprintw(c, "\n");
int volumePercent = (size_t) round(this->transport->Volume() * 100.0f) - 1;
int volumePercent = (size_t) round(this->transport.Volume() * 100.0f) - 1;
int thumbOffset = std::min(9, (volumePercent * 10) / 100);
std::string volume = "vol ";
@ -171,9 +159,9 @@ void TransportWindow::Update() {
}
}
transport->Position();
transport.Position();
int secondsCurrent = (int) round(transport->Position());
int secondsCurrent = (int) round(transport.Position());
int secondsTotal = boost::lexical_cast<int>(duration);
std::string currentTime = text::Duration(secondsCurrent);

View File

@ -1,10 +1,8 @@
#pragma once
#include <cursespp/Window.h>
#include <core/playback/Transport.h>
#include <core/library/track/Track.h>
#include <core/library/ILibrary.h>
#include <app/query/SingleTrackQuery.h>
#include <app/service/PlaybackService.h>
#include <sigslot/sigslot.h>
#include "OutputWindow.h"
@ -18,11 +16,8 @@ namespace musik {
public sigslot::has_slots<>
{
public:
TransportWindow(
musik::core::LibraryPtr library,
musik::core::audio::Transport& transport);
~TransportWindow();
TransportWindow(musik::box::PlaybackService& playback);
virtual ~TransportWindow();
virtual void ProcessMessage(cursespp::IMessage &message);
@ -33,16 +28,14 @@ namespace musik {
void Update();
private:
void OnTransportStreamEvent(int eventType, std::string url);
void OnPlaybackServiceTrackChanged(size_t index, musik::core::TrackPtr track);
void OnTransportVolumeChanged();
void OnTransportTimeChanged(double time);
void OnQueryCompleted(musik::core::QueryPtr query);
bool paused, focused;
musik::core::LibraryPtr library;
musik::core::audio::Transport* transport;
musik::core::audio::Transport& transport;
musik::box::PlaybackService& playback;
musik::core::TrackPtr currentTrack;
std::shared_ptr<SingleTrackQuery> trackQuery;
};
}
}