From 820ab942182950f047599a5ed811df6102f25a4a Mon Sep 17 00:00:00 2001 From: casey Date: Sat, 25 Jun 2016 10:42:36 -0700 Subject: [PATCH] Added support for repeat modes (none, track, list) in PlaybackService. Also found some potential race conditions and patched them up. --- src/musikbox/app/service/PlaybackService.cpp | 72 ++++++++++++++++---- src/musikbox/app/service/PlaybackService.h | 15 +++- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/musikbox/app/service/PlaybackService.cpp b/src/musikbox/app/service/PlaybackService.cpp index f2cdbfb36..345add4ea 100755 --- a/src/musikbox/app/service/PlaybackService.cpp +++ b/src/musikbox/app/service/PlaybackService.cpp @@ -56,11 +56,17 @@ using namespace musik::box; #define PREVIOUS_GRACE_PERIOD 2.0f #define MESSAGE_STREAM_EVENT 1000 #define MESSAGE_PLAYBACK_EVENT 1001 +#define MESSAGE_PREPARE_NEXT_TRACK 1002 + +#define POST(instance, type, user1, user2) \ + cursespp::MessageQueue::Instance().Post( \ + cursespp::Message::Create(instance, type, user1, user2)); PlaybackService::PlaybackService(LibraryPtr library, ITransport& transport) : library(library) , transport(transport) -, playlist(library) { +, playlist(library) +, repeatMode(RepeatNone) { transport.StreamEvent.connect(this, &PlaybackService::OnStreamEvent); transport.PlaybackEvent.connect(this, &PlaybackService::OnPlaybackEvent); this->index = NO_POSITION; @@ -68,11 +74,34 @@ PlaybackService::PlaybackService(LibraryPtr library, ITransport& transport) } void PlaybackService::PrepareNextTrack() { - if (this->playlist.Count() > this->index + 1) { - if (this->nextIndex != this->index + 1) { - this->nextIndex = this->index + 1; - this->transport.PrepareNextTrack(URI_AT_INDEX(nextIndex)); + boost::recursive_mutex::scoped_lock lock(this->playlistMutex); + + /* repeat track, just keep playing the same thing over and over */ + if (this->repeatMode == RepeatTrack) { + this->transport.PrepareNextTrack(URI_AT_INDEX(this->index)); + } + else { + /* normal case, just move forward */ + if (this->playlist.Count() > this->index + 1) { + if (this->nextIndex != this->index + 1) { + this->nextIndex = this->index + 1; + this->transport.PrepareNextTrack(URI_AT_INDEX(nextIndex)); + } } + /* repeat list case, wrap around to the beginning if necessary */ + else if (this->repeatMode == RepeatList) { + if (this->nextIndex != 0) { + this->nextIndex = 0; + this->transport.PrepareNextTrack(URI_AT_INDEX(nextIndex)); + } + } + } +} + +void PlaybackService::SetRepeatMode(RepeatMode mode) { + if (this->repeatMode != mode) { + this->repeatMode = mode; + POST(this, MESSAGE_PREPARE_NEXT_TRACK, 0, 0); } } @@ -87,7 +116,14 @@ void PlaybackService::ProcessMessage(IMessage &message) { } if (this->index != NO_POSITION) { - this->TrackChanged(this->index, this->playlist.Get(this->index)); + TrackPtr track; + + { + boost::recursive_mutex::scoped_lock lock(this->playlistMutex); + track = this->playlist.Get(this->index); + } + + this->TrackChanged(this->index, track); } this->PrepareNextTrack(); @@ -100,6 +136,9 @@ void PlaybackService::ProcessMessage(IMessage &message) { this->TrackChanged(NO_POSITION, TrackPtr()); } } + else if (message.Type() == MESSAGE_PREPARE_NEXT_TRACK) { + this->PrepareNextTrack(); + } } bool PlaybackService::Next() { @@ -107,10 +146,16 @@ bool PlaybackService::Next() { return false; } + boost::recursive_mutex::scoped_lock lock(this->playlistMutex); + if (this->playlist.Count() > index + 1) { this->Play(index + 1); return true; } + else if (this->repeatMode == RepeatList) { + this->Play(0); /* wrap around */ + return true; + } return false; } @@ -129,6 +174,10 @@ bool PlaybackService::Previous() { this->Play(index - 1); return true; } + else if (this->repeatMode == RepeatList) { + this->Play(this->Count() - 1); /* wrap around */ + return true; + } return false; } @@ -139,7 +188,7 @@ void PlaybackService::Play(TrackList& tracks, size_t index) { temp.CopyFrom(tracks); { - boost::recursive_mutex::scoped_lock lock(this->stateMutex); + boost::recursive_mutex::scoped_lock lock(this->playlistMutex); this->playlist.Swap(temp); } @@ -149,7 +198,7 @@ void PlaybackService::Play(TrackList& tracks, size_t index) { } void PlaybackService::CopyTo(TrackList& target) { - boost::recursive_mutex::scoped_lock lock(this->stateMutex); + boost::recursive_mutex::scoped_lock lock(this->playlistMutex); target.CopyFrom(this->playlist); } @@ -164,15 +213,14 @@ size_t PlaybackService::GetIndex() { } TrackPtr PlaybackService::GetTrackAtIndex(size_t index) { + boost::recursive_mutex::scoped_lock lock(this->playlistMutex); return this->playlist.Get(index); } void PlaybackService::OnStreamEvent(int eventType, std::string uri) { - cursespp::MessageQueue::Instance().Post( - cursespp::Message::Create(this, MESSAGE_STREAM_EVENT, eventType, 0)); + POST(this, MESSAGE_STREAM_EVENT, eventType, 0); } void PlaybackService::OnPlaybackEvent(int eventType) { - cursespp::MessageQueue::Instance().Post( - cursespp::Message::Create(this, MESSAGE_PLAYBACK_EVENT, eventType, 0)); + POST(this, MESSAGE_PLAYBACK_EVENT, eventType, 0); } diff --git a/src/musikbox/app/service/PlaybackService.h b/src/musikbox/app/service/PlaybackService.h index 9af685536..7d9500e5f 100755 --- a/src/musikbox/app/service/PlaybackService.h +++ b/src/musikbox/app/service/PlaybackService.h @@ -52,6 +52,12 @@ namespace musik { public: sigslot::signal2 TrackChanged; + enum RepeatMode { + RepeatNone, + RepeatTrack, + RepeatList + }; + PlaybackService( musik::core::LibraryPtr library, musik::core::audio::ITransport& transport); @@ -69,6 +75,9 @@ namespace musik { void CopyTo(TrackList& target); + RepeatMode GetRepeatMode() { return this->repeatMode; } + void SetRepeatMode(RepeatMode mode); + musik::core::TrackPtr GetTrackAtIndex(size_t index); size_t GetIndex(); @@ -79,11 +88,13 @@ namespace musik { void OnPlaybackEvent(int eventType); void PrepareNextTrack(); + TrackList playlist; + boost::recursive_mutex playlistMutex; + musik::core::LibraryPtr library; musik::core::audio::ITransport& transport; - TrackList playlist; size_t index, nextIndex; - boost::recursive_mutex stateMutex; + RepeatMode repeatMode; }; } }