[Orxonox-commit 2668] r7373 - code/branches/doc/src/libraries/core
landauf at orxonox.net
landauf at orxonox.net
Tue Sep 7 23:24:47 CEST 2010
Author: landauf
Date: 2010-09-07 23:24:47 +0200 (Tue, 07 Sep 2010)
New Revision: 7373
Modified:
code/branches/doc/src/libraries/core/ConfigFileManager.cc
code/branches/doc/src/libraries/core/ConfigFileManager.h
code/branches/doc/src/libraries/core/OrxonoxClass.cc
code/branches/doc/src/libraries/core/OrxonoxClass.h
code/branches/doc/src/libraries/core/SmartPtr.h
code/branches/doc/src/libraries/core/WeakPtr.h
Log:
added documentation
Modified: code/branches/doc/src/libraries/core/ConfigFileManager.cc
===================================================================
--- code/branches/doc/src/libraries/core/ConfigFileManager.cc 2010-09-06 22:58:52 UTC (rev 7372)
+++ code/branches/doc/src/libraries/core/ConfigFileManager.cc 2010-09-07 21:24:47 UTC (rev 7373)
@@ -26,6 +26,11 @@
*
*/
+/**
+ @file
+ @brief Implementation of ConfigFileManager and its helper classes.
+*/
+
#include "ConfigFileManager.h"
#include <boost/filesystem.hpp>
@@ -42,7 +47,9 @@
//////////////////////////
// ConfigFileEntryValue //
//////////////////////////
-
+ /**
+ @brief Updates the string that will be stored in the file after one of it's components (name, value, comment) has changed.
+ */
void ConfigFileEntryValue::update()
{
// Make sure we remove the quotes when bString changes
@@ -62,6 +69,9 @@
////////////////////////////////
// ConfigFileEntryVectorValue //
////////////////////////////////
+ /**
+ @brief Updates the string that will be stored in the file after one of it's components (name, value, index, comment) has changed.
+ */
void ConfigFileEntryVectorValue::update()
{
this->keyString_ = this->name_ + '[' + multi_cast<std::string>(this->index_) + ']';
@@ -72,12 +82,21 @@
///////////////////////
// ConfigFileSection //
///////////////////////
+ /**
+ @brief Destructor: Deletes all entries.
+ */
ConfigFileSection::~ConfigFileSection()
{
for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); )
delete (*(it++));
}
+ /**
+ @brief Deletes all elements of a config vector if their index is greater or equal to @a startindex.
+
+ @param name The name of the vector
+ @param startindex The index of the first element that will be deleted
+ */
void ConfigFileSection::deleteVectorEntries(const std::string& name, unsigned int startindex)
{
for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); )
@@ -94,6 +113,10 @@
}
}
+ /**
+ @brief Returns the size of a config vector.
+ @param name The name of the vector
+ */
unsigned int ConfigFileSection::getVectorSize(const std::string& name) const
{
unsigned int size = 0;
@@ -107,6 +130,9 @@
return (size + 1);
}
+ /**
+ @brief Returns the title and comment of the section as it will be stored in the file.
+ */
std::string ConfigFileSection::getFileEntry() const
{
if (this->additionalComment_.empty())
@@ -115,6 +141,11 @@
return ('[' + this->name_ + "] " + this->additionalComment_);
}
+ /**
+ @brief Returns the entry with given name (or NULL if it doesn't exist).
+
+ @param name The name of the entry
+ */
ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name) const
{
for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
@@ -125,6 +156,12 @@
return NULL;
}
+ /**
+ @brief Returns the entry of a vector element with given name and index (or NULL if it doesn't exist).
+
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ */
ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name, unsigned int index) const
{
for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
@@ -135,6 +172,13 @@
return NULL;
}
+ /**
+ @brief Returns the iterator to the entry with given name. If the entry doesn't exist, it is created using the fallback value.
+
+ @param name The name of the entry
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
std::list<ConfigFileEntry*>::iterator ConfigFileSection::getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString)
{
for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
@@ -151,6 +195,14 @@
return this->entries_.insert(this->entries_.end(), new ConfigFileEntryValue(name, fallback, bString));
}
+ /**
+ @brief Returns the iterator to the entry of a vector element with given name and index. If the entry doesn't exist, it is created using the fallback value.
+
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
std::list<ConfigFileEntry*>::iterator ConfigFileSection::getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
{
for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
@@ -177,6 +229,11 @@
const char* ConfigFile::DEFAULT_CONFIG_FOLDER = "defaultConfig";
+ /**
+ @brief Constructor: Initializes the config file.
+ @param filename The file-name of this config file
+ @param bCopyFallbackFile If true, the default config file is copied into the config-directory before loading the file
+ */
ConfigFile::ConfigFile(const std::string& filename, bool bCopyFallbackFile)
: filename_(filename)
, bCopyFallbackFile_(bCopyFallbackFile)
@@ -184,11 +241,17 @@
{
}
+ /**
+ @brief Destructor: Deletes all sections and entries.
+ */
ConfigFile::~ConfigFile()
{
this->clear();
}
+ /**
+ @brief Loads the config file from the hard-disk and reads the sections and their values.
+ */
void ConfigFile::load()
{
// Be sure we start from new in the memory
@@ -317,11 +380,17 @@
} // end file.is_open()
}
+ /**
+ @brief Writes the sections and values to the hard-disk.
+ */
void ConfigFile::save() const
{
this->saveAs(this->filename_);
}
+ /**
+ @brief Writes the sections and values to a given file on the hard-disk.
+ */
void ConfigFile::saveAs(const std::string& filename) const
{
boost::filesystem::path filepath(filename);
@@ -353,6 +422,9 @@
COUT(4) << "Saved config file \"" << filename << "\"." << std::endl;
}
+ /**
+ @brief Deletes all sections (which again delete all their values) and clears the list of sections.
+ */
void ConfigFile::clear()
{
for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); )
@@ -360,20 +432,13 @@
this->sections_.clear();
}
- const std::string& ConfigFile::getOrCreateValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString)
- {
- const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, fallback, bString);
- this->saveIfUpdated();
- return output;
- }
+ /**
+ @brief Deletes all elements of a config vector if their index is greater or equal to @a startindex.
- const std::string& ConfigFile::getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString)
- {
- const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, index, fallback, bString);
- this->saveIfUpdated();
- return output;
- }
-
+ @param section The name of the section
+ @param name The name of the vector
+ @param startindex The index of the first element that will be deleted
+ */
void ConfigFile::deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex)
{
if (ConfigFileSection* sectionPtr = this->getSection(section))
@@ -383,6 +448,9 @@
}
}
+ /**
+ @brief Returns a pointer to the section with given name (or NULL if the section doesn't exist).
+ */
ConfigFileSection* ConfigFile::getSection(const std::string& section) const
{
for (std::list<ConfigFileSection*>::const_iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)
@@ -391,6 +459,9 @@
return NULL;
}
+ /**
+ @brief Returns a pointer to the section with given name. If it doesn't exist, the section is created.
+ */
ConfigFileSection* ConfigFile::getOrCreateSection(const std::string& section)
{
for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)
@@ -402,6 +473,9 @@
return (*this->sections_.insert(this->sections_.end(), new ConfigFileSection(section)));
}
+ /**
+ @brief Saves the config file if it was updated (or if any of its sections were updated).
+ */
void ConfigFile::saveIfUpdated()
{
bool sectionsUpdated = false;
@@ -441,6 +515,9 @@
SettingsConfigFile* SettingsConfigFile::singletonPtr_s = 0;
+ /**
+ @brief Constructor: Activates the console commands.
+ */
SettingsConfigFile::SettingsConfigFile(const std::string& filename)
: ConfigFile(filename)
{
@@ -451,6 +528,9 @@
ModifyConsoleCommand(__CC_getConfig_name).setObject(this);
}
+ /**
+ @brief Destructor: Deactivates the console commands.
+ */
SettingsConfigFile::~SettingsConfigFile()
{
ModifyConsoleCommand(__CC_load_name).setObject(0);
@@ -460,17 +540,26 @@
ModifyConsoleCommand(__CC_getConfig_name).setObject(0);
}
+ /**
+ @brief Loads the config file and updates the @ref ConfigValueContainer "config value containers".
+ */
void SettingsConfigFile::load()
{
ConfigFile::load();
this->updateConfigValues();
}
+ /**
+ @brief Changes the file-name.
+ */
void SettingsConfigFile::setFilename(const std::string& filename)
{
ConfigFileManager::getInstance().setFilename(ConfigFileType::Settings, filename);
}
+ /**
+ @brief Registers a new @ref ConfigValueContainer "config value container".
+ */
void SettingsConfigFile::addConfigValueContainer(ConfigValueContainer* container)
{
if (container == NULL)
@@ -480,6 +569,9 @@
this->sectionNames_.insert(container->getSectionName());
}
+ /**
+ @brief Unregisters a @ref ConfigValueContainer "config value container".
+ */
void SettingsConfigFile::removeConfigValueContainer(ConfigValueContainer* container)
{
if (container == NULL)
@@ -499,8 +591,13 @@
}
}
+ /**
+ @brief Updates all @ref ConfigValueContainer "config value containers".
+ */
void SettingsConfigFile::updateConfigValues()
{
+ // todo: can this be done more efficiently? looks like some identifiers will be updated multiple times.
+
for (ContainerMap::const_iterator it = this->containers_.begin(); it != this->containers_.end(); ++it)
{
it->second.second->update();
@@ -508,6 +605,10 @@
}
}
+ /**
+ @brief Removes entries and sections from the file that don't exist anymore (i.e. if there's no corresponding @ref ConfigValueContainer "config value container").
+ @param bCleanComments If true, comments are also removed from the file
+ */
void SettingsConfigFile::clean(bool bCleanComments)
{
for (std::list<ConfigFileSection*>::iterator itSection = this->sections_.begin(); itSection != this->sections_.end(); )
@@ -557,18 +658,40 @@
this->save();
}
+ /**
+ @brief Console-command: Changes the value of an entry and stores it the file.
+
+ @param section The section of the config value
+ @param entry The name of the config value
+ @param value The new value
+ */
void SettingsConfigFile::config(const std::string& section, const std::string& entry, const std::string& value)
{
if (!this->configImpl(section, entry, value, &ConfigValueContainer::set))
COUT(1) << "Error: Config value \"" << entry << "\" in section \"" << section << "\" doesn't exist." << std::endl;
}
+ /**
+ @brief Console-command: Changes the value of an entry, but doesn't store it in the file (it's only a temporary change).
+
+ @param section The section of the config value
+ @param entry The name of the config value
+ @param value The new value
+ */
void SettingsConfigFile::tconfig(const std::string& section, const std::string& entry, const std::string& value)
{
if (!this->configImpl(section, entry, value, &ConfigValueContainer::tset))
COUT(1) << "Error: Config value \"" << entry << "\" in section \"" << section << "\" doesn't exist." << std::endl;
}
+ /**
+ @brief Changes the value of an entry, depending on @a function, either by using "set" or "tset"
+
+ @param section The section of the config value
+ @param entry The name of the config value
+ @param value The new value
+ @param function The function ("set" or "tset") that will be used to change the value.
+ */
bool SettingsConfigFile::configImpl(const std::string& section, const std::string& entry, const std::string& value, bool (ConfigValueContainer::*function)(const MultiType&))
{
const std::string& sectionLC = getLowercase(section);
@@ -585,6 +708,12 @@
return false;
}
+ /**
+ @brief Console-command: Returns the value of a given entry.
+
+ @param section The section of the config value
+ @param entry The name of the config value
+ */
std::string SettingsConfigFile::getConfig(const std::string& section, const std::string& entry)
{
const std::string& sectionLC = getLowercase(section);
@@ -610,11 +739,13 @@
ConfigFileManager* ConfigFileManager::singletonPtr_s = 0;
+ /// Constructor: Initializes the array of config files with NULL.
ConfigFileManager::ConfigFileManager()
{
this->configFiles_.assign(NULL);
}
+ /// Destructor: Deletes the config files.
ConfigFileManager::~ConfigFileManager()
{
for (boost::array<ConfigFile*, 3>::const_iterator it = this->configFiles_.begin(); it != this->configFiles_.end(); ++it)
@@ -622,6 +753,7 @@
delete (*it);
}
+ /// Defines the file-name for the config file of a given type (settings, calibration, etc.).
void ConfigFileManager::setFilename(ConfigFileType::Value type, const std::string& filename)
{
if (this->getConfigFile(type))
Modified: code/branches/doc/src/libraries/core/ConfigFileManager.h
===================================================================
--- code/branches/doc/src/libraries/core/ConfigFileManager.h 2010-09-06 22:58:52 UTC (rev 7372)
+++ code/branches/doc/src/libraries/core/ConfigFileManager.h 2010-09-07 21:24:47 UTC (rev 7373)
@@ -29,6 +29,7 @@
/**
@file
@ingroup Config ConfigFile
+ @brief Declaration of ConfigFileManager and its helper classes.
*/
#ifndef _ConfigFileManager_H__
@@ -50,16 +51,35 @@
/////////////////////
// ConfigFileEntry //
/////////////////////
+ /**
+ @brief This class represents an entry in the config file.
+
+ This class is pure virtual. Use one of the derived classes to define the type of the entry.
+ */
class _CoreExport ConfigFileEntry
{
public:
+ /// Destructor
virtual ~ConfigFileEntry() {};
+
+ /// Changes the value of the entry.
virtual void setValue(const std::string& value) = 0;
+ /// Returns the value of the entry.
virtual const std::string& getValue() const = 0;
+
+ /// Returns the name of the entry
virtual const std::string& getName() const = 0;
+
+ /// Changes the comment of the entry (will be placed after the value)
virtual void setComment(const std::string& comment) = 0;
+
+ /// Returns the index of the entry in a vector (used only if it is a vector)
virtual unsigned int getIndex() const { return 0; }
+
+ /// Defines if this entry is treated as string which means some special treatment of special characters.
virtual void setString(bool bString) = 0;
+
+ /// Returns the line as it will be stored in the config file.
virtual const std::string& getFileEntry() const = 0;
};
@@ -67,9 +87,20 @@
//////////////////////////
// ConfigFileEntryValue //
//////////////////////////
+ /**
+ @brief This class represents a normal value in the config file.
+ */
class _CoreExport ConfigFileEntryValue : public ConfigFileEntry
{
public:
+ /**
+ @brief Constructor: Initializes the entry.
+
+ @param name The name of the entry
+ @param value The value of the entry
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ @param additionalComment An optional comment that will be placed behind the value in the config file
+ */
inline ConfigFileEntryValue(const std::string& name, const std::string& value = "", bool bString = false, const std::string& additionalComment = "")
: name_(name)
, value_(value)
@@ -77,6 +108,7 @@
, bString_(bString)
{ this->update(); }
+ /// Destructor
inline virtual ~ConfigFileEntryValue() {}
inline virtual const std::string& getName() const
@@ -96,54 +128,75 @@
inline virtual const std::string& getFileEntry() const
{ return this->fileEntry_; }
+ /// Returns the "key" of the value (in this case it's just the name of the entry, but for vectors it's different)
inline virtual const std::string& getKeyString() const
{ return this->name_; }
protected:
virtual void update();
- const std::string name_;
- std::string value_;
- std::string additionalComment_;
- std::string fileEntry_;
- bool bString_;
+ const std::string name_; ///< The name of the value
+ std::string value_; ///< The value
+ std::string additionalComment_; ///< The additional comment
+ std::string fileEntry_; ///< The string as it will be stored in the config file
+ bool bString_; ///< If true, the value is treated as string which means some special treatment of special characters.
};
////////////////////////////////
// ConfigFileEntryVectorValue //
////////////////////////////////
+ /**
+ @brief Subclass of ConfigFileEntryValue, represents an element of a vector.
+ */
class _CoreExport ConfigFileEntryVectorValue : public ConfigFileEntryValue
{
public:
+ /**
+ @brief Constructor: Initializes the entry.
+
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param value The value of the element
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ @param additionalComment An optional comment that will be placed behind the value in the config file
+ */
inline ConfigFileEntryVectorValue(const std::string& name, unsigned int index, const std::string& value = "", bool bString = false, const std::string& additionalComment = "")
: ConfigFileEntryValue(name, value, bString, additionalComment)
, index_(index)
{ this->update(); /*No virtual calls in base class ctor*/ }
+ /// Destructor
inline ~ConfigFileEntryVectorValue() {}
inline unsigned int getIndex() const
{ return this->index_; }
+ /// Returns the "key" of the value (the name of the vector plus the index of the element)
inline const std::string& getKeyString() const
{ return this->keyString_; }
private:
void update();
- unsigned int index_;
- std::string keyString_;
+ unsigned int index_; ///< The index of the element in the vector
+ std::string keyString_; ///< The full name of the entry (the name of the vector plus the index of the element)
};
////////////////////////////
// ConfigFileEntryComment //
////////////////////////////
+ /**
+ @brief This class represents a line in the config file which contains only a comment.
+ */
class _CoreExport ConfigFileEntryComment : public ConfigFileEntry
{
public:
+ /// Constructor: Initializes the object.
inline ConfigFileEntryComment(const std::string& comment) : comment_(comment) {}
+
+ /// Destructor
inline virtual ~ConfigFileEntryComment() {}
inline virtual const std::string& getName() const
@@ -163,23 +216,31 @@
inline virtual const std::string& getFileEntry() const
{ return this->comment_; }
- inline virtual const std::string& getKeyString() const
- { return BLANKSTRING; }
-
private:
- std::string comment_;
+ std::string comment_; ///< The comment
};
///////////////////////
// ConfigFileSection //
///////////////////////
+ /**
+ @brief Represents a section in a config file.
+
+ A section has a name and a list of config values.
+ */
class _CoreExport ConfigFileSection
{
friend class ConfigFile;
friend class SettingsConfigFile;
public:
+ /**
+ @brief Constructor: Initializes the section.
+
+ @param name The name of the section
+ @param additionalComment An additional comment placed after the title of the section in the config file
+ */
inline ConfigFileSection(const std::string& name, const std::string& additionalComment = "")
: name_(name)
, additionalComment_(additionalComment)
@@ -187,39 +248,84 @@
{}
~ConfigFileSection();
+ /// Returns the name of the section.
inline const std::string& getName() const
{ return this->name_; }
+ /// Changes the comment which is placed after the title of the section in the config file.
inline void setComment(const std::string& comment)
{ this->additionalComment_ = comment; }
+ /**
+ @brief Stores a value in the section. If the entry doesn't exist, it's created.
+
+ @param name The name of the entry
+ @param value The new value
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline void setValue(const std::string& name, const std::string& value, bool bString)
{ this->getOrCreateEntry(name, value, bString)->setValue(value); }
+ /**
+ @brief Returns the value of a given entry in the section. Returns a blank string if the value doesn't exist.
+
+ @param name The name of the entry
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline const std::string& getValue(const std::string& name, bool bString)
{
ConfigFileEntry* entry = this->getEntry(name);
if (entry)
{
- entry->setString(bString);
+ entry->setString(bString); // if the entry was loaded from the config file, we have to tell it if it's a string
return entry->getValue();
}
return BLANKSTRING;
}
+ /**
+ @brief Returns the value of a given entry in the section. If it doesn't exist, the entry is created using the fallback value.
+
+ @param name The name of the entry
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline const std::string& getOrCreateValue(const std::string& name, const std::string& fallback, bool bString)
{ return this->getOrCreateEntry(name, fallback, bString)->getValue(); }
+ /**
+ @brief Stores the value of an element of a vector in the section. If the entry doesn't exist, it's created.
+
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param value The new value
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline void setValue(const std::string& name, unsigned int index, const std::string& value, bool bString)
{ this->getOrCreateEntry(name, index, value, bString)->setValue(value); }
+ /**
+ @brief Returns the value of a given element of a vector in the section. Returns a blank string if the value doesn't exist.
+
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline const std::string& getValue(const std::string& name, unsigned int index, bool bString)
{
ConfigFileEntry* entry = this->getEntry(name, index);
if (entry)
{
- entry->setString(bString);
+ entry->setString(bString); // if the entry was loaded from the config file, we have to tell it if it's a string
return entry->getValue();
}
return BLANKSTRING;
}
+ /**
+ @brief Returns the value of a given element of a vector in the section. If it doesn't exist, the entry is created using the fallback value.
+
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline const std::string& getOrCreateValue(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
{ return this->getOrCreateEntry(name, index, fallback, bString)->getValue(); }
@@ -229,10 +335,13 @@
std::string getFileEntry() const;
private:
+ /// Returns the list of entries in this section.
std::list<ConfigFileEntry*>& getEntries()
{ return this->entries_; }
+ /// Returns the begin-iterator of the list of entries in this section.
std::list<ConfigFileEntry*>::const_iterator getEntriesBegin() const
{ return this->entries_.begin(); }
+ /// Returns the end-iterator of the list of entries in this section.
std::list<ConfigFileEntry*>::const_iterator getEntriesEnd() const
{ return this->entries_.end(); }
@@ -240,22 +349,43 @@
std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString);
ConfigFileEntry* getEntry(const std::string& name) const;
+ /**
+ @brief Returns the entry with given name. If it doesn't exist, the entry is created using the fallback value.
+
+ @param name The name of the entry
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline ConfigFileEntry* getOrCreateEntry(const std::string& name, const std::string& fallback, bool bString)
{ return (*this->getOrCreateEntryIterator(name, fallback, bString)); }
+
ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const;
+ /**
+ @brief Returns the entry that contains an element of a vector with given name. If it doesn't exist, the entry is created using the fallback value.
+
+ @param name The name of the entry
+ @param index The index of the element in the vector
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline ConfigFileEntry* getOrCreateEntry(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
{ return (*this->getOrCreateEntryIterator(name, index, fallback, bString)); }
- std::string name_;
- std::string additionalComment_;
- std::list<ConfigFileEntry*> entries_;
- bool bUpdated_;
+ std::string name_; ///< The name of the section
+ std::string additionalComment_; ///< The additional comment which is placed after the title of the section in the config file
+ std::list<ConfigFileEntry*> entries_; ///< The list of entries in this section
+ bool bUpdated_; ///< True if an entry is created
};
////////////////
// ConfigFile //
////////////////
+ /**
+ @brief This class represents a config file, which is stored on the hard-disk and contains config values in different sections.
+
+ It provides an interface to manipulate the sections and values.
+ */
class _CoreExport ConfigFile
{
public:
@@ -267,59 +397,134 @@
virtual void saveAs(const std::string& filename) const;
virtual void clear();
+ /// Returns the file-name of this config file
inline const std::string& getFilename()
{ return this->filename_; }
+ /**
+ @brief Stores a value in the config file. If the entry or its section doesn't exist, it's created.
+
+ @param section The name of the section
+ @param name The name of the entry
+ @param value The new value
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline void setValue(const std::string& section, const std::string& name, const std::string& value, bool bString)
{
this->getOrCreateSection(section)->setValue(name, value, bString);
this->save();
}
+ /**
+ @brief Returns the value of a given entry in the config file. Returns a blank string if the value doesn't exist.
+
+ @param section The name of the section
+ @param name The name of the entry
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline const std::string& getValue(const std::string& section, const std::string& name, bool bString)
{
ConfigFileSection* sectionPtr = this->getSection(section);
return (sectionPtr ? sectionPtr->getValue(name, bString) : BLANKSTRING);
}
- const std::string& getOrCreateValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString);
+ /**
+ @brief Returns the value of a given entry in the config file. If it doesn't exist, the entry is created using the fallback value.
+ @param section The name of the section
+ @param name The name of the entry
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
+ inline const std::string& getOrCreateValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString)
+ {
+ const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, fallback, bString);
+ this->saveIfUpdated();
+ return output;
+ }
+
+ /**
+ @brief Stores the value of an element of a vector in the config file. If the entry or its section doesn't exist, it's created.
+
+ @param section The name of the section
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param value The new value
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline void setValue(const std::string& section, const std::string& name, unsigned int index, const std::string& value, bool bString)
{
this->getOrCreateSection(section)->setValue(name, index, value, bString);
this->save();
}
+ /**
+ @brief Returns the value of a given element of a vector in the config file. Returns a blank string if the value doesn't exist.
+
+ @param section The name of the section
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
inline const std::string& getValue(const std::string& section, const std::string& name, unsigned int index, bool bString)
{
ConfigFileSection* sectionPtr = this->getSection(section);
return (sectionPtr ? sectionPtr->getValue(name, index, bString) : BLANKSTRING);
}
- const std::string& getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString);
+ /**
+ @brief Returns the value of a given element of a vector in the config file. If it doesn't exist, the entry is created using the fallback value.
+ @param section The name of the section
+ @param name The name of the vector
+ @param index The index of the element in the vector
+ @param fallback The value that will be used if the entry doesn't exist
+ @param bString If true, the value is treated as string which means some special treatment of special characters.
+ */
+ const std::string& getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString)
+ {
+ const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, index, fallback, bString);
+ this->saveIfUpdated();
+ return output;
+ }
+
void deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex = 0);
+ /**
+ @brief Returns the size of a config vector.
+ @param section The section of the vector
+ @param name The name of the vector
+ */
inline unsigned int getVectorSize(const std::string& section, const std::string& name) const
{
ConfigFileSection* sectionPtr = this->getSection(section);
return (sectionPtr ? sectionPtr->getVectorSize(name) : 0);
}
- static const char* DEFAULT_CONFIG_FOLDER;
+ static const char* DEFAULT_CONFIG_FOLDER; ///< The folder where the default config files will be stored
protected:
ConfigFileSection* getSection(const std::string& section) const;
ConfigFileSection* getOrCreateSection(const std::string& section);
- std::list<ConfigFileSection*> sections_;
+ std::list<ConfigFileSection*> sections_; ///< A list of sections in this config file
private:
void saveIfUpdated();
- const std::string filename_;
- const bool bCopyFallbackFile_;
- bool bUpdated_;
+
+ const std::string filename_; ///< The filename of this config file
+ const bool bCopyFallbackFile_; ///< If true, the default config file is copied into the config-directory before loading the file
+ bool bUpdated_; ///< Becomes true if a section is added
};
////////////////////////
// SettingsConfigFile //
////////////////////////
+ /**
+ @brief Child class of ConfigFile, used to store the settings of the game.
+
+ In addition to ConfigFile, this class provides an interface to manipulate the settings
+ with console commands and to cache entries in instances of ConfigValueContainer.
+
+ SettingsConfigFile is a Singleton, meaning there's only one instance of this class
+ (and thus only one config file that stores settings).
+ */
class _CoreExport SettingsConfigFile // tolua_export
: public ConfigFile, public Singleton<SettingsConfigFile>
{ // tolua_export
@@ -342,10 +547,13 @@
void addConfigValueContainer(ConfigValueContainer* container);
void removeConfigValueContainer(ConfigValueContainer* container);
+ /// Returns a set containing the names of all sections in this config file.
inline const std::set<std::string>& getSectionNames()
{ return this->sectionNames_; }
+ /// Returns the lower-bound-iterator of the @ref ConfigValueContainer "config value containers" for the given section.
inline ContainerMap::const_iterator getContainerLowerBound(const std::string section)
{ return this->containers_.lower_bound(section); }
+ /// Returns the upper-bound-iterator of the @ref ConfigValueContainer "config value containers" for the given section.
inline ContainerMap::const_iterator getContainerUpperBound(const std::string section)
{ return this->containers_.upper_bound(section); }
@@ -355,15 +563,18 @@
void updateConfigValues();
bool configImpl(const std::string& section, const std::string& entry, const std::string& value, bool (ConfigValueContainer::*function)(const MultiType&));
- ContainerMap containers_;
- std::set<std::string> sectionNames_;
- static SettingsConfigFile* singletonPtr_s;
+ ContainerMap containers_; ///< Stores all @ref ConfigValueContainer "config value containers"
+ std::set<std::string> sectionNames_; ///< Stores all section names
+ static SettingsConfigFile* singletonPtr_s; ///< The singleton pointer
}; // tolua_export
///////////////////////
// ConfigFileManager //
///////////////////////
+ /**
+ @brief Manages the different config files (settings, calibration, etc). Implemented as Singleton.
+ */
class _CoreExport ConfigFileManager : public Singleton<ConfigFileManager>
{
friend class Singleton<ConfigFileManager>;
@@ -373,6 +584,7 @@
void setFilename(ConfigFileType::Value type, const std::string& filename);
+ /// Returns the config file of a given type (settings, calibration, etc.)
inline ConfigFile* getConfigFile(ConfigFileType::Value type)
{
// Check array bounds
@@ -380,10 +592,10 @@
}
private:
- ConfigFileManager(const ConfigFileManager&);
+ ConfigFileManager(const ConfigFileManager&); ///< Copy-constructor: not implemented
- boost::array<ConfigFile*, 3> configFiles_;
- static ConfigFileManager* singletonPtr_s;
+ boost::array<ConfigFile*, 3> configFiles_; ///< Stores the config files for each type in an array (must have the same size like ConfigFileType::Value)
+ static ConfigFileManager* singletonPtr_s; ///< Stores the singleton-pointer
};
} // tolua_export
Modified: code/branches/doc/src/libraries/core/OrxonoxClass.cc
===================================================================
--- code/branches/doc/src/libraries/core/OrxonoxClass.cc 2010-09-06 22:58:52 UTC (rev 7372)
+++ code/branches/doc/src/libraries/core/OrxonoxClass.cc 2010-09-07 21:24:47 UTC (rev 7373)
@@ -40,7 +40,9 @@
namespace orxonox
{
- /** @brief Constructor: Sets the default values. */
+ /**
+ @brief Constructor: Sets the default values.
+ */
OrxonoxClass::OrxonoxClass()
{
this->identifier_ = 0;
@@ -52,7 +54,9 @@
this->objectPointers_.reserve(6);
}
- /** @brief Destructor: Deletes, if existing, the list of the parents. */
+ /**
+ @brief Destructor: Removes the object from the object-lists, notifies all @ref WeakPtr "weak pointers" that this object is being deleted.
+ */
OrxonoxClass::~OrxonoxClass()
{
// if (!this->requestedDestruction_)
@@ -71,7 +75,9 @@
(*(it++))->objectDeleted();
}
- /** @brief Deletes the object if no smart pointers point to this object. Otherwise schedules the object to be deleted as soon as possible. */
+ /**
+ @brief Deletes the object if no @ref orxonox::SmartPtr "smart pointers" point to this object. Otherwise schedules the object to be deleted as soon as possible.
+ */
void OrxonoxClass::destroy()
{
assert(this); // Just in case someone tries to delete a NULL pointer
@@ -84,6 +90,9 @@
}
}
+ /**
+ @brief Removes this object from the object-lists.
+ */
void OrxonoxClass::unregisterObject()
{
if (this->metaList_)
@@ -91,42 +100,42 @@
this->metaList_ = 0;
}
- /** @brief Returns true if the objects class is of the given type or a derivative. */
+ /// Returns true if the object's class is of the given type or a derivative.
bool OrxonoxClass::isA(const Identifier* identifier)
{ return this->getIdentifier()->isA(identifier); }
- /** @brief Returns true if the objects class is exactly of the given type. */
+ /// Returns true if the object's class is exactly of the given type.
bool OrxonoxClass::isExactlyA(const Identifier* identifier)
{ return this->getIdentifier()->isExactlyA(identifier); }
- /** @brief Returns true if the objects class is a child of the given type. */
+ /// Returns true if the object's class is a child of the given type.
bool OrxonoxClass::isChildOf(const Identifier* identifier)
{ return this->getIdentifier()->isChildOf(identifier); }
- /** @brief Returns true if the objects class is a direct child of the given type. */
+ /// Returns true if the object's class is a direct child of the given type.
bool OrxonoxClass::isDirectChildOf(const Identifier* identifier)
{ return this->getIdentifier()->isDirectChildOf(identifier); }
- /** @brief Returns true if the objects class is a parent of the given type. */
+ /// Returns true if the object's class is a parent of the given type.
bool OrxonoxClass::isParentOf(const Identifier* identifier)
{ return this->getIdentifier()->isParentOf(identifier); }
- /** @brief Returns true if the objects class is a direct parent of the given type. */
+ /// Returns true if the object's class is a direct parent of the given type.
bool OrxonoxClass::isDirectParentOf(const Identifier* identifier)
{ return this->getIdentifier()->isDirectParentOf(identifier); }
- /** @brief Returns true if the objects class is of the given type or a derivative. */
+ /// Returns true if the object's class is of the given type or a derivative.
bool OrxonoxClass::isA(const OrxonoxClass* object)
{ return this->getIdentifier()->isA(object->getIdentifier()); }
- /** @brief Returns true if the objects class is exactly of the given type. */
+ /// Returns true if the object's class is exactly of the given type.
bool OrxonoxClass::isExactlyA(const OrxonoxClass* object)
{ return this->getIdentifier()->isExactlyA(object->getIdentifier()); }
- /** @brief Returns true if the objects class is a child of the given type. */
+ /// Returns true if the object's class is a child of the given type.
bool OrxonoxClass::isChildOf(const OrxonoxClass* object)
{ return this->getIdentifier()->isChildOf(object->getIdentifier()); }
- /** @brief Returns true if the objects class is a direct child of the given type. */
+ /// Returns true if the object's class is a direct child of the given type.
bool OrxonoxClass::isDirectChildOf(const OrxonoxClass* object)
{ return this->getIdentifier()->isDirectChildOf(object->getIdentifier()); }
- /** @brief Returns true if the objects class is a parent of the given type. */
+ /// Returns true if the object's class is a parent of the given type.
bool OrxonoxClass::isParentOf(const OrxonoxClass* object)
{ return this->getIdentifier()->isParentOf(object->getIdentifier()); }
- /** @brief Returns true if the objects class is a direct child of the given type. */
+ /// Returns true if the object's class is a direct child of the given type.
bool OrxonoxClass::isDirectParentOf(const OrxonoxClass* object)
{ return this->getIdentifier()->isDirectParentOf(object->getIdentifier()); }
}
Modified: code/branches/doc/src/libraries/core/OrxonoxClass.h
===================================================================
--- code/branches/doc/src/libraries/core/OrxonoxClass.h 2010-09-06 22:58:52 UTC (rev 7372)
+++ code/branches/doc/src/libraries/core/OrxonoxClass.h 2010-09-07 21:24:47 UTC (rev 7373)
@@ -62,7 +62,8 @@
@brief The class all objects and interfaces of the game-logic (not the engine) are derived from.
The BaseObject and Interfaces are derived with @c virtual @c public @c OrxonoxClass from OrxonoxClass.
- OrxonoxClass is needed to create the class-hierarchy at startup and to store the Identifier and the MetaObjectList.
+ OrxonoxClass is needed to create the class-hierarchy at startup and to store the Identifier and the
+ MetaObjectList, as well as to provide an interface for SmartPtr and WeakPtr.
*/
class _CoreExport OrxonoxClass
{
@@ -95,16 +96,22 @@
bool isParentOf(const Identifier* identifier);
bool isDirectParentOf(const Identifier* identifier);
+ /// Returns true if the object's class is of the given type or a derivative.
template <class B> inline bool isA(const SubclassIdentifier<B>* identifier)
{ return this->isA(*identifier); }
+ /// Returns true if the object's class is exactly of the given type.
template <class B> inline bool isExactlyA(const SubclassIdentifier<B>* identifier)
{ return this->isExactlyA(*identifier); }
+ /// Returns true if the object's class is a child of the given type.
template <class B> inline bool isChildOf(const SubclassIdentifier<B>* identifier)
{ return this->isChildOf(*identifier); }
+ /// Returns true if the object's class is a direct child of the given type.
template <class B> inline bool isDirectChildOf(const SubclassIdentifier<B>* identifier)
{ return this->isDirectChildOf(*identifier); }
+ /// Returns true if the object's class is a parent of the given type.
template <class B> inline bool isParentOf(const SubclassIdentifier<B>* identifier)
{ return this->isParentOf(*identifier); }
+ /// Returns true if the object's class is a direct parent of the given type.
template <class B> inline bool isDirectParentOf(const SubclassIdentifier<B>* identifier)
{ return this->isDirectParentOf(*identifier); }
@@ -117,6 +124,7 @@
virtual void clone(OrxonoxClass*& item) {}
+ /// Returns the number of @ref orxonox::SmartPtr "smart pointers" that point to this object.
inline unsigned int getReferenceCount() const
{ return this->referenceCount_; }
@@ -145,6 +153,7 @@
{ return const_cast<OrxonoxClass*>(this)->getDerivedPointer<T>(classID); }
protected:
+ /// This virtual function is called if destroy() is called and no SmartPtr points to this object. Used in some cases to create a new SmartPtr to prevent destruction.
virtual void preDestroy() {}
private:
@@ -168,12 +177,12 @@
inline void unregisterWeakPtr(WeakPtr<T>* pointer)
{ this->weakPointers_.erase(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
- Identifier* identifier_; //!< The Identifier of the object
- std::set<const Identifier*>* parents_; //!< List of all parents of the object
- MetaObjectList* metaList_; //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
- int referenceCount_; //!< Counts the references from smart pointers to this object
- bool requestedDestruction_; //!< Becomes true after someone called delete on this object
- std::set<WeakPtr<OrxonoxClass>*> weakPointers_; //!< All weak pointers which point to this object (and like to get notified if it dies)
+ Identifier* identifier_; //!< The Identifier of the object
+ std::set<const Identifier*>* parents_; //!< List of all parents of the object
+ MetaObjectList* metaList_; //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
+ int referenceCount_; //!< Counts the references from smart pointers to this object
+ bool requestedDestruction_; //!< Becomes true after someone called delete on this object
+ std::set<WeakPtr<OrxonoxClass>*> weakPointers_; //!< All weak pointers which point to this object (and like to get notified if it dies)
/// 'Fast map' that holds this-pointers of all derived types
std::vector<std::pair<unsigned int, void*> > objectPointers_;
Modified: code/branches/doc/src/libraries/core/SmartPtr.h
===================================================================
--- code/branches/doc/src/libraries/core/SmartPtr.h 2010-09-06 22:58:52 UTC (rev 7372)
+++ code/branches/doc/src/libraries/core/SmartPtr.h 2010-09-07 21:24:47 UTC (rev 7373)
@@ -36,6 +36,83 @@
/**
@file
@ingroup Object SmartPtr
+ @brief Definition of SmartPtr<T>.
+
+ @anchor SmartPtrExample
+
+ orxonox::SmartPtr is an implementation of a smart pointer - it wraps a pointer to an
+ object and keeps this object alive until no SmartPtr points to this object anymore.
+ In contrast to orxonox::SharedPtr, SmartPtr works only with classes that are derived
+ from orxonox::OrxonoxClass, because it's an intrusive implementation, meaning the
+ reference counter is stored in the object itself.
+
+ It's possible to use normal pointers and smart pointers to an object simultaneously.
+ You don't have to use SmartPtr all the time, you can create a SmartPtr for an object
+ at any time and also convert it back to a normal pointer if you like. This is possible
+ because the reference counter is stored in the object itself and not in SmartPtr (in
+ contrast to SharedPtr).
+
+ @b Important: If you want to delete an object, you must not use @c delete @c object but
+ rather @c object->destroy(). This function will check if there are smart pointers
+ pointing to the object. If yes, the object will be kept alive until all smart pointes
+ are destroyed. If no, the object is deleted instantly.
+
+ If all smart pointers that point to an object are destroyed, but you never called
+ @c object->destroy() before, the object will not be deleted! All a SmartPtr will do
+ is to really just keep an object alive, but it will not delete it automatically
+ unless you tried to destroy it before.
+
+ Example:
+ @code
+ class MyClass // class declaration
+ {
+ public:
+ void setObject(OtherClass* object) // passes a normal pointer which will be stored in a SmartPtr
+ { this->object_ = object; }
+
+ OtherClass* getObject() const // converts the SmartPtr to a normal pointer and returns it
+ { return this->object_; }
+
+ private:
+ SmartPtr<OtherClass> object_; // a pointer to an instance of OtherClass is stored in a SmartPtr
+ };
+ @endcode
+ In this example we assume that OtherClass is a child of OrxonoxClass. We don't care
+ about the inheritance of MyClass though.
+
+ Now we create an instance of MyClass and assign a pointer to an instance of OtherClass:
+ @code
+ MyClass* myclass = new MyClass(); // create an instance of MyClass
+ OtherClass* object = new OtherClass(); // create an instance of OtherClass
+ myclass->setObject(object); // the object is now stored in a SmartPtr inside myclass
+
+ object->destroy(); // we try to destroy object, but there's still a SmartPtr pointing at it.
+
+ # object still exists at this point (because a SmartPtr points at it)
+
+ delete myclass; // now we delete myclass, which also destroys the SmartPtr
+
+ # object doesn't exist anymore (because the SmartPtr is now destroyed)
+ @endcode
+
+ Now we look at the same example, but we first delete myclass, then destroy object:
+ @code
+ MyClass* myclass = new MyClass(); // create an instance of MyClass
+ OtherClass* object = new OtherClass(); // create an instance of OtherClass
+ myclass->setObject(object); // the object is now stored in a SmartPtr inside myclass
+
+ delete myclass; // we delete myclass, which also destroys the SmartPtr
+
+ # object still exists at this point (because destroy() was not called yet)
+
+ object->destroy(); // now we try to destroy object, which works instantly
+
+ # object doesn't exist anymore (because we just destroyed it)
+ @endcode
+
+ Note that in any case @c object->destroy() has to be called to delete the object.
+ However if a SmartPtr points at it, the destruction is delayed until all SmartPtr
+ are destroyed.
*/
#ifndef _SmartPtr_H__
@@ -51,30 +128,40 @@
namespace orxonox
{
+ /**
+ @brief A smart pointer which wraps a pointer to an object and keeps this object alive as long as the smart pointer exists.
+
+ @see See @ref SmartPtrExample "this description" for more information and an example.
+ */
template <class T>
class SmartPtr
{
public:
+ /// Constructor: Initializes the smart pointer with a null pointer.
inline SmartPtr() : pointer_(0), base_(0)
{
}
+ /// Constructor: Used to explicitly initialize the smart pointer with a null pointer
inline SmartPtr(int) : pointer_(0), base_(0)
{
}
+ /// Constructor: Initializes the smart pointer with a pointer to an object. @param pointer The pointer @param bAddRef If true, the reference counter is increased. Don't set this to false unless you know exactly what you're doing! (for example to avoid circular references if the @c this pointer of the possessing object is stored)
inline SmartPtr(T* pointer, bool bAddRef = true) : pointer_(pointer), base_(pointer)
{
if (this->base_ && bAddRef)
this->base_->incrementReferenceCount();
}
+ /// Copy-constructor
inline SmartPtr(const SmartPtr& other) : pointer_(other.pointer_), base_(other.base_)
{
if (this->base_)
this->base_->incrementReferenceCount();
}
+ /// Copy-constructor for smart pointers to objects of another class.
template <class O>
inline SmartPtr(const SmartPtr<O>& other) : pointer_(other.get()), base_(other.base_)
{
@@ -82,6 +169,7 @@
this->base_->incrementReferenceCount();
}
+ /// Constructor: Initializes the smart pointer with the pointer that is stored in a WeakPtr.
template <class O>
inline SmartPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.getBase())
{
@@ -89,30 +177,35 @@
this->base_->incrementReferenceCount();
}
+ /// Destructor: Decrements the reference counter.
inline ~SmartPtr()
{
if (this->base_)
this->base_->decrementReferenceCount();
}
+ /// Used to assign a null pointer.
inline SmartPtr& operator=(int)
{
SmartPtr(0).swap(*this);
return *this;
}
+ /// Assigns a new pointer.
inline SmartPtr& operator=(T* pointer)
{
SmartPtr(pointer).swap(*this);
return *this;
}
+ /// Assigns the wrapped pointer of another SmartPtr.
inline SmartPtr& operator=(const SmartPtr& other)
{
SmartPtr(other).swap(*this);
return *this;
}
+ /// Assigns the wrapped pointer of a SmartPtr of another class
template <class O>
inline SmartPtr& operator=(const SmartPtr<O>& other)
{
@@ -120,6 +213,7 @@
return *this;
}
+ /// Assigns the wrapped pointer of a WeakPtr.
template <class O>
inline SmartPtr& operator=(const WeakPtr<O>& other)
{
@@ -127,38 +221,45 @@
return *this;
}
+ /// Returns the wrapped pointer as @c T*
inline T* get() const
{
return this->pointer_;
}
+ /// Returns the wrapped pointer as @c OrxonoxClass*
inline OrxonoxClass* getBase() const
{
return this->base_;
}
+ /// Implicitly converts the SmartPtr to a pointer of type @c T*
inline operator T*() const
{
return this->pointer_;
}
+ /// Overloaded operator, returns a pointer to the stored object.
inline T* operator->() const
{
assert(this->pointer_ != 0);
return this->pointer_;
}
+ /// Overloaded operator, returns a reference to the stored object.
inline T& operator*() const
{
assert(this->pointer_ != 0);
return *this->pointer_;
}
+ /// Returns true if the wrapped pointer is NULL.
inline bool operator!() const
{
return (this->pointer_ == 0);
}
+ /// Swaps the contents of two smart pointers.
inline void swap(SmartPtr& other)
{
{
@@ -173,34 +274,39 @@
}
}
+ /// Resets the smart pointer (equivalent to assigning a NULL pointer).
inline void reset()
{
SmartPtr().swap(*this);
}
private:
- T* pointer_;
- OrxonoxClass* base_;
+ T* pointer_; ///< The wrapped pointer to an object of type @a T
+ OrxonoxClass* base_; ///< The wrapped pointer, casted up to OrxonoxClass (this is needed because with just a T* pointer, SmartPtr couln't be used with forward declarations)
};
+ /// Swaps the contents of two smart pointers.
template <class T>
void swap(SmartPtr<T>& a, SmartPtr<T>& b)
{
a.swap(b);
}
+ /// Uses a static_cast to cast a pointer of type U* to a pointer of type T* and returns it in a new SmartPtr<T>.
template <class T, class U>
SmartPtr<T> static_pointer_cast(const SmartPtr<U>& p)
{
return static_cast<T*>(p.get());
}
+ /// Uses a const_cast to cast a pointer of type U* to a pointer of type T* and returns it in a new SmartPtr<T>.
template <class T, class U>
SmartPtr<T> const_pointer_cast(const SmartPtr<U>& p)
{
return const_cast<T*>(p.get());
}
+ /// Uses a dynamic_cast to cast a pointer of type U* to a pointer of type T* and returns it in a new SmartPtr<T>.
template <class T, class U>
SmartPtr<T> dynamic_pointer_cast(const SmartPtr<U>& p)
{
Modified: code/branches/doc/src/libraries/core/WeakPtr.h
===================================================================
--- code/branches/doc/src/libraries/core/WeakPtr.h 2010-09-06 22:58:52 UTC (rev 7372)
+++ code/branches/doc/src/libraries/core/WeakPtr.h 2010-09-07 21:24:47 UTC (rev 7373)
@@ -31,6 +31,50 @@
/**
@file
@ingroup Object SmartPtr
+ @brief Definition of WeakPtr<T>.
+
+ @anchor WeakPtrExample
+
+ A WeakPtr wraps a pointer to an object. If the object gets deleted, the WeakPtr becomes
+ NULL. This can be used to store pointers to objects without knowing when they will be
+ destroyed.
+
+ WeakPtr works only with objects that are derived from orxonox::OrxonoxClass, because
+ WeakPtr is intrusive and registers itself in the stored object, to get a notification if
+ the object is being deleted.
+
+ Example:
+ @code
+ MyClass* object = new MyClass(); // create an instance of MyClass
+
+ WeakPtr<MyClass> pointer = object; // create a WeakPtr and assign the object
+
+ if (pointer) // checks if pointer is not NULL (which is true)
+ pointer->someFunction(); // calls MyClass::someFunction()
+
+ object->destroy(); // calls destroy() which deletes the object
+
+ if (pointer) // checks if pointer is not NULL (which is now false)
+ pointer->someFunction(); // this will not be executed
+ @endcode
+ In this example we assumed that MyClass is derived of OrxonoxClass (otherwise it couldn't
+ be used with a WeakPtr).
+
+ A callback can be registerd with the WeakPtr that will be called if the object gets deleted.
+ @code
+ void myCallback() // definition of the callback function
+ {
+ COUT(0) << "Object destroyed" << std::endl;
+ }
+
+ MyClass* object = new MyClass(); // create an instance of MyClass
+
+ WeakPtr<MyClass> pointer = object; // create a WeakPtr and assign the object
+
+ pointer.setCallback(createFunctor(&myCallback)); // defines a callback
+
+ object->destroy(); // calls destroy() which deletes the object. prints "Object destroyed" to the console
+ @endcode
*/
#ifndef _WeakPtr_H__
@@ -45,32 +89,42 @@
namespace orxonox
{
+ /**
+ @brief WeakPtr wraps a pointer to an object, which becomes NULL if the object is deleted.
+
+ @see See @ref WeakPtrExample "this description" for more information and an example.
+ */
template <class T>
class WeakPtr
{
friend class OrxonoxClass;
public:
+ /// Constructor: Initializes the weak pointer with a null pointer.
inline WeakPtr() : pointer_(0), base_(0), callback_(0)
{
}
+ /// Constructor: Used to explicitly initialize the weak pointer with a null pointer
inline WeakPtr(int) : pointer_(0), base_(0), callback_(0)
{
}
+ /// Constructor: Initializes the weak pointer with a pointer to an object.
inline WeakPtr(T* pointer) : pointer_(pointer), base_(pointer), callback_(0)
{
if (this->base_)
this->base_->registerWeakPtr(this);
}
+ /// Copy-constructor
inline WeakPtr(const WeakPtr& other) : pointer_(other.pointer_), base_(other.base_), callback_(0)
{
if (this->base_)
this->base_->registerWeakPtr(this);
}
+ /// Copy-constructor for weak pointers to objects of another class.
template <class O>
inline WeakPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.base_), callback_(0)
{
@@ -78,6 +132,7 @@
this->base_->registerWeakPtr(this);
}
+ /// Destructor
inline ~WeakPtr()
{
if (this->base_)
@@ -85,24 +140,28 @@
}
+ /// Used to assign a null pointer.
inline WeakPtr& operator=(int)
{
WeakPtr(0).swap(*this);
return *this;
}
+ /// Assigns a new pointer.
inline WeakPtr& operator=(T* pointer)
{
WeakPtr(pointer).swap(*this);
return *this;
}
+ /// Assigns the wrapped pointer of another WeakPtr.
inline WeakPtr& operator=(const WeakPtr& other)
{
WeakPtr(other).swap(*this);
return *this;
}
+ /// Assigns the wrapped pointer of a WeakPtr of another class
template <class O>
inline WeakPtr& operator=(const WeakPtr<O>& other)
{
@@ -110,38 +169,45 @@
return *this;
}
+ /// Returns the wrapped pointer as @c T*
inline T* get() const
{
return this->pointer_;
}
+ /// Returns the wrapped pointer as @c OrxonoxClass*
inline OrxonoxClass* getBase() const
{
return this->base_;
}
+ /// Implicitly converts the WeakPtr to a pointer of type @c T*
inline operator T*() const
{
return this->pointer_;
}
+ /// Overloaded operator, returns a pointer to the stored object.
inline T* operator->() const
{
assert(this->pointer_ != 0);
return this->pointer_;
}
+ /// Overloaded operator, returns a reference to the stored object.
inline T& operator*() const
{
assert(this->pointer_ != 0);
return *this->pointer_;
}
+ /// Returns true if the wrapped pointer is NULL.
inline bool operator!() const
{
return (this->pointer_ == 0);
}
+ /// Swaps the contents of two weak pointers.
inline void swap(WeakPtr& other)
{
if (this->base_)
@@ -166,22 +232,26 @@
other.base_->registerWeakPtr(&other);
}
+ /// Resets the weak pointer (equivalent to assigning a NULL pointer).
inline void reset()
{
WeakPtr().swap(*this);
}
+ /// Registers a callback that will be executed if the stored object is destroyed.
inline void setCallback(const FunctorPtr& callback)
{
this->callback_ = callback;
}
+ /// Returns the registered callback.
inline const FunctorPtr& getCallback() const
{
return this->callback_;
}
private:
+ /// Will be called by OrxonoxClass::~OrxonoxClass() if the stored object is deleted. Resets the wrapped pointer and executes the callback.
inline void objectDeleted()
{
this->base_ = 0;
@@ -190,29 +260,33 @@
(*this->callback_)();
}
- T* pointer_;
- OrxonoxClass* base_;
- FunctorPtr callback_;
+ T* pointer_; ///< The wrapped pointer to an object of type @a T
+ OrxonoxClass* base_; ///< The wrapped pointer, casted up to OrxonoxClass (this is needed because with just a T* pointer, WeakPtr couln't be used with forward declarations)
+ FunctorPtr callback_; ///< This callback will be executed if the stored object is deleted
};
+ /// Swaps the contents of two weak pointers.
template <class T>
void swap(WeakPtr<T>& a, WeakPtr<T>& b)
{
a.swap(b);
}
+ /// Uses a static_cast to cast a pointer of type U* to a pointer of type T* and returns it in a new WeakPtr<T>.
template <class T, class U>
WeakPtr<T> static_pointer_cast(const WeakPtr<U>& p)
{
return static_cast<T*>(p.get());
}
+ /// Uses a const_cast to cast a pointer of type U* to a pointer of type T* and returns it in a new WeakPtr<T>.
template <class T, class U>
WeakPtr<T> const_pointer_cast(const WeakPtr<U>& p)
{
return const_cast<T*>(p.get());
}
+ /// Uses a dynamic_cast to cast a pointer of type U* to a pointer of type T* and returns it in a new WeakPtr<T>.
template <class T, class U>
WeakPtr<T> dynamic_pointer_cast(const WeakPtr<U>& p)
{
More information about the Orxonox-commit
mailing list