Fixed: Protected MultiLibraryList with mutex.

Fixed: Behavior of transport, PlaybackQueue and the TransportView/Controller.
This commit is contained in:
Daniel Önnerby 2009-01-13 15:37:30 +00:00
parent a6ba49b423
commit 94530ec9a4
7 changed files with 142 additions and 86 deletions

View File

@ -113,6 +113,11 @@ void PlaybackQueue::Play(){
// if( !this->nowPlaying->Library()->Exited() ){
TrackPtr track(this->CurrentTrack());
if(!track){
this->nowPlaying->SetPosition(0);
track = this->CurrentTrack();
}
this->Stop();
if(track){
@ -159,7 +164,14 @@ void PlaybackQueue::Next(){
musik::core::TrackPtr track( this->nowPlaying->NextTrack() );
this->SetCurrentTrack(track);
this->Play();
this->Stop();
if(track=this->CurrentTrack()){
this->playing = true;
this->transport.Start(track->URL());
this->paused = false;
}
}
//////////////////////////////////////////
@ -212,6 +224,10 @@ TrackPtr PlaybackQueue::CurrentTrack(){
//////////////////////////////////////////
void PlaybackQueue::SetCurrentTrack(TrackPtr track){
if(!this->currentTrack && !track){
return;
}
if(track){
this->currentTrack = track->Copy();
}else{

View File

@ -67,8 +67,9 @@ MultiLibraryList::MultiLibraryList()
///shared pointer to track (could be a null pointer)
//////////////////////////////////////////
musik::core::TrackPtr MultiLibraryList::operator [](long position){
boost::mutex::scoped_lock lock(this->mutex);
// Valid position?
if(position>=0 && position<this->Size()){
if(position>=0 && position<this->tracklist.size()){
return this->tracklist[position];
}
return musik::core::TrackPtr();
@ -92,11 +93,14 @@ musik::core::TrackPtr MultiLibraryList::operator [](long position){
///TrackMetadataUpdated
//////////////////////////////////////////
musik::core::TrackPtr MultiLibraryList::TrackWithMetadata(long position){
{
boost::mutex::scoped_lock lock(this->mutex);
// check the positionCache if the track is in the cache already
PositionCacheMap::iterator trackPosition = this->positionCache.find(position);
if(trackPosition!=this->positionCache.end()){
return trackPosition->second;
// check the positionCache if the track is in the cache already
PositionCacheMap::iterator trackPosition = this->positionCache.find(position);
if(trackPosition!=this->positionCache.end()){
return trackPosition->second;
}
}
// Load and add to cache
@ -110,10 +114,6 @@ musik::core::TrackPtr MultiLibraryList::TrackWithMetadata(long position){
///Get the current track
//////////////////////////////////////////
musik::core::TrackPtr MultiLibraryList::CurrentTrack(){
/* if(this->currentPosition==-1 && this->Size()>0){
this->SetPosition(0);
}
*/
return (*this)[this->currentPosition];
}
@ -122,11 +122,13 @@ musik::core::TrackPtr MultiLibraryList::CurrentTrack(){
///Get the next track and increase the position.
//////////////////////////////////////////
musik::core::TrackPtr MultiLibraryList::NextTrack(){
long newPosition = this->currentPosition+1;
long newPosition;
{
boost::mutex::scoped_lock lock(this->mutex);
newPosition = this->currentPosition+1;
}
musik::core::TrackPtr nextTrack = (*this)[newPosition];
// if(nextTrack){
this->SetPosition(newPosition);
// }
this->SetPosition(newPosition);
return nextTrack;
}
@ -135,11 +137,13 @@ musik::core::TrackPtr MultiLibraryList::NextTrack(){
///Get the previous track and decrease the position.
//////////////////////////////////////////
musik::core::TrackPtr MultiLibraryList::PreviousTrack(){
long newPosition = this->currentPosition-1;
long newPosition;
{
boost::mutex::scoped_lock lock(this->mutex);
newPosition = this->currentPosition-1;
}
musik::core::TrackPtr nextTrack = (*this)[newPosition];
// if(nextTrack){
this->SetPosition(newPosition);
// }
this->SetPosition(newPosition);
return nextTrack;
}
@ -155,9 +159,12 @@ musik::core::TrackPtr MultiLibraryList::PreviousTrack(){
///True if position is a valid one and successfully set.
//////////////////////////////////////////
bool MultiLibraryList::SetPosition(long position){
if(position>=-1 && position<=this->tracklist.size()){
if(position>=-1 && position<=this->Size()){
this->PositionChanged(position,this->currentPosition);
this->currentPosition = position;
{
boost::mutex::scoped_lock lock(this->mutex);
this->currentPosition = position;
}
return true;
}
@ -169,6 +176,7 @@ bool MultiLibraryList::SetPosition(long position){
///Get the current position. -1 if undefined.
//////////////////////////////////////////
long MultiLibraryList::CurrentPosition(){
boost::mutex::scoped_lock lock(this->mutex);
return this->currentPosition;
}
@ -177,6 +185,7 @@ long MultiLibraryList::CurrentPosition(){
///Get current size of the tracklist. -1 if unknown.
//////////////////////////////////////////
long MultiLibraryList::Size(){
boost::mutex::scoped_lock lock(this->mutex);
return (long)this->tracklist.size();
}
@ -185,14 +194,20 @@ long MultiLibraryList::Size(){
///Clear the tracklist
//////////////////////////////////////////
void MultiLibraryList::Clear(){
this->tracklist.clear();
long oldPosition;
{
boost::mutex::scoped_lock lock(this->mutex);
this->tracklist.clear();
oldPosition = this->currentPosition;
this->currentPosition = -1;
}
this->ClearMetadata();
this->TracklistChanged(true);
this->PositionChanged(-1,this->currentPosition);
this->currentPosition = -1;
this->PositionChanged(-1,oldPosition);
}
void MultiLibraryList::ClearMetadata(){
boost::mutex::scoped_lock lock(this->mutex);
this->positionCache.clear();
this->trackCache.clear();
}
@ -216,12 +231,17 @@ bool MultiLibraryList::operator =(musik::core::tracklist::Base &tracklist){
if(&tracklist != this){
this->Clear();
this->tracklist.reserve(tracklist.Size());
{
boost::mutex::scoped_lock lock(this->mutex);
// Loop through the tracks and copy everything
for(long i(0);i<tracklist.Size();++i){
this->tracklist.push_back(tracklist[i]->Copy());
this->tracklist.reserve(tracklist.Size());
// Loop through the tracks and copy everything
for(long i(0);i<tracklist.Size();++i){
this->tracklist.push_back(tracklist[i]->Copy());
}
}
this->TracklistChanged(true);
this->SetPosition(tracklist.CurrentPosition());
}
@ -242,11 +262,14 @@ bool MultiLibraryList::operator +=(musik::core::tracklist::Base &tracklist){
this->inited = true;
}
this->tracklist.reserve(tracklist.Size()+this->Size());
{
boost::mutex::scoped_lock lock(this->mutex);
this->tracklist.reserve(tracklist.Size()+this->tracklist.size());
// Loop through the tracks and copy everything
for(long i(0);i<tracklist.Size();++i){
this->tracklist.push_back(tracklist[i]->Copy());
// Loop through the tracks and copy everything
for(long i(0);i<tracklist.Size();++i){
this->tracklist.push_back(tracklist[i]->Copy());
}
}
this->TracklistChanged(false);
@ -270,7 +293,10 @@ bool MultiLibraryList::operator +=(musik::core::TrackPtr track){
this->inited = true;
}
this->tracklist.push_back(track->Copy());
{
boost::mutex::scoped_lock lock(this->mutex);
this->tracklist.push_back(track->Copy());
}
this->TracklistChanged(false);
@ -319,6 +345,7 @@ void MultiLibraryList::LoadTrack(long position){
///Request metadata for track
//////////////////////////////////////////
bool MultiLibraryList::QueryForTrack(long position){
PositionCacheMap::iterator trackIt=this->positionCache.find(position);
if(trackIt==this->positionCache.end()){
// Not in cache, lets find the track
@ -339,10 +366,13 @@ bool MultiLibraryList::QueryForTrack(long position){
void MultiLibraryList::OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks){
std::vector<long> updateTrackPositions;
for(musik::core::TrackVector::iterator track=metaTracks->begin();track!=metaTracks->end();++track){
TrackCacheMap::iterator position = this->trackCache.find(*track);
if(position!=this->trackCache.end()){
updateTrackPositions.push_back(position->second);
{
boost::mutex::scoped_lock lock(this->mutex);
for(musik::core::TrackVector::iterator track=metaTracks->begin();track!=metaTracks->end();++track){
TrackCacheMap::iterator position = this->trackCache.find(*track);
if(position!=this->trackCache.end()){
updateTrackPositions.push_back(position->second);
}
}
}
@ -352,9 +382,12 @@ void MultiLibraryList::OnTracksMetaFromQuery(musik::core::TrackVector *metaTrack
void MultiLibraryList::OnTracksMetaFromNonLibrary(musik::core::TrackPtr track){
std::vector<long> updateTrackPositions;
TrackCacheMap::iterator position = this->trackCache.find(track);
if(position!=this->trackCache.end()){
updateTrackPositions.push_back(position->second);
{
boost::mutex::scoped_lock lock(this->mutex);
TrackCacheMap::iterator position = this->trackCache.find(track);
if(position!=this->trackCache.end()){
updateTrackPositions.push_back(position->second);
}
}
if(!updateTrackPositions.empty()){
@ -363,6 +396,7 @@ void MultiLibraryList::OnTracksMetaFromNonLibrary(musik::core::TrackPtr track){
}
bool MultiLibraryList::SortTracks(std::string sortingMetakey){
boost::mutex::scoped_lock lock(this->mutex);
this->queryState = MultiLibraryList::Sorting;

View File

@ -44,6 +44,8 @@
#include <core/Library/Base.h>
#include <core/Query/SortTracksWithData.h>
#include <boost/thread/mutex.hpp>
#include <set>
#include <map>
#include <sigslot/sigslot.h>
@ -142,6 +144,12 @@ class MultiLibraryList : public Base, public sigslot::has_slots<> {
bool operator<(const SortHelper &sortHelper) const;
};
//////////////////////////////////////
///\brief
///mutex protexting the internal tracklist
//////////////////////////////////////
boost::mutex mutex;
};
//////////////////////////////////////////////////////////////////////////////

View File

@ -139,11 +139,11 @@ MenuRef MainMenuController::CreateMenu()
this->mainMenu = Menu::Create();
MenuItemCollection& mainItems = this->mainMenu->Items();
//
this->file = mainItems.Append(MenuItem::Create(_(_T("&File"))));
this->view = mainItems.Append(MenuItem::Create(_(_T("&View"))));
this->audio = mainItems.Append(MenuItem::Create(_(_T("&Audio"))));
this->tags = mainItems.Append(MenuItem::Create(_(_T("&Tags"))));
this->help = mainItems.Append(MenuItem::Create(_(_T("&Help"))));
this->file = mainItems.Append(MenuItem::Create(_TTP("&File")));
this->view = mainItems.Append(MenuItem::Create(_TTP("&View")));
this->audio = mainItems.Append(MenuItem::Create(_TTP("&Audio")));
this->tags = mainItems.Append(MenuItem::Create(_TTP("&Tags")));
this->help = mainItems.Append(MenuItem::Create(_TTP("&Help")));
// file menu
this->fileMenu = Menu::Create();
@ -151,24 +151,24 @@ MenuRef MainMenuController::CreateMenu()
//
this->file->SetSubMenu(this->fileMenu);
MenuItemRef addLibraryMenu = fileItems.Append(MenuItem::Create(_(_T("&New Library"))));
MenuItemRef addLibraryMenu = fileItems.Append(MenuItem::Create(_TTP("&New Library")));
MenuRef addLibrarySubmenu = Menu::Create();
this->fileAddLibraryLocal = addLibrarySubmenu->Items().Append(MenuItem::Create(_(_T("&Local library"))));
this->fileAddLibraryRemote = addLibrarySubmenu->Items().Append(MenuItem::Create(_(_T("&Remote library"))));
this->fileAddLibraryLocal = addLibrarySubmenu->Items().Append(MenuItem::Create(_TTP("&Local library")));
this->fileAddLibraryRemote = addLibrarySubmenu->Items().Append(MenuItem::Create(_TTP("&Remote library")));
addLibraryMenu->SetSubMenu(addLibrarySubmenu);
//this->fileNewPlaylist = fileItems.Append(MenuItem::Create(_(_T("&New Playlist"))));
//this->fileNewPlaylist = fileItems.Append(MenuItem::Create(_TTP("&New Playlist")));
this->fileOpenURL = fileItems.Append(MenuItem::Create(_(_T("Open &URL"))));
this->fileOpenURL = fileItems.Append(MenuItem::Create(_TTP("Open &URL\tCtrl+U")));
this->fileExit = fileItems.Append(MenuItem::Create(_(_T("E&xit"))));
this->fileExit = fileItems.Append(MenuItem::Create(_TTP("E&xit")));
// help menu
this->helpMenu = Menu::Create();
MenuItemCollection& helpItems = this->helpMenu->Items();
//
this->help->SetSubMenu(this->helpMenu);
this->helpAbout = helpItems.Append(MenuItem::Create(_(_T("&About"))));
this->helpAbout = helpItems.Append(MenuItem::Create(_TTP("&About")));
this->ConnectMenuHandlers();

View File

@ -85,7 +85,7 @@ void TransportController::OnViewCreated(Window* window)
this, &TransportController::OnVolumeSliderChange);
this->transportView.volumeSlider->SetPosition(
musik::core::PlaybackQueue::Instance().Transport().Volume()*100);
(short)(musik::core::PlaybackQueue::Instance().Transport().Volume()*(double)100));
musik::core::PlaybackQueue::Instance().CurrentTrackChanged.connect(this,&TransportController::OnTrackChange);
@ -153,23 +153,27 @@ void TransportController::OnTrackChange(musik::core::TrackPtr track){
return;
}
win32cpp::uistring title(_T("-"));
win32cpp::uistring artist(_T("-"));
if(track == musik::core::PlaybackQueue::Instance().CurrentTrack()){
win32cpp::uistring title(_T("-"));
win32cpp::uistring artist(_T("-"));
if(track){
if(track){
if(track->GetValue("title"))
title.assign( track->GetValue("title") );
if(track->GetValue("title"))
title.assign( track->GetValue("title") );
if(track->GetValue("visual_artist"))
artist.assign( track->GetValue("visual_artist") );
if(track->GetValue("visual_artist"))
artist.assign( track->GetValue("visual_artist") );
}else{
this->transportView.timeDurationLabel->SetCaption(_T("0:00"));
this->transportView.timeDurationLabel->SetCaption(this->FormatTime(this->CurrentTrackLength()));
}else{
this->transportView.timeElapsedLabel->SetCaption(_T("0:00"));
this->transportView.timeDurationLabel->SetCaption(_T("0:00"));
}
this->transportView.titleLabel->SetCaption(title);
this->transportView.artistLabel->SetCaption(artist);
}
this->transportView.titleLabel->SetCaption(title);
this->transportView.artistLabel->SetCaption(artist);
}
void TransportController::OnPlaybackSliderChange(Trackbar *trackBar)
@ -188,6 +192,10 @@ void TransportController::OnPlaybackSliderChange(Trackbar *trackBar)
void TransportController::OnPlaybackSliderTimerTimedOut()
{
if(!musik::core::PlaybackQueue::Instance().CurrentTrack()){
return;
}
// Get the length from the track
double trackLength = this->CurrentTrackLength();
@ -195,7 +203,7 @@ void TransportController::OnPlaybackSliderTimerTimedOut()
double position = musik::core::PlaybackQueue::Instance().Transport().Position();
if (!this->playbackSliderMouseDown){
if(trackLength>0){
this->transportView.playbackSlider->SetPosition( this->transportView.playbackSlider->Range()*(position/trackLength) );
this->transportView.playbackSlider->SetPosition( (short)((double)this->transportView.playbackSlider->Range()*(position/trackLength)) );
}
this->transportView.timeElapsedLabel->SetCaption(this->FormatTime(position));
return;
@ -266,29 +274,17 @@ void TransportController::OnPlaybackStopped()
return;
}
this->displayedTrack.reset();
/*
utfstring trackURI;
const utfchar* uri = track->URI();
if(uri)
trackURI = uri;
if(this->displayedTrack){
if (trackURI == this->displayedTrack->URI()) // For out of order signals
{*/
this->playing = false;
this->paused = false;
this->playing = false;
this->paused = false;
this->transportView.playButton->SetCaption(_T("Play"));
this->transportView.playButton->SetCaption(_T("Play"));
this->transportView.playbackSlider->SetPosition(0);
this->transportView.playbackSlider->SetPosition(0);
// this->playbackSliderTimer.Stop();
this->OnTrackChange(musik::core::TrackPtr());
this->transportView.timeElapsedLabel->SetCaption(_T("0:00"));
this->transportView.timeElapsedLabel->SetCaption(_T("0:00"));
this->transportView.timeDurationLabel->SetCaption(_T("0:00"));
// }
// }
}
void TransportController::OnPlaybackPaused()

View File

@ -86,11 +86,11 @@ void TransportView::OnCreated()
uistring nowPlayingCaption = _(_T("Now playing"));
nowPlayingCaption += _T(" ");
nowPlayingLayout->AddChild(new Label(nowPlayingCaption.c_str()));
this->titleLabel = nowPlayingLayout->AddChild(new Label(_(_T("Song Title"))));
this->titleLabel = nowPlayingLayout->AddChild(new Label(_(_T("-"))));
uistring byCaption = _(_T("by"));
byCaption = _T(" ") + byCaption + _T(" ");
nowPlayingLayout->AddChild(new Label(byCaption.c_str()));
this->artistLabel = nowPlayingLayout->AddChild(new Label(_(_T("Artist Name"))));
this->artistLabel = nowPlayingLayout->AddChild(new Label(_(_T("-"))));
//
this->titleLabel->SetFont(boldFont);
this->artistLabel->SetFont(boldFont);

View File

@ -98,6 +98,8 @@ public:
};
#define _(ORIGINALTEXT) (win32cpp::Locale::Instance()->Translate(ORIGINALTEXT).c_str())
#define _TT(ORIGINALTEXT) (win32cpp::Locale::Instance()->Translate(_T(ORIGINALTEXT)))
#define _TTP(ORIGINALTEXT) (win32cpp::Locale::Instance()->Translate(_T(ORIGINALTEXT)).c_str())
//////////////////////////////////////////////////////////////////////////////