diff --git a/src/3rdparty/include/sigslot/sigslot.h b/src/3rdparty/include/sigslot/sigslot.h index eded10fab..3f49c6363 100644 --- a/src/3rdparty/include/sigslot/sigslot.h +++ b/src/3rdparty/include/sigslot/sigslot.h @@ -2220,6 +2220,14 @@ namespace sigslot { pclass->signal_connect(this); } + bool has_connections(){ + lock_block lock(this); + if(this->m_connected_slots.size()==0){ + return false; + } + return true; + } + void emit(arg1_type a1, arg2_type a2, arg3_type a3) { lock_block lock(this); diff --git a/src/core/Library/Remote.cpp b/src/core/Library/Remote.cpp index a3a80bf50..dd6d96921 100644 --- a/src/core/Library/Remote.cpp +++ b/src/core/Library/Remote.cpp @@ -175,7 +175,7 @@ void Library::Remote::ReadThread(){ if(currentQuery->RecieveResults(node,this)){ currentQuery->status |= Query::Base::Status::Ended; }else{ - currentQuery->status |= Query::Base::Status::Canceled; + currentQuery->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended; } } } @@ -227,7 +227,11 @@ void Library::Remote::WriteThread(){ queryNode.Attributes()["options"] = boost::lexical_cast(query->options); } - query->SendQuery(queryNode); + if(!query->SendQuery(queryNode)){ + // Query can not be send, lets cancel it + boost::mutex::scoped_lock lock(this->libraryMutex); + query->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended; + } // Check if writer has quit if(writer.Exited()){ diff --git a/src/core/Query/ListBase.cpp b/src/core/Query/ListBase.cpp index c566c740d..ecc077305 100644 --- a/src/core/Query/ListBase.cpp +++ b/src/core/Query/ListBase.cpp @@ -38,6 +38,7 @@ #include #include #include +#include using namespace musik::core; @@ -251,26 +252,31 @@ bool Query::ListBase::SendResults(musik::core::xml::WriterNode &queryNode,Librar } - if(!continueSending){ - boost::mutex::scoped_lock lock(library->oResultMutex); - // Check for trackinfo update - musik::core::xml::WriterNode trackInfoNode(queryNode,"trackinfo"); - trackInfoNode.Content() = boost::lexical_cast( trackInfoTracks ); - trackInfoNode.Content() += ","+boost::lexical_cast( trackInfoDuration ); - trackInfoNode.Content() += ","+boost::lexical_cast( trackInfoSize ); - }else{ + if(continueSending){ if( metadataResultsCopy.empty() && trackResultsCopy.empty() ){ // Yield for more results boost::thread::yield(); } } } + + { + boost::mutex::scoped_lock lock(library->oResultMutex); + // Check for trackinfo update + musik::core::xml::WriterNode trackInfoNode(queryNode,"trackinfo"); + trackInfoNode.Content() = boost::lexical_cast( this->trackInfoTracks ); + trackInfoNode.Content() += ","+boost::lexical_cast( this->trackInfoDuration ); + trackInfoNode.Content() += ","+boost::lexical_cast( this->trackInfoSize ); + } + return true; } bool Query::ListBase::RecieveResults(musik::core::xml::ParserNode &queryNode,Library::Base *library){ while( musik::core::xml::ParserNode node = queryNode.ChildNode() ){ + + // Recieve metadata if( node.Name()=="metadata"){ std::string metakey(node.Attributes()["key"]); @@ -310,6 +316,59 @@ bool Query::ListBase::RecieveResults(musik::core::xml::ParserNode &queryNode,Lib } + + typedef std::vector StringVector; + + // Recieve tracks + if( node.Name()=="tracklist"){ + while( musik::core::xml::ParserNode tracksNode = node.ChildNode("tracks") ){ + tracksNode.WaitForContent(); + + StringVector values; + boost::algorithm::split(values,tracksNode.Content(),boost::algorithm::is_any_of(",")); + + try{ // lexical_cast can throw + TrackVector tempTrackResults; + tempTrackResults.reserve(101); + + for(StringVector::iterator value=values.begin();value!=values.end();++value){ + int trackId(boost::lexical_cast(*value)); + tempTrackResults.push_back(TrackPtr(new Track(trackId))); + } + + { + boost::mutex::scoped_lock lock(library->oResultMutex); + this->trackResults.insert(this->trackResults.end(),tempTrackResults.begin(),tempTrackResults.end()); + } + + } + catch(...){ + return false; + } + } + } + + + // Recieve trackinfo + if( node.Name()=="trackinfo"){ + node.WaitForContent(); + + StringVector values; + boost::algorithm::split(values,node.Content(),boost::algorithm::is_any_of(",")); + + if(values.size()>=3){ + try{ + boost::mutex::scoped_lock lock(library->oResultMutex); + this->trackInfoTracks = boost::lexical_cast( values[0] ); + this->trackInfoDuration = boost::lexical_cast( values[1] ); + this->trackInfoSize = boost::lexical_cast( values[2] ); + } + catch(...){ + return false; + } + } + } + } return true; diff --git a/src/core/Query/ListSelection.cpp b/src/core/Query/ListSelection.cpp index e75c929d2..1f3551295 100644 --- a/src/core/Query/ListSelection.cpp +++ b/src/core/Query/ListSelection.cpp @@ -571,11 +571,12 @@ bool Query::ListSelection::RecieveQuery(musik::core::xml::ParserNode &queryNode) while( musik::core::xml::ParserNode node = queryNode.ChildNode() ){ if(node.Name()=="selections"){ - + std::cout << ""; // Get metakey nodes // Expected tag is likle this: // 2,5,3 while( musik::core::xml::ParserNode selectionNode = node.ChildNode("selection") ){ + std::cout << ""; // Wait for all content selectionNode.WaitForContent(); @@ -587,9 +588,13 @@ bool Query::ListSelection::RecieveQuery(musik::core::xml::ParserNode &queryNode) for(StringVector::iterator value=values.begin();value!=values.end();++value){ this->SelectMetadata(selectionNode.Attributes()["key"].c_str(),boost::lexical_cast(*value)); + std::cout << "," << *value; } + std::cout << "" << std::endl; } + std::cout << "" << std::endl; + }else if(node.Name()=="listeners"){ // Wait for all content @@ -656,6 +661,16 @@ bool Query::ListSelection::SendQuery(musik::core::xml::WriterNode &queryNode){ listenersNode.Content().append(listener->first); } } + // Then the track listener + if( this->trackEvent.has_connections() ){ + xml::WriterNode listTracksNode(queryNode,"listtracks"); + listTracksNode.Content().append("true"); + } + // Then the track listener + if( this->trackInfoEvent.has_connections() ){ + xml::WriterNode listTrackInfoNode(queryNode,"listtrackinfo"); + listTrackInfoNode.Content().append("true"); + } return true; } diff --git a/src/core/xml/Parser.cpp b/src/core/xml/Parser.cpp index db7c2aede..3c4121079 100644 --- a/src/core/xml/Parser.cpp +++ b/src/core/xml/Parser.cpp @@ -117,7 +117,7 @@ void Parser::OnElementEndReal(const char *name){ if(this->currentNodeLevels.size()>0){ if(this->currentNodeLevels.back()->name == name){ - this->currentNodeLevels.back()->status = Node::Status::Ended; + this->currentNodeLevels.back()->status |= Node::Status::Ended; this->currentNodeLevels.pop_back(); this->currentEventType = EventTypes::NodeEnd; diff --git a/src/core/xml/ParserNode.cpp b/src/core/xml/ParserNode.cpp index 080063e61..5cea61b93 100644 --- a/src/core/xml/ParserNode.cpp +++ b/src/core/xml/ParserNode.cpp @@ -138,7 +138,7 @@ std::string& ParserNode::Content(){ ////////////////////////////////////////// void ParserNode::WaitForContent(){ if(this->node && this->status==1){ - while(this->node->status!=Node::Status::Ended){ + while( !(this->node->status & Node::Status::Ended) ){ // Wait for node to be ended this->parser->ContinueParsing(); }