Changeset 9559
- Timestamp:
- Mar 23, 2013, 9:57:41 PM (12 years ago)
- Location:
- code/branches/core6/src/libraries
- Files:
-
- 12 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core6/src/libraries/core/CMakeLists.txt
r9558 r9559 54 54 BUILD_UNIT FilesystemBuildUnit.cc 55 55 command/ArgumentCompletionFunctions.cc 56 config/ConfigFile Manager.cc56 config/ConfigFile.cc 57 57 PathConfig.cc 58 58 END_BUILD_UNIT … … 74 74 TOLUA_FILES 75 75 command/CommandExecutor.h 76 config/ ConfigFileManager.h76 config/SettingsConfigFile.h 77 77 Game.h 78 78 GameMode.h -
code/branches/core6/src/libraries/core/command/ArgumentCompletionFunctions.cc
r9558 r9559 40 40 #include "util/StringUtils.h" 41 41 #include "core/Identifier.h" 42 #include "core/config/ ConfigFileManager.h"42 #include "core/config/SettingsConfigFile.h" 43 43 #include "core/config/ConfigValueContainer.h" 44 44 #include "CommandExecutor.h" -
code/branches/core6/src/libraries/core/config/CMakeLists.txt
r9558 r9559 1 1 ADD_SOURCE_FILES(CORE_SRC_FILES 2 # ConfigFile.cc is already included in FilesystemBuildUnit.cc 3 ConfigFileEntryValue.cc 4 ConfigFileEntryVectorValue.cc 5 ConfigFileManager.cc 6 ConfigFileSection.cc 2 7 ConfigValueContainer.cc 8 SettingsConfigFile.cc 3 9 ) -
code/branches/core6/src/libraries/core/config/ConfigFileManager.cc
r9558 r9559 29 29 /** 30 30 @file 31 @brief Implementation of ConfigFileManager and its helper classes.31 @brief Implementation of ConfigFileManager. 32 32 */ 33 33 34 34 #include "ConfigFileManager.h" 35 35 36 #include <boost/filesystem.hpp> 37 38 #include "util/Convert.h" 39 #include "util/Math.h" 40 #include "util/StringUtils.h" 41 #include "core/PathConfig.h" 42 #include "core/command/ConsoleCommand.h" 43 #include "ConfigValueContainer.h" 36 #include "SettingsConfigFile.h" 44 37 45 38 namespace orxonox 46 39 { 47 //////////////////////////48 // ConfigFileEntryValue //49 //////////////////////////50 /**51 @brief Updates the string that will be stored in the file after one of it's components (name, value, comment) has changed.52 */53 void ConfigFileEntryValue::update()54 {55 // Make sure we remove the quotes when bString changes56 if (this->bString_)57 this->value_ = stripEnclosingQuotes(this->value_);58 // Assemble the entry line59 this->fileEntry_ = this->getKeyString() + " = ";60 if (this->bString_ && !this->value_.empty())61 this->fileEntry_ += '"' + addSlashes(this->value_) + '"';62 else63 this->fileEntry_ += this->value_;64 if (!this->additionalComment_.empty())65 this->fileEntry_ += ' ' + this->additionalComment_;66 }67 68 69 ////////////////////////////////70 // ConfigFileEntryVectorValue //71 ////////////////////////////////72 /**73 @brief Updates the string that will be stored in the file after one of it's components (name, value, index, comment) has changed.74 */75 void ConfigFileEntryVectorValue::update()76 {77 this->keyString_ = this->name_ + '[' + multi_cast<std::string>(this->index_) + ']';78 ConfigFileEntryValue::update();79 }80 81 82 ///////////////////////83 // ConfigFileSection //84 ///////////////////////85 /**86 @brief Destructor: Deletes all entries.87 */88 ConfigFileSection::~ConfigFileSection()89 {90 for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); )91 delete (*(it++));92 }93 94 /**95 @brief Deletes all elements of a config vector if their index is greater or equal to @a startindex.96 97 @param name The name of the vector98 @param startindex The index of the first element that will be deleted99 */100 void ConfigFileSection::deleteVectorEntries(const std::string& name, unsigned int startindex)101 {102 for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); )103 {104 if (((*it)->getName() == name) && ((*it)->getIndex() >= startindex))105 {106 delete (*it);107 this->entries_.erase(it++);108 }109 else110 {111 ++it;112 }113 }114 }115 116 /**117 @brief Returns the size of a config vector.118 @param name The name of the vector119 */120 unsigned int ConfigFileSection::getVectorSize(const std::string& name) const121 {122 unsigned int size = 0;123 for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)124 if ((*it)->getName() == name)125 if ((*it)->getIndex() >= size)126 size = (*it)->getIndex() + 1;127 return size;128 }129 130 /**131 @brief Returns the title and comment of the section as it will be stored in the file.132 */133 std::string ConfigFileSection::getFileEntry() const134 {135 if (this->additionalComment_.empty())136 return ('[' + this->name_ + ']');137 else138 return ('[' + this->name_ + "] " + this->additionalComment_);139 }140 141 /**142 @brief Returns the entry with given name (or NULL if it doesn't exist).143 144 @param name The name of the entry145 */146 ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name) const147 {148 for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)149 {150 if ((*it)->getName() == name)151 return *it;152 }153 return NULL;154 }155 156 /**157 @brief Returns the entry of a vector element with given name and index (or NULL if it doesn't exist).158 159 @param name The name of the vector160 @param index The index of the element in the vector161 */162 ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name, unsigned int index) const163 {164 for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)165 {166 if (((*it)->getName() == name) && ((*it)->getIndex() == index))167 return *it;168 }169 return NULL;170 }171 172 /**173 @brief Returns the iterator to the entry with given name. If the entry doesn't exist, it is created using the fallback value.174 175 @param name The name of the entry176 @param fallback The value that will be used if the entry doesn't exist177 @param bString If true, the value is treated as string which means some special treatment of special characters.178 */179 std::list<ConfigFileEntry*>::iterator ConfigFileSection::getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString)180 {181 for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)182 {183 if ((*it)->getName() == name)184 {185 (*it)->setString(bString);186 return it;187 }188 }189 190 this->bUpdated_ = true;191 192 return this->entries_.insert(this->entries_.end(), new ConfigFileEntryValue(name, fallback, bString));193 }194 195 /**196 @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.197 198 @param name The name of the vector199 @param index The index of the element in the vector200 @param fallback The value that will be used if the entry doesn't exist201 @param bString If true, the value is treated as string which means some special treatment of special characters.202 */203 std::list<ConfigFileEntry*>::iterator ConfigFileSection::getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString)204 {205 for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)206 {207 if (((*it)->getName() == name) && ((*it)->getIndex() == index))208 {209 (*it)->setString(bString);210 return it;211 }212 }213 214 this->bUpdated_ = true;215 216 if (index == 0)217 return this->entries_.insert(this->entries_.end(), new ConfigFileEntryVectorValue(name, index, fallback, bString));218 else219 return this->entries_.insert(++this->getOrCreateEntryIterator(name, index - 1, "", bString), new ConfigFileEntryVectorValue(name, index, fallback, bString));220 }221 222 223 ////////////////224 // ConfigFile //225 ////////////////226 227 const char* ConfigFile::DEFAULT_CONFIG_FOLDER = "defaultConfig";228 229 /**230 @brief Constructor: Initializes the config file.231 @param filename The file-name of this config file232 @param bCopyFallbackFile If true, the default config file is copied into the config-directory before loading the file233 */234 ConfigFile::ConfigFile(const std::string& filename, bool bCopyFallbackFile)235 : filename_(filename)236 , bCopyFallbackFile_(bCopyFallbackFile)237 , bUpdated_(false)238 {239 }240 241 /**242 @brief Destructor: Deletes all sections and entries.243 */244 ConfigFile::~ConfigFile()245 {246 this->clear();247 }248 249 /**250 @brief Loads the config file from the hard-disk and reads the sections and their values.251 */252 void ConfigFile::load()253 {254 // Be sure we start from new in the memory255 this->clear();256 257 boost::filesystem::path filepath(this->filename_);258 if (!filepath.is_complete())259 {260 filepath = PathConfig::getConfigPath() / filepath;261 if (this->bCopyFallbackFile_)262 {263 // Look for default file in the data folder264 if (!boost::filesystem::exists(filepath))265 {266 boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / DEFAULT_CONFIG_FOLDER / this->filename_);267 if (boost::filesystem::exists(defaultFilepath))268 {269 // Try to copy default file from the data folder270 try271 {272 boost::filesystem::copy_file(defaultFilepath, filepath);273 orxout(internal_info, context::config) << "Copied " << this->filename_ << " from the default config folder." << endl;274 }275 catch (const boost::filesystem::filesystem_error& ex)276 { orxout(user_error, context::config) << "Error in ConfigFile: " << ex.what() << endl; }277 }278 }279 }280 }281 282 // Open the file283 std::ifstream file;284 file.open(filepath.string().c_str(), std::fstream::in);285 if (file.is_open())286 {287 ConfigFileSection* newsection = 0;288 289 while (file.good() && !file.eof())290 {291 std::string line;292 std::getline(file, line);293 294 const std::string& temp = getStripped(line);295 if (!isEmpty(temp) && !isComment(temp))296 {297 size_t pos1 = temp.find('[');298 if (pos1 == 0) pos1 = line.find('['); else pos1 = std::string::npos;299 size_t pos2 = line.find(']');300 301 if (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1)302 {303 // New section304 const std::string& comment = line.substr(pos2 + 1);305 if (isComment(comment))306 newsection = new ConfigFileSection(line.substr(pos1 + 1, pos2 - pos1 - 1), comment);307 else308 newsection = new ConfigFileSection(line.substr(pos1 + 1, pos2 - pos1 - 1));309 this->sections_.insert(this->sections_.end(), newsection);310 continue;311 }312 }313 314 if (newsection != 0)315 {316 if (isComment(line))317 {318 // New comment319 newsection->getEntries().insert(newsection->getEntries().end(), new ConfigFileEntryComment(removeTrailingWhitespaces(line)));320 continue;321 }322 else323 {324 size_t pos1 = line.find('=');325 326 if (pos1 != std::string::npos && pos1 > 0)327 {328 // New entry329 size_t pos2 = line.find('[');330 size_t pos3 = line.find(']');331 size_t commentposition = getNextCommentPosition(line, pos1 + 1);332 while (isBetweenQuotes(line, commentposition))333 {334 commentposition = getNextCommentPosition(line, commentposition + 1);335 }336 std::string value, comment;337 if (commentposition == std::string::npos)338 {339 value = line.substr(pos1 + 1);340 }341 else342 {343 value = line.substr(pos1 + 1, commentposition - pos1 - 1);344 comment = removeTrailingWhitespaces(line.substr(commentposition));345 }346 347 value = removeTrailingWhitespaces(value);348 value = removeSlashes(value);349 350 if (pos2 != std::string::npos && pos3 != std::string::npos && pos3 > pos2 + 1)351 {352 // There might be an array index353 unsigned int index = 0;354 if (convertValue(&index, line.substr(pos2 + 1, pos3 - pos2 - 1)))355 {356 // New array357 std::list<ConfigFileEntry*>::iterator it = newsection->getOrCreateEntryIterator(getStripped(line.substr(0, pos2)), index, value, false);358 (*it)->setValue(value);359 (*it)->setComment(comment);360 continue;361 }362 }363 364 // New value365 newsection->getEntries().insert(newsection->getEntries().end(), new ConfigFileEntryValue(getStripped(line.substr(0, pos1)), value, false, comment));366 continue;367 }368 }369 }370 }371 372 file.close();373 374 orxout(internal_info, context::config) << "Loaded config file \"" << this->filename_ << "\"." << endl;375 376 // DO NOT save the file --> we can open supposedly read only config files377 } // end file.is_open()378 }379 380 /**381 @brief Writes the sections and values to the hard-disk.382 */383 void ConfigFile::save() const384 {385 this->saveAs(this->filename_);386 }387 388 /**389 @brief Writes the sections and values to a given file on the hard-disk.390 */391 void ConfigFile::saveAs(const std::string& filename) const392 {393 boost::filesystem::path filepath(filename);394 if (!filepath.is_complete())395 filepath = PathConfig::getConfigPath() / filename;396 std::ofstream file;397 file.open(filepath.string().c_str(), std::fstream::out);398 file.setf(std::ios::fixed, std::ios::floatfield);399 file.precision(6);400 401 if (!file.is_open())402 {403 orxout(user_error, context::config) << "Couldn't open config-file \"" << filename << "\"." << endl;404 return;405 }406 407 for (std::list<ConfigFileSection*>::const_iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)408 {409 file << (*it)->getFileEntry() << endl;410 411 for (std::list<ConfigFileEntry*>::const_iterator it_entries = (*it)->getEntriesBegin(); it_entries != (*it)->getEntriesEnd(); ++it_entries)412 file << (*it_entries)->getFileEntry() << endl;413 414 file << endl;415 }416 417 file.close();418 419 orxout(verbose, context::config) << "Saved config file \"" << filename << "\"." << endl;420 }421 422 /**423 @brief Deletes all sections (which again delete all their values) and clears the list of sections.424 */425 void ConfigFile::clear()426 {427 for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); )428 delete (*(it++));429 this->sections_.clear();430 }431 432 /**433 @brief Deletes all elements of a config vector if their index is greater or equal to @a startindex.434 435 @param section The name of the section436 @param name The name of the vector437 @param startindex The index of the first element that will be deleted438 */439 void ConfigFile::deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex)440 {441 if (ConfigFileSection* sectionPtr = this->getSection(section))442 {443 sectionPtr->deleteVectorEntries(name, startindex);444 this->save();445 }446 }447 448 /**449 @brief Returns a pointer to the section with given name (or NULL if the section doesn't exist).450 */451 ConfigFileSection* ConfigFile::getSection(const std::string& section) const452 {453 for (std::list<ConfigFileSection*>::const_iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)454 if ((*it)->getName() == section)455 return (*it);456 return NULL;457 }458 459 /**460 @brief Returns a pointer to the section with given name. If it doesn't exist, the section is created.461 */462 ConfigFileSection* ConfigFile::getOrCreateSection(const std::string& section)463 {464 for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)465 if ((*it)->getName() == section)466 return (*it);467 468 this->bUpdated_ = true;469 470 return (*this->sections_.insert(this->sections_.end(), new ConfigFileSection(section)));471 }472 473 /**474 @brief Saves the config file if it was updated (or if any of its sections were updated).475 */476 void ConfigFile::saveIfUpdated()477 {478 bool sectionsUpdated = false;479 480 for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)481 {482 if ((*it)->bUpdated_)483 {484 sectionsUpdated = true;485 (*it)->bUpdated_ = false;486 }487 }488 489 if (this->bUpdated_ || sectionsUpdated)490 {491 this->bUpdated_ = false;492 this->save();493 }494 }495 496 497 ////////////////////////498 // SettingsConfigFile //499 ////////////////////////500 501 static const std::string __CC_load_name = "reloadSettings";502 static const std::string __CC_setFilename_name = "setSettingsFile";503 static const std::string __CC_config_name = "config";504 static const std::string __CC_tconfig_name = "tconfig";505 static const std::string __CC_getConfig_name = "getConfig";506 507 SetConsoleCommand(__CC_load_name, &ConfigFile::load);508 SetConsoleCommand(__CC_setFilename_name, &SettingsConfigFile::setFilename);509 SetConsoleCommand(__CC_config_name, &SettingsConfigFile::config).argumentCompleter(0, autocompletion::settingssections()).argumentCompleter(1, autocompletion::settingsentries()).argumentCompleter(2, autocompletion::settingsvalue());510 SetConsoleCommand(__CC_tconfig_name, &SettingsConfigFile::tconfig).argumentCompleter(0, autocompletion::settingssections()).argumentCompleter(1, autocompletion::settingsentries()).argumentCompleter(2, autocompletion::settingsvalue());511 SetConsoleCommand(__CC_getConfig_name, &SettingsConfigFile::getConfig).argumentCompleter(0, autocompletion::settingssections()).argumentCompleter(1, autocompletion::settingsentries());512 513 SettingsConfigFile* SettingsConfigFile::singletonPtr_s = 0;514 515 /**516 @brief Constructor: Activates the console commands.517 */518 SettingsConfigFile::SettingsConfigFile(const std::string& filename)519 : ConfigFile(filename)520 {521 ModifyConsoleCommand(__CC_load_name).setObject(this);522 ModifyConsoleCommand(__CC_setFilename_name).setObject(this);523 ModifyConsoleCommand(__CC_config_name).setObject(this);524 ModifyConsoleCommand(__CC_tconfig_name).setObject(this);525 ModifyConsoleCommand(__CC_getConfig_name).setObject(this);526 }527 528 /**529 @brief Destructor: Deactivates the console commands.530 */531 SettingsConfigFile::~SettingsConfigFile()532 {533 ModifyConsoleCommand(__CC_load_name).setObject(0);534 ModifyConsoleCommand(__CC_setFilename_name).setObject(0);535 ModifyConsoleCommand(__CC_config_name).setObject(0);536 ModifyConsoleCommand(__CC_tconfig_name).setObject(0);537 ModifyConsoleCommand(__CC_getConfig_name).setObject(0);538 }539 540 /**541 @brief Loads the config file and updates the @ref ConfigValueContainer "config value containers".542 */543 void SettingsConfigFile::load()544 {545 ConfigFile::load();546 this->updateConfigValues();547 }548 549 /**550 @brief Changes the file-name.551 */552 void SettingsConfigFile::setFilename(const std::string& filename)553 {554 ConfigFileManager::getInstance().setFilename(ConfigFileType::Settings, filename);555 }556 557 /**558 @brief Registers a new @ref ConfigValueContainer "config value container".559 */560 void SettingsConfigFile::addConfigValueContainer(ConfigValueContainer* container)561 {562 if (container == NULL)563 return;564 std::pair<std::string, ConfigValueContainer*> second(getLowercase(container->getName()), container);565 this->containers_.insert(std::make_pair(getLowercase(container->getSectionName()), second));566 this->sectionNames_.insert(container->getSectionName());567 }568 569 /**570 @brief Unregisters a @ref ConfigValueContainer "config value container".571 */572 void SettingsConfigFile::removeConfigValueContainer(ConfigValueContainer* container)573 {574 if (container == NULL)575 return;576 const std::string& sectionLC = getLowercase(container->getSectionName());577 ContainerMap::iterator upper = this->containers_.upper_bound(sectionLC);578 for (ContainerMap::iterator it = this->containers_.lower_bound(sectionLC); it != upper; ++it)579 {580 if (it->second.second == container)581 {582 // Remove entry from section name set this was the last container for that section583 if (upper == this->containers_.lower_bound(sectionLC))584 this->sectionNames_.erase(container->getSectionName());585 this->containers_.erase(it);586 break;587 }588 }589 }590 591 /**592 @brief Updates all @ref ConfigValueContainer "config value containers".593 */594 void SettingsConfigFile::updateConfigValues()595 {596 // todo: can this be done more efficiently? looks like some identifiers will be updated multiple times.597 598 for (ContainerMap::const_iterator it = this->containers_.begin(); it != this->containers_.end(); ++it)599 {600 it->second.second->update();601 it->second.second->getIdentifier()->updateConfigValues();602 }603 }604 605 /**606 @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").607 @param bCleanComments If true, comments are also removed from the file608 */609 void SettingsConfigFile::clean(bool bCleanComments)610 {611 for (std::list<ConfigFileSection*>::iterator itSection = this->sections_.begin(); itSection != this->sections_.end(); )612 {613 const std::string& sectionLC = getLowercase((*itSection)->getName());614 ContainerMap::const_iterator lower = this->containers_.lower_bound(sectionLC);615 ContainerMap::const_iterator upper = this->containers_.upper_bound(sectionLC);616 if (lower != upper)617 {618 // The section exists, delete comment619 if (bCleanComments)620 (*itSection)->setComment("");621 for (std::list<ConfigFileEntry*>::iterator itEntry = (*itSection)->entries_.begin(); itEntry != (*itSection)->entries_.end(); )622 {623 const std::string& entryLC = getLowercase((*itEntry)->getName());624 bool bFound = false;625 for (ContainerMap::const_iterator itContainer = lower; itContainer != upper; ++itContainer)626 {627 if (itContainer->second.first == entryLC)628 {629 // The config-value exists, delete comment630 if (bCleanComments)631 (*itEntry)->setComment("");632 ++itEntry;633 bFound = true;634 break;635 }636 }637 if (!bFound)638 {639 // The config-value doesn't exist640 delete (*itEntry);641 (*itSection)->entries_.erase(itEntry++);642 }643 }644 ++itSection;645 }646 else647 {648 // The section doesn't exist649 delete (*itSection);650 this->sections_.erase(itSection++);651 }652 }653 654 // Save the file655 this->save();656 }657 658 /**659 @brief Console-command: Changes the value of an entry and stores it the file.660 661 @param section The section of the config value662 @param entry The name of the config value663 @param value The new value664 */665 void SettingsConfigFile::config(const std::string& section, const std::string& entry, const std::string& value)666 {667 if (!this->configImpl(section, entry, value, &ConfigValueContainer::set))668 orxout(user_error, context::config) << "Config value \"" << entry << "\" in section \"" << section << "\" doesn't exist." << endl;669 }670 671 /**672 @brief Console-command: Changes the value of an entry, but doesn't store it in the file (it's only a temporary change).673 674 @param section The section of the config value675 @param entry The name of the config value676 @param value The new value677 */678 void SettingsConfigFile::tconfig(const std::string& section, const std::string& entry, const std::string& value)679 {680 if (!this->configImpl(section, entry, value, &ConfigValueContainer::tset))681 orxout(user_error, context::config) << "Config value \"" << entry << "\" in section \"" << section << "\" doesn't exist." << endl;682 }683 684 /**685 @brief Changes the value of an entry, depending on @a function, either by using "set" or "tset"686 687 @param section The section of the config value688 @param entry The name of the config value689 @param value The new value690 @param function The function ("set" or "tset") that will be used to change the value.691 */692 bool SettingsConfigFile::configImpl(const std::string& section, const std::string& entry, const std::string& value, bool (ConfigValueContainer::*function)(const MultiType&))693 {694 const std::string& sectionLC = getLowercase(section);695 const std::string& entryLC = getLowercase(entry);696 ContainerMap::iterator upper = this->containers_.upper_bound(sectionLC);697 for (ContainerMap::iterator it = this->containers_.lower_bound(sectionLC); it != upper; ++it)698 {699 // Note: Config value vectors cannot be supported700 if (it->second.first == entryLC && !it->second.second->isVector())701 {702 return (it->second.second->*function)(value);703 }704 }705 return false;706 }707 708 /**709 @brief Console-command: Returns the value of a given entry.710 711 @param section The section of the config value712 @param entry The name of the config value713 */714 std::string SettingsConfigFile::getConfig(const std::string& section, const std::string& entry)715 {716 const std::string& sectionLC = getLowercase(section);717 const std::string& entryLC = getLowercase(entry);718 ContainerMap::iterator upper = this->containers_.upper_bound(sectionLC);719 for (ContainerMap::iterator it = this->containers_.lower_bound(sectionLC); it != upper; ++it)720 {721 // Note: Config value vectors cannot be supported722 if (it->second.first == entryLC && ! it->second.second->isVector())723 {724 std::string value;725 it->second.second->getValue<std::string, OrxonoxClass>(&value, NULL);726 return value;727 }728 }729 return "";730 }731 732 733 40 /////////////////////// 734 41 // ConfigFileManager // -
code/branches/core6/src/libraries/core/config/ConfigFileManager.h
r9558 r9559 30 30 @file 31 31 @ingroup Config ConfigFile 32 @brief Declaration of ConfigFileManager and its helper classes, used to load and save config files.32 @brief Declaration of ConfigFileManager, used to load and save config files. 33 33 */ 34 34 … … 38 38 #include "core/CorePrereqs.h" 39 39 40 #include <list>41 #include <map>42 #include <set>43 #include <string>44 40 #include <boost/array.hpp> 45 41 46 42 #include "util/Singleton.h" 47 43 48 namespace orxonox // tolua_export 49 { // tolua_export 50 51 ///////////////////// 52 // ConfigFileEntry // 53 ///////////////////// 54 /** 55 @brief This class represents an entry in the config file. 56 57 This class is pure virtual. Use one of the derived classes to define the type of the entry. 58 */ 59 class _CoreExport ConfigFileEntry 60 { 61 public: 62 /// Destructor 63 virtual ~ConfigFileEntry() {}; 64 65 /// Changes the value of the entry. 66 virtual void setValue(const std::string& value) = 0; 67 /// Returns the value of the entry. 68 virtual const std::string& getValue() const = 0; 69 70 /// Returns the name of the entry 71 virtual const std::string& getName() const = 0; 72 73 /// Changes the comment of the entry (will be placed after the value) 74 virtual void setComment(const std::string& comment) = 0; 75 76 /// Returns the index of the entry in a vector (used only if it is a vector) 77 virtual unsigned int getIndex() const { return 0; } 78 79 /// Defines if this entry is treated as string which means some special treatment of special characters. 80 virtual void setString(bool bString) = 0; 81 82 /// Returns the line as it will be stored in the config file. 83 virtual const std::string& getFileEntry() const = 0; 84 }; 85 86 87 ////////////////////////// 88 // ConfigFileEntryValue // 89 ////////////////////////// 90 /** 91 @brief This class represents a normal value in the config file. 92 */ 93 class _CoreExport ConfigFileEntryValue : public ConfigFileEntry 94 { 95 public: 96 /** 97 @brief Constructor: Initializes the entry. 98 99 @param name The name of the entry 100 @param value The value of the entry 101 @param bString If true, the value is treated as string which means some special treatment of special characters. 102 @param additionalComment An optional comment that will be placed behind the value in the config file 103 */ 104 inline ConfigFileEntryValue(const std::string& name, const std::string& value = "", bool bString = false, const std::string& additionalComment = "") 105 : name_(name) 106 , value_(value) 107 , additionalComment_(additionalComment) 108 , bString_(bString) 109 { this->update(); } 110 111 /// Destructor 112 inline virtual ~ConfigFileEntryValue() {} 113 114 inline virtual const std::string& getName() const 115 { return this->name_; } 116 117 inline virtual void setComment(const std::string& comment) 118 { this->additionalComment_ = comment; this->update(); } 119 120 inline virtual void setValue(const std::string& value) 121 { this->value_ = value; this->update(); } 122 inline virtual const std::string& getValue() const 123 { return this->value_; } 124 125 inline void virtual setString(bool bString) 126 { this->bString_ = bString; this->update(); } 127 128 inline virtual const std::string& getFileEntry() const 129 { return this->fileEntry_; } 130 131 /// Returns the "key" of the value (in this case it's just the name of the entry, but for vectors it's different) 132 inline virtual const std::string& getKeyString() const 133 { return this->name_; } 134 135 protected: 136 virtual void update(); 137 138 const std::string name_; ///< The name of the value 139 std::string value_; ///< The value 140 std::string additionalComment_; ///< The additional comment 141 std::string fileEntry_; ///< The string as it will be stored in the config file 142 bool bString_; ///< If true, the value is treated as string which means some special treatment of special characters. 143 }; 144 145 146 //////////////////////////////// 147 // ConfigFileEntryVectorValue // 148 //////////////////////////////// 149 /** 150 @brief Subclass of ConfigFileEntryValue, represents an element of a vector. 151 */ 152 class _CoreExport ConfigFileEntryVectorValue : public ConfigFileEntryValue 153 { 154 public: 155 /** 156 @brief Constructor: Initializes the entry. 157 158 @param name The name of the vector 159 @param index The index of the element in the vector 160 @param value The value of the element 161 @param bString If true, the value is treated as string which means some special treatment of special characters. 162 @param additionalComment An optional comment that will be placed behind the value in the config file 163 */ 164 inline ConfigFileEntryVectorValue(const std::string& name, unsigned int index, const std::string& value = "", bool bString = false, const std::string& additionalComment = "") 165 : ConfigFileEntryValue(name, value, bString, additionalComment) 166 , index_(index) 167 { this->update(); /*No virtual calls in base class ctor*/ } 168 169 /// Destructor 170 inline ~ConfigFileEntryVectorValue() {} 171 172 inline unsigned int getIndex() const 173 { return this->index_; } 174 175 /// Returns the "key" of the value (the name of the vector plus the index of the element) 176 inline const std::string& getKeyString() const 177 { return this->keyString_; } 178 179 private: 180 void update(); 181 182 unsigned int index_; ///< The index of the element in the vector 183 std::string keyString_; ///< The full name of the entry (the name of the vector plus the index of the element) 184 }; 185 186 187 //////////////////////////// 188 // ConfigFileEntryComment // 189 //////////////////////////// 190 /** 191 @brief This class represents a line in the config file which contains only a comment. 192 */ 193 class _CoreExport ConfigFileEntryComment : public ConfigFileEntry 194 { 195 public: 196 /// Constructor: Initializes the object. 197 inline ConfigFileEntryComment(const std::string& comment) : comment_(comment) {} 198 199 /// Destructor 200 inline virtual ~ConfigFileEntryComment() {} 201 202 inline virtual const std::string& getName() const 203 { return this->comment_; } 204 205 inline virtual void setComment(const std::string& comment) 206 { this->comment_ = comment; } 207 208 inline virtual void setValue(const std::string& value) 209 {} 210 inline virtual const std::string& getValue() const 211 { return BLANKSTRING; } 212 213 inline void setString(bool bString) 214 {} 215 216 inline virtual const std::string& getFileEntry() const 217 { return this->comment_; } 218 219 private: 220 std::string comment_; ///< The comment 221 }; 222 223 224 /////////////////////// 225 // ConfigFileSection // 226 /////////////////////// 227 /** 228 @brief Represents a section in a config file. 229 230 A section has a name and a list of config values. 231 */ 232 class _CoreExport ConfigFileSection 233 { 234 friend class ConfigFile; 235 friend class SettingsConfigFile; 236 237 public: 238 /** 239 @brief Constructor: Initializes the section. 240 241 @param name The name of the section 242 @param additionalComment An additional comment placed after the title of the section in the config file 243 */ 244 inline ConfigFileSection(const std::string& name, const std::string& additionalComment = "") 245 : name_(name) 246 , additionalComment_(additionalComment) 247 , bUpdated_(false) 248 {} 249 ~ConfigFileSection(); 250 251 /// Returns the name of the section. 252 inline const std::string& getName() const 253 { return this->name_; } 254 255 /// Changes the comment which is placed after the title of the section in the config file. 256 inline void setComment(const std::string& comment) 257 { this->additionalComment_ = comment; } 258 259 /** 260 @brief Stores a value in the section. If the entry doesn't exist, it's created. 261 262 @param name The name of the entry 263 @param value The new value 264 @param bString If true, the value is treated as string which means some special treatment of special characters. 265 */ 266 inline void setValue(const std::string& name, const std::string& value, bool bString) 267 { this->getOrCreateEntry(name, value, bString)->setValue(value); } 268 /** 269 @brief Returns the value of a given entry in the section. Returns a blank string if the value doesn't exist. 270 271 @param name The name of the entry 272 @param bString If true, the value is treated as string which means some special treatment of special characters. 273 */ 274 inline const std::string& getValue(const std::string& name, bool bString) 275 { 276 ConfigFileEntry* entry = this->getEntry(name); 277 if (entry) 278 { 279 entry->setString(bString); // if the entry was loaded from the config file, we have to tell it if it's a string 280 return entry->getValue(); 281 } 282 return BLANKSTRING; 283 } 284 /** 285 @brief Returns the value of a given entry in the section. If it doesn't exist, the entry is created using the fallback value. 286 287 @param name The name of the entry 288 @param fallback The value that will be used if the entry doesn't exist 289 @param bString If true, the value is treated as string which means some special treatment of special characters. 290 */ 291 inline const std::string& getOrCreateValue(const std::string& name, const std::string& fallback, bool bString) 292 { return this->getOrCreateEntry(name, fallback, bString)->getValue(); } 293 294 /** 295 @brief Stores the value of an element of a vector in the section. If the entry doesn't exist, it's created. 296 297 @param name The name of the vector 298 @param index The index of the element in the vector 299 @param value The new value 300 @param bString If true, the value is treated as string which means some special treatment of special characters. 301 */ 302 inline void setValue(const std::string& name, unsigned int index, const std::string& value, bool bString) 303 { this->getOrCreateEntry(name, index, value, bString)->setValue(value); } 304 /** 305 @brief Returns the value of a given element of a vector in the section. Returns a blank string if the value doesn't exist. 306 307 @param name The name of the vector 308 @param index The index of the element in the vector 309 @param bString If true, the value is treated as string which means some special treatment of special characters. 310 */ 311 inline const std::string& getValue(const std::string& name, unsigned int index, bool bString) 312 { 313 ConfigFileEntry* entry = this->getEntry(name, index); 314 if (entry) 315 { 316 entry->setString(bString); // if the entry was loaded from the config file, we have to tell it if it's a string 317 return entry->getValue(); 318 } 319 return BLANKSTRING; 320 } 321 /** 322 @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. 323 324 @param name The name of the vector 325 @param index The index of the element in the vector 326 @param fallback The value that will be used if the entry doesn't exist 327 @param bString If true, the value is treated as string which means some special treatment of special characters. 328 */ 329 inline const std::string& getOrCreateValue(const std::string& name, unsigned int index, const std::string& fallback, bool bString) 330 { return this->getOrCreateEntry(name, index, fallback, bString)->getValue(); } 331 332 void deleteVectorEntries(const std::string& name, unsigned int startindex = 0); 333 unsigned int getVectorSize(const std::string& name) const; 334 335 std::string getFileEntry() const; 336 337 private: 338 /// Returns the list of entries in this section. 339 std::list<ConfigFileEntry*>& getEntries() 340 { return this->entries_; } 341 /// Returns the begin-iterator of the list of entries in this section. 342 std::list<ConfigFileEntry*>::const_iterator getEntriesBegin() const 343 { return this->entries_.begin(); } 344 /// Returns the end-iterator of the list of entries in this section. 345 std::list<ConfigFileEntry*>::const_iterator getEntriesEnd() const 346 { return this->entries_.end(); } 347 348 std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString); 349 std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString); 350 351 ConfigFileEntry* getEntry(const std::string& name) const; 352 /** 353 @brief Returns the entry with given name. If it doesn't exist, the entry is created using the fallback value. 354 355 @param name The name of the entry 356 @param fallback The value that will be used if the entry doesn't exist 357 @param bString If true, the value is treated as string which means some special treatment of special characters. 358 */ 359 inline ConfigFileEntry* getOrCreateEntry(const std::string& name, const std::string& fallback, bool bString) 360 { return (*this->getOrCreateEntryIterator(name, fallback, bString)); } 361 362 ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const; 363 /** 364 @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. 365 366 @param name The name of the entry 367 @param index The index of the element in the vector 368 @param fallback The value that will be used if the entry doesn't exist 369 @param bString If true, the value is treated as string which means some special treatment of special characters. 370 */ 371 inline ConfigFileEntry* getOrCreateEntry(const std::string& name, unsigned int index, const std::string& fallback, bool bString) 372 { return (*this->getOrCreateEntryIterator(name, index, fallback, bString)); } 373 374 std::string name_; ///< The name of the section 375 std::string additionalComment_; ///< The additional comment which is placed after the title of the section in the config file 376 std::list<ConfigFileEntry*> entries_; ///< The list of entries in this section 377 bool bUpdated_; ///< True if an entry is created 378 }; 379 380 381 //////////////// 382 // ConfigFile // 383 //////////////// 384 /** 385 @brief This class represents a config file, which is stored on the hard-disk and contains config values in different sections. 386 387 It provides an interface to manipulate the sections and values. 388 */ 389 class _CoreExport ConfigFile 390 { 391 public: 392 ConfigFile(const std::string& filename, bool bCopyFallbackFile = true); 393 virtual ~ConfigFile(); 394 395 virtual void load(); 396 virtual void save() const; 397 virtual void saveAs(const std::string& filename) const; 398 virtual void clear(); 399 400 /// Returns the file-name of this config file 401 inline const std::string& getFilename() 402 { return this->filename_; } 403 404 /** 405 @brief Stores a value in the config file. If the entry or its section doesn't exist, it's created. 406 407 @param section The name of the section 408 @param name The name of the entry 409 @param value The new value 410 @param bString If true, the value is treated as string which means some special treatment of special characters. 411 */ 412 inline void setValue(const std::string& section, const std::string& name, const std::string& value, bool bString) 413 { 414 this->getOrCreateSection(section)->setValue(name, value, bString); 415 this->save(); 416 } 417 /** 418 @brief Returns the value of a given entry in the config file. Returns a blank string if the value doesn't exist. 419 420 @param section The name of the section 421 @param name The name of the entry 422 @param bString If true, the value is treated as string which means some special treatment of special characters. 423 */ 424 inline const std::string& getValue(const std::string& section, const std::string& name, bool bString) 425 { 426 ConfigFileSection* sectionPtr = this->getSection(section); 427 return (sectionPtr ? sectionPtr->getValue(name, bString) : BLANKSTRING); 428 } 429 /** 430 @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. 431 432 @param section The name of the section 433 @param name The name of the entry 434 @param fallback The value that will be used if the entry doesn't exist 435 @param bString If true, the value is treated as string which means some special treatment of special characters. 436 */ 437 inline const std::string& getOrCreateValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString) 438 { 439 const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, fallback, bString); 440 this->saveIfUpdated(); 441 return output; 442 } 443 444 /** 445 @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. 446 447 @param section The name of the section 448 @param name The name of the vector 449 @param index The index of the element in the vector 450 @param value The new value 451 @param bString If true, the value is treated as string which means some special treatment of special characters. 452 */ 453 inline void setValue(const std::string& section, const std::string& name, unsigned int index, const std::string& value, bool bString) 454 { 455 this->getOrCreateSection(section)->setValue(name, index, value, bString); 456 this->save(); 457 } 458 /** 459 @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. 460 461 @param section The name of the section 462 @param name The name of the vector 463 @param index The index of the element in the vector 464 @param bString If true, the value is treated as string which means some special treatment of special characters. 465 */ 466 inline const std::string& getValue(const std::string& section, const std::string& name, unsigned int index, bool bString) 467 { 468 ConfigFileSection* sectionPtr = this->getSection(section); 469 return (sectionPtr ? sectionPtr->getValue(name, index, bString) : BLANKSTRING); 470 } 471 /** 472 @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. 473 474 @param section The name of the section 475 @param name The name of the vector 476 @param index The index of the element in the vector 477 @param fallback The value that will be used if the entry doesn't exist 478 @param bString If true, the value is treated as string which means some special treatment of special characters. 479 */ 480 const std::string& getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString) 481 { 482 const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, index, fallback, bString); 483 this->saveIfUpdated(); 484 return output; 485 } 486 487 void deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex = 0); 488 /** 489 @brief Returns the size of a config vector. 490 @param section The section of the vector 491 @param name The name of the vector 492 */ 493 inline unsigned int getVectorSize(const std::string& section, const std::string& name) const 494 { 495 ConfigFileSection* sectionPtr = this->getSection(section); 496 return (sectionPtr ? sectionPtr->getVectorSize(name) : 0); 497 } 498 499 static const char* DEFAULT_CONFIG_FOLDER; ///< The folder where the default config files will be stored 500 501 protected: 502 ConfigFileSection* getSection(const std::string& section) const; 503 ConfigFileSection* getOrCreateSection(const std::string& section); 504 505 std::list<ConfigFileSection*> sections_; ///< A list of sections in this config file 506 507 private: 508 void saveIfUpdated(); 509 510 const std::string filename_; ///< The filename of this config file 511 const bool bCopyFallbackFile_; ///< If true, the default config file is copied into the config-directory before loading the file 512 bool bUpdated_; ///< Becomes true if a section is added 513 }; 514 515 516 //////////////////////// 517 // SettingsConfigFile // 518 //////////////////////// 519 /** 520 @brief Child class of ConfigFile, used to store the settings of the game. 521 522 In addition to ConfigFile, this class provides an interface to manipulate the settings 523 with console commands and to cache entries in instances of ConfigValueContainer. 524 525 SettingsConfigFile is a Singleton, meaning there's only one instance of this class 526 (and thus only one config file that stores settings). 527 */ 528 class _CoreExport SettingsConfigFile // tolua_export 529 : public ConfigFile, public Singleton<SettingsConfigFile> 530 { // tolua_export 531 friend class Singleton<SettingsConfigFile>; 532 533 public: 534 typedef std::multimap<std::string, std::pair<std::string, ConfigValueContainer*> > ContainerMap; 535 536 SettingsConfigFile(const std::string& filename); 537 ~SettingsConfigFile(); 538 539 void load(); // tolua_export 540 void setFilename(const std::string& filename); // tolua_export 541 void clean(bool bCleanComments = false); // tolua_export 542 543 void config(const std::string& section, const std::string& entry, const std::string& value); // tolua_export 544 void tconfig(const std::string& section, const std::string& entry, const std::string& value); // tolua_export 545 std::string getConfig(const std::string& section, const std::string& entry); // tolua_export 546 547 void addConfigValueContainer(ConfigValueContainer* container); 548 void removeConfigValueContainer(ConfigValueContainer* container); 549 550 /// Returns a set containing the names of all sections in this config file. 551 inline const std::set<std::string>& getSectionNames() 552 { return this->sectionNames_; } 553 /// Returns the lower-bound-iterator of the @ref ConfigValueContainer "config value containers" for the given section. 554 inline ContainerMap::const_iterator getContainerLowerBound(const std::string section) 555 { return this->containers_.lower_bound(section); } 556 /// Returns the upper-bound-iterator of the @ref ConfigValueContainer "config value containers" for the given section. 557 inline ContainerMap::const_iterator getContainerUpperBound(const std::string section) 558 { return this->containers_.upper_bound(section); } 559 560 static SettingsConfigFile& getInstance() { return Singleton<SettingsConfigFile>::getInstance(); } // tolua_export 561 562 private: 563 void updateConfigValues(); 564 bool configImpl(const std::string& section, const std::string& entry, const std::string& value, bool (ConfigValueContainer::*function)(const MultiType&)); 565 566 ContainerMap containers_; ///< Stores all @ref ConfigValueContainer "config value containers" 567 std::set<std::string> sectionNames_; ///< Stores all section names 568 static SettingsConfigFile* singletonPtr_s; ///< The singleton pointer 569 }; // tolua_export 570 571 44 namespace orxonox 45 { 572 46 /////////////////////// 573 47 // ConfigFileManager // … … 598 72 static ConfigFileManager* singletonPtr_s; ///< Stores the singleton-pointer 599 73 }; 600 } // tolua_export74 } 601 75 602 76 #endif /* _ConfigFileManager_H__ */ -
code/branches/core6/src/libraries/core/config/ConfigValueContainer.cc
r9558 r9559 38 38 #include "core/Language.h" 39 39 #include "ConfigFileManager.h" 40 #include "SettingsConfigFile.h" 40 41 41 42 namespace orxonox -
code/branches/core6/src/libraries/core/input/Button.cc
r9558 r9559 42 42 #include "core/command/CommandEvaluation.h" 43 43 #include "core/command/CommandExecutor.h" 44 #include "core/config/ConfigFile Manager.h"44 #include "core/config/ConfigFile.h" 45 45 46 46 namespace orxonox -
code/branches/core6/src/libraries/core/input/JoyStick.cc
r9558 r9559 34 34 35 35 #include "util/StringUtils.h" 36 #include "core/config/ConfigFile.h" 36 37 #include "core/config/ConfigFileManager.h" 37 38 #include "core/config/ConfigValueIncludes.h" -
code/branches/core6/src/libraries/core/input/KeyBinder.cc
r9558 r9559 36 36 #include "core/CoreIncludes.h" 37 37 #include "core/config/ConfigValueIncludes.h" 38 #include "core/config/ConfigFile Manager.h"38 #include "core/config/ConfigFile.h" 39 39 #include "core/PathConfig.h" 40 40 #include "InputCommands.h" -
code/branches/core6/src/libraries/network/WANDiscovery.h
r9558 r9559 33 33 #include "core/CoreIncludes.h" 34 34 #include "core/OrxonoxClass.h" 35 #include "core/config/ConfigFileManager.h"36 35 #include "core/config/ConfigValueIncludes.h" 37 36 #include "MasterServerComm.h"
Note: See TracChangeset
for help on using the changeset viewer.