Added some documentation.

This commit is contained in:
Daniel Önnerby 2008-09-04 10:39:03 +00:00
parent 56d9c246a5
commit 86bd96e710
11 changed files with 299 additions and 21 deletions

View File

@ -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<utfstring> Indexer::GetPaths(){
std::vector<utfstring> 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);

View File

@ -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);

View File

@ -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<std::string> 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<std::string> 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<std::string> 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("");
}

View File

@ -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

View File

@ -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;
}

View File

@ -44,7 +44,6 @@
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <atlbase.h>
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<unsigned int>(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();

View File

@ -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;
}

View File

@ -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<LibraryPtr> 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:

View File

@ -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);

View File

@ -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 &copyNode){
this->node = copyNode.node;
this->parentNode = copyNode.parentNode;
@ -55,6 +82,19 @@ ParserNode& ParserNode::operator=(ParserNode const &copyNode){
}
//////////////////////////////////////////
///\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;
}

View File

@ -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: