From 86bd96e7104a7dfda184cd2963dee29bf59e0857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C3=96nnerby?= Date: Thu, 4 Sep 2008 10:39:03 +0000 Subject: [PATCH] Added some documentation. --- src/core/Indexer.cpp | 29 +++++++++++++++ src/core/Indexer.h | 8 +++++ src/core/Library/Base.cpp | 57 +++++++++++++++++++++++++++++ src/core/Library/Base.h | 2 +- src/core/Library/LocalDB.cpp | 12 +++++++ src/core/Library/Remote.cpp | 37 ++++++++++--------- src/core/LibraryFactory.cpp | 47 ++++++++++++++++++++++++ src/core/LibraryFactory.h | 24 ++++++++++++- src/core/xml/Parser.h | 26 ++++++++++++++ src/core/xml/ParserNode.cpp | 69 ++++++++++++++++++++++++++++++++++-- src/core/xml/ParserNode.h | 9 +++++ 11 files changed, 299 insertions(+), 21 deletions(-) diff --git a/src/core/Indexer.cpp b/src/core/Indexer.cpp index 39a0fcb2a..a0a6f11dc 100644 --- a/src/core/Indexer.cpp +++ b/src/core/Indexer.cpp @@ -59,6 +59,12 @@ Indexer::Indexer(void) { } +////////////////////////////////////////// +///\brief +///Destructor +/// +///Exits and joins threads +////////////////////////////////////////// Indexer::~Indexer(void){ if(this->oThread){ this->Exit(); @@ -69,6 +75,10 @@ Indexer::~Indexer(void){ } +////////////////////////////////////////// +///\brief +///Get the current status (text) +////////////////////////////////////////// utfstring Indexer::GetStatus(){ boost::mutex::scoped_lock oLock(this->oProgressMutex); utfstring sStatus; @@ -93,6 +103,13 @@ utfstring Indexer::GetStatus(){ } +////////////////////////////////////////// +///\brief +///Restart the sync +/// +///\param bNewRestart +///Should if be restarted or not +////////////////////////////////////////// void Indexer::RestartSync(bool bNewRestart){ boost::mutex::scoped_lock oLock(this->exitMutex); this->bRestart = bNewRestart; @@ -101,6 +118,10 @@ void Indexer::RestartSync(bool bNewRestart){ } } +////////////////////////////////////////// +///\brief +///Should the sync be restarted? +////////////////////////////////////////// bool Indexer::Restarted(){ boost::mutex::scoped_lock oLock(this->exitMutex); return this->bRestart; @@ -668,6 +689,10 @@ void Indexer::SyncCleanup(){ } +////////////////////////////////////////// +///\brief +///Get a vector with all sync paths +////////////////////////////////////////// std::vector Indexer::GetPaths(){ std::vector aPaths; @@ -804,6 +829,10 @@ void Indexer::SyncOptimize(){ } +////////////////////////////////////////// +///\brief +///Method for adding/removing paths in the database +////////////////////////////////////////// void Indexer::SyncAddRemovePaths(){ boost::mutex::scoped_lock lock(this->exitMutex); diff --git a/src/core/Indexer.h b/src/core/Indexer.h index a9a0b77ca..d637845bb 100644 --- a/src/core/Indexer.h +++ b/src/core/Indexer.h @@ -56,6 +56,14 @@ namespace musik{ namespace core{ ////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////// +///\brief +///The Indexer is the class that syncronizes musik tracks with the database +/// +///The Indexer is often a member of classes like the LocalDB +///but can also be used as a standalone class for indexing files. +///All you need to do is create a Indexer object and call Startup() +////////////////////////////////////////// class Indexer : public ThreadHelper,private boost::noncopyable { public: Indexer(void); diff --git a/src/core/Library/Base.cpp b/src/core/Library/Base.cpp index 11a686658..76ef07ce5 100644 --- a/src/core/Library/Base.cpp +++ b/src/core/Library/Base.cpp @@ -47,6 +47,10 @@ using namespace musik::core; +////////////////////////////////////////// +///\brief +///Constructor +////////////////////////////////////////// Library::Base::Base(utfstring identifier) :identifier(identifier) ,queueCallbackStarted(false) @@ -55,6 +59,13 @@ Library::Base::Base(utfstring identifier) { } +////////////////////////////////////////// +///\brief +///Get the librarys "now playing" tracklist +/// +///\returns +///a tracklist::Ptr +////////////////////////////////////////// musik::core::tracklist::Ptr Library::Base::NowPlaying(){ if(tracklist::Ptr tracklist = this->nowPlaying.lock()){ return tracklist; @@ -69,11 +80,24 @@ musik::core::tracklist::Ptr Library::Base::NowPlaying(){ return tracklist; } +////////////////////////////////////////// +///\brief +///Destructor +/// +///The destructor will exit all threads created by the library +////////////////////////////////////////// Library::Base::~Base(void){ this->Exit(); this->threads.join_all(); } +////////////////////////////////////////// +///\brief +///Get the librarys identifier. The identifier is unique for the library +/// +///\returns +///A string with the identifier +////////////////////////////////////////// const utfstring& Library::Base::Identifier(){ return this->identifier; } @@ -438,11 +462,21 @@ void Library::Base::CancelCurrentQuery(){ } +////////////////////////////////////////// +///\brief +///Has the library exited? +////////////////////////////////////////// bool Library::Base::Exited(){ boost::mutex::scoped_lock lock(this->libraryMutex); return this->exit; } +////////////////////////////////////////// +///\brief +///Exit the library +/// +///Will set the library to Exited and notify all sleeping threads +////////////////////////////////////////// void Library::Base::Exit(){ { boost::mutex::scoped_lock lock(this->libraryMutex); @@ -452,6 +486,10 @@ void Library::Base::Exit(){ } +////////////////////////////////////////// +///\brief +///Helper method to determin what metakeys are "static" +////////////////////////////////////////// bool Library::Base::IsStaticMetaKey(std::string &metakey){ static std::set staticMetaKeys; @@ -470,6 +508,10 @@ bool Library::Base::IsStaticMetaKey(std::string &metakey){ } +////////////////////////////////////////// +///\brief +///Helper method to determin what metakeys that have a special many to one relation +////////////////////////////////////////// bool Library::Base::IsSpecialMTOMetaKey(std::string &metakey){ static std::set specialMTOMetaKeys; @@ -482,6 +524,10 @@ bool Library::Base::IsSpecialMTOMetaKey(std::string &metakey){ return specialMTOMetaKeys.find(metakey)!=specialMTOMetaKeys.end(); } +////////////////////////////////////////// +///\brief +///Helper method to determin what metakeys that have a special many to meny relation +////////////////////////////////////////// bool Library::Base::IsSpecialMTMMetaKey(std::string &metakey){ static std::set specialMTMMetaKeys; @@ -492,6 +538,10 @@ bool Library::Base::IsSpecialMTMMetaKey(std::string &metakey){ return specialMTMMetaKeys.find(metakey)!=specialMTMMetaKeys.end(); } +////////////////////////////////////////// +///\brief +///Get a pointer to the librarys Indexer (NULL if none) +////////////////////////////////////////// musik::core::Indexer *Library::Base::Indexer(){ return NULL; } @@ -629,6 +679,13 @@ void Library::Base::CreateDatabase(db::Connection &db){ db.Analyze(); } +////////////////////////////////////////// +///\brief +///Get the base path to where the tracks are located +/// +///This method is mostly used by the Library::Remote to +///get the HTTP-address to the tracks +////////////////////////////////////////// utfstring Library::Base::BasePath(){ return UTF(""); } diff --git a/src/core/Library/Base.h b/src/core/Library/Base.h index bfa2a3045..869356d26 100644 --- a/src/core/Library/Base.h +++ b/src/core/Library/Base.h @@ -82,7 +82,7 @@ namespace musik{ namespace core{ namespace Library{ /// ///\remarks ///Library::Base is only the interface and can not be used directly. -///Library::Base extends the ThreadHelper and is therefore a noncopyable object. +///Library::Base is a noncopyable object. /// ///\see ///musik::core::Library::LocalDB diff --git a/src/core/Library/LocalDB.cpp b/src/core/Library/LocalDB.cpp index e05cae202..adaf9fd2f 100644 --- a/src/core/Library/LocalDB.cpp +++ b/src/core/Library/LocalDB.cpp @@ -58,12 +58,20 @@ Library::LocalDB::LocalDB(utfstring identifier) { } +////////////////////////////////////////// +///\brief +///Create a LocalDB library +////////////////////////////////////////// LibraryPtr Library::LocalDB::Create(utfstring identifier){ LibraryPtr lib(new Library::LocalDB(identifier)); lib->self = lib; return lib; } +////////////////////////////////////////// +///\brief +///Destructor that exits and joins all threads +////////////////////////////////////////// Library::LocalDB::~LocalDB(void){ this->Exit(); this->threads.join_all(); @@ -191,6 +199,10 @@ void Library::LocalDB::CancelCurrentQuery( ){ this->db.Interrupt(); } +////////////////////////////////////////// +///\brief +///Get a pointer to the librarys Indexer (NULL if none) +////////////////////////////////////////// musik::core::Indexer *Library::LocalDB::Indexer(){ return &this->indexer; } diff --git a/src/core/Library/Remote.cpp b/src/core/Library/Remote.cpp index 53f4c7b01..0023ec2f2 100644 --- a/src/core/Library/Remote.cpp +++ b/src/core/Library/Remote.cpp @@ -44,7 +44,6 @@ #include #include -#include using namespace musik::core; @@ -64,12 +63,20 @@ Library::Remote::Remote(utfstring identifier) { } +////////////////////////////////////////// +///\brief +///Create a Remote library +////////////////////////////////////////// LibraryPtr Library::Remote::Create(utfstring identifier){ LibraryPtr lib(new Library::Remote(identifier)); lib->self = lib; return lib; } +////////////////////////////////////////// +///\brief +///Destructor that exits and joins all threads +////////////////////////////////////////// Library::Remote::~Remote(void){ this->Exit(); this->threads.join_all(); @@ -99,7 +106,6 @@ utfstring Library::Remote::GetInfo(){ ////////////////////////////////////////// bool Library::Remote::Startup(){ - ATLTRACE2("Library::Remote::Startup\n"); // Lets start the ReadThread first, it will startup the connection and // then start the WriteThread this->threads.create_thread(boost::bind(&Library::Remote::ReadThread,this)); @@ -114,7 +120,6 @@ bool Library::Remote::Startup(){ ////////////////////////////////////////// void Library::Remote::ReadThread(){ -ATLTRACE2("Library::Remote::ReadThread\n"); { Preferences prefs("Connection",this->Identifier().c_str()); @@ -126,42 +131,33 @@ ATLTRACE2("Library::Remote::ReadThread\n"); boost::asio::ip::tcp::resolver::query resolverQuery(this->address,this->port); try{ - ATLTRACE2("Library::Remote::ReadThread 1\n"); boost::system::error_code resolverError; boost::asio::ip::tcp::resolver::iterator endpointIterator = resolver.resolve(resolverQuery,resolverError); boost::asio::ip::tcp::resolver::iterator end; - ATLTRACE2("Library::Remote::ReadThread 1.1\n"); if(resolverError){ - ATLTRACE2("Library::Remote::ReadThread ERROR 1.1\n"); this->Exit(); return; } boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpointIterator!=end){ - ATLTRACE2("Library::Remote::ReadThread 1.2\n"); this->socket.close(); - ATLTRACE2("Library::Remote::ReadThread 1.3\n"); this->socket.connect(*endpointIterator, error); - ATLTRACE2("Library::Remote::ReadThread 1.4\n"); if(error){ endpointIterator++; } } if (error || endpointIterator==end){ - ATLTRACE2("Library::Remote::ReadThread 1.5\n"); this->Exit(); return; } - ATLTRACE2("Library::Remote::ReadThread 1.6\n"); } catch(...){ this->Exit(); return; } - ATLTRACE2("Library::Remote::ReadThread 2\n"); // Successfully connected to server // Start the WriteThread try{ @@ -172,15 +168,12 @@ ATLTRACE2("Library::Remote::ReadThread\n"); return; } - ATLTRACE2("Library::Remote::ReadThread 3\n"); try{ // Lets start recieving queries xml::Parser parser(&this->socket); - ATLTRACE2("Library::Remote::ReadThread 4\n"); if( xml::ParserNode rootNode=parser.ChildNode("musik")){ while(xml::ParserNode node=rootNode.ChildNode()){ - ATLTRACE2("Library::Remote::ReadThread 5\n"); if(node.Name()=="queryresults"){ unsigned int queryId = boost::lexical_cast(node.Attributes()["id"]); @@ -225,7 +218,6 @@ ATLTRACE2("Library::Remote::ReadThread\n"); ///Thread for writing to the socket ////////////////////////////////////////// void Library::Remote::WriteThread(){ - ATLTRACE2("Library::Remote::WriteThread\n"); xml::Writer writer(&this->socket); @@ -302,6 +294,12 @@ void Library::Remote::CancelCurrentQuery( ){ } +////////////////////////////////////////// +///\brief +///Exit the library +/// +///Will set the library to Exited, close sockets and notify all sleeping threads +////////////////////////////////////////// void Library::Remote::Exit(){ { boost::mutex::scoped_lock lock(this->libraryMutex); @@ -315,6 +313,13 @@ void Library::Remote::Exit(){ this->waitCondition.notify_all(); } +////////////////////////////////////////// +///\brief +///Get the base path to where the tracks are located +/// +///This method is mostly used by the Library::Remote to +///get the HTTP-address to the tracks +////////////////////////////////////////// utfstring Library::Remote::BasePath(){ utfstring path(UTF("http://")); boost::asio::ip::tcp::endpoint endPoint = this->socket.remote_endpoint(); diff --git a/src/core/LibraryFactory.cpp b/src/core/LibraryFactory.cpp index a1324d208..43b01a111 100644 --- a/src/core/LibraryFactory.cpp +++ b/src/core/LibraryFactory.cpp @@ -45,6 +45,10 @@ using namespace musik::core; LibraryFactory LibraryFactory::sInstance; +////////////////////////////////////////// +///\brief +///Constructor +////////////////////////////////////////// LibraryFactory::LibraryFactory(void){ // Connect to the settings.db utfstring dataDir = GetDataDirectory(); @@ -68,9 +72,32 @@ LibraryFactory::LibraryFactory(void){ } +////////////////////////////////////////// +///\brief +///Destructor +////////////////////////////////////////// LibraryFactory::~LibraryFactory(void){ } +////////////////////////////////////////// +///\brief +///Add a new library to the LibraryFactory +/// +///\param name +///Identifier of library. Need to be a unique name. +/// +///\param type +///Type of library. See LibraryFactory::Types +/// +///\param sendEvent +///Send the LibrariesUpdated when library has been added? +/// +///\param startup +///Start the library when added +/// +///\returns +///LibraryPtr of the added library. (NULL pointer on failure) +////////////////////////////////////////// LibraryPtr LibraryFactory::AddLibrary(utfstring name,int type,bool sendEvent,bool startup){ LibraryPtr lib; switch(type){ @@ -102,6 +129,22 @@ LibraryPtr LibraryFactory::AddLibrary(utfstring name,int type,bool sendEvent,boo void LibraryFactory::RemoveLibrary(utfstring name){ } +////////////////////////////////////////// +///\brief +///Create a new Library +/// +///\param name +///Identifier of library. Need to be a unique name. +/// +///\param type +///Type of library. See LibraryFactory::Types +/// +///\param startup +///Start the library when added +/// +///\returns +///LibraryPtr of the added library. (NULL pointer on failure) +////////////////////////////////////////// LibraryPtr LibraryFactory::CreateLibrary(utfstring name,int type,bool startup){ // Connect to the settings.db utfstring dataDir = GetDataDirectory(); @@ -121,6 +164,10 @@ LibraryPtr LibraryFactory::CreateLibrary(utfstring name,int type,bool startup){ void LibraryFactory::DeleteLibrary(utfstring name){ } +////////////////////////////////////////// +///\brief +///Get the vector with all current libraries +////////////////////////////////////////// LibraryFactory::LibraryVector& LibraryFactory::Libraries(){ return LibraryFactory::sInstance.libraries; } diff --git a/src/core/LibraryFactory.h b/src/core/LibraryFactory.h index 1512dd91a..2c8915d0e 100644 --- a/src/core/LibraryFactory.h +++ b/src/core/LibraryFactory.h @@ -45,11 +45,23 @@ namespace musik{ namespace core{ ////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////// +///\brief +///Factory for Libraries +/// +///LibraryFactory contains all Libraries (LocalDB and Remote) +///When the LibraryFactory is first initialized it will load all +///libraries from the settings.db database. +////////////////////////////////////////// class LibraryFactory{ private: static LibraryFactory sInstance; public: + ////////////////////////////////////////// + ///\brief + ///enum for the different library types + ////////////////////////////////////////// enum Types:int{ LocalDB=1, Remote=2 @@ -57,14 +69,24 @@ class LibraryFactory{ typedef std::vector LibraryVector; + ////////////////////////////////////////// + ///\brief + ///Get the LibraryFactory singleton + ////////////////////////////////////////// static LibraryFactory& Instance(){ return sInstance; }; + static LibraryVector& Libraries(); LibraryPtr CreateLibrary(utfstring name,int type,bool startup=true); void DeleteLibrary(utfstring name); typedef sigslot::signal0<> LibrariesUpdatedEvent; - LibrariesUpdatedEvent LibrariesUpdated; + + ////////////////////////////////////////// + ///\brief + ///signal alerting that a library has been added/removed + ////////////////////////////////////////// + LibrariesUpdatedEvent LibrariesUpdated; private: diff --git a/src/core/xml/Parser.h b/src/core/xml/Parser.h index ef963ea69..6dc25712e 100644 --- a/src/core/xml/Parser.h +++ b/src/core/xml/Parser.h @@ -61,6 +61,32 @@ namespace musik{ namespace core{ namespace xml{ ////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////// +///\brief +///Parser class to parse xml continously from a socket stream +/// +///The Parser and the ParserNode contiously parse from the +///socket provided in the constructor like this +///\code +///xml::Parser parser(&socket); +/// +///\/\/To wait for a specific xml node to arrive +///if(xml::ParserNode rootNode = parser.ChildNode("musik") ){ +/// \/\/Make a loop, waiting for any xml node to arrive that's inside the rootNode +/// while( xml::ParserNode node = rootNode.ChildNode() ){ +/// // The Nodes can be used to access the tags attributes and content +/// std::cout << "Tag: " << node.Name() << std::endl; +/// std::cout << "Attribute[type]: " << node.Attributes()["type"] << std::endl; +/// \/\/ Although, if you are to use the content of the node, you need to make sure that the content is read +/// node.WaitForContent(); +/// std::cout << "Content: " << node.Content() << std::endl; +/// } +///} +///\endcode +/// +///\see +///musik::core::xml::ParserNode +////////////////////////////////////////// class Parser : public ParserNode{ public: Parser(boost::asio::ip::tcp::socket *socket); diff --git a/src/core/xml/ParserNode.cpp b/src/core/xml/ParserNode.cpp index 5cea61b93..29bc5a3a0 100644 --- a/src/core/xml/ParserNode.cpp +++ b/src/core/xml/ParserNode.cpp @@ -39,13 +39,40 @@ using namespace musik::core::xml; +////////////////////////////////////////// +///\brief +///Contructor +////////////////////////////////////////// ParserNode::ParserNode() -:status(0) -,parser(NULL) + :status(0) + ,parser(NULL) { } +////////////////////////////////////////// +///\brief +///Copy a ParserNode +/// +///\param copyNode +///node to be copied +/// +///\returns +///A reference to *this +/// +///The copy method is used when you are writing code like this: +///\code +///while( xml::ParserNode node=parentNode.ChildNode() ){ +///} +///\endcode +///In this case, a "node" is created and then copied from the node +///returned from the parentNode.ChildNode method. This method need to +///return a reference to itself since the while loop is looking for +///the "operator bool" to see if the loop should continue. +/// +///\see +///operator bool +////////////////////////////////////////// ParserNode& ParserNode::operator=(ParserNode const ©Node){ this->node = copyNode.node; this->parentNode = copyNode.parentNode; @@ -55,6 +82,19 @@ ParserNode& ParserNode::operator=(ParserNode const ©Node){ } +////////////////////////////////////////// +///\brief +///Contructor +/// +///\param parent +///A pointer to the nodes parent node +/// +///This contrutor will hold until the node is read from the socket +///or until an error occurs (like the node should go out of scope) +/// +///\see +///ParserNode::ChildNode +////////////////////////////////////////// ParserNode::ParserNode(const ParserNode *parent) : status(0) { @@ -65,6 +105,22 @@ ParserNode::ParserNode(const ParserNode *parent) this->WaitForNode(nodeNames); } +////////////////////////////////////////// +///\brief +///Contructor +/// +///\param parent +///A pointer to the nodes parent node +/// +///\param expectedNode +///A node name to wait for +/// +///This contrutor will hold until the expectedNode is read from the socket +///or until an error occurs (like the node should go out of scope) +/// +///\see +///ParserNode::ChildNode +////////////////////////////////////////// ParserNode::ParserNode(const ParserNode *parent,std::string &expectedNode) : status(0) { @@ -132,7 +188,7 @@ std::string& ParserNode::Content(){ ///\brief ///Wait for all content to be retrieved /// -///What realy happens is that the method will wait until +///What really happens is that the method will wait until ///the nodes end tag has been set to assure that all content ///has been retrieved. ////////////////////////////////////////// @@ -157,6 +213,13 @@ Node::AttributeMap& ParserNode::Attributes(){ return this->node->attributes; } +////////////////////////////////////////// +///\brief +///Overload of the bool operator +/// +///\returns +///Is this node successfully started +////////////////////////////////////////// ParserNode::operator bool(){ return this->status==1; } diff --git a/src/core/xml/ParserNode.h b/src/core/xml/ParserNode.h index a4f35dcfe..2f643cdf3 100644 --- a/src/core/xml/ParserNode.h +++ b/src/core/xml/ParserNode.h @@ -48,6 +48,15 @@ namespace musik{ namespace core{ namespace xml{ class Parser; +////////////////////////////////////////// +///\brief +///ParserNode represent a xml-node in a DOM tree. +/// +///For example look at musik::core::xml::Parser +/// +///\see +///musik::core::xml::Parser +////////////////////////////////////////// class ParserNode { public: