[Orxonox-commit 1719] r6437 - in code/branches/gamestate/src/libraries/core: . input
rgrieder at orxonox.net
rgrieder at orxonox.net
Fri Jan 1 22:05:57 CET 2010
Author: rgrieder
Date: 2010-01-01 22:05:56 +0100 (Fri, 01 Jan 2010)
New Revision: 6437
Modified:
code/branches/gamestate/src/libraries/core/ConfigFileManager.cc
code/branches/gamestate/src/libraries/core/ConfigFileManager.h
code/branches/gamestate/src/libraries/core/input/Button.cc
code/branches/gamestate/src/libraries/core/input/Button.h
code/branches/gamestate/src/libraries/core/input/KeyBinder.cc
code/branches/gamestate/src/libraries/core/input/KeyBinder.h
Log:
Added support for keybindings.ini merging:
When running development builds, the keybinder will merge the local file and the one from the data folder.
Catch: if you want to remove a binding, you'll have to write "NoBinding" (not case sensitive) to override the default command
The keybind command already does that for you though.
Modified: code/branches/gamestate/src/libraries/core/ConfigFileManager.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/ConfigFileManager.cc 2010-01-01 20:52:45 UTC (rev 6436)
+++ code/branches/gamestate/src/libraries/core/ConfigFileManager.cc 2010-01-01 21:05:56 UTC (rev 6437)
@@ -32,7 +32,6 @@
#include "util/Convert.h"
#include "util/Math.h"
-#include "util/StringUtils.h"
#include "ConsoleCommand.h"
#include "ConfigValueContainer.h"
#include "PathConfig.h"
@@ -115,16 +114,26 @@
return ('[' + this->name_ + "] " + this->additionalComment_);
}
- std::list<ConfigFileEntry*>::const_iterator ConfigFileSection::getEntryIterator(const std::string& name) const
+ ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name) const
{
for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
{
if ((*it)->getName() == name)
- return it;
+ return *it;
}
- return this->entries_.end();
+ return NULL;
}
+ 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)
+ {
+ if (((*it)->getName() == name) && ((*it)->getIndex() == index))
+ return *it;
+ }
+ return NULL;
+ }
+
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)
@@ -141,16 +150,6 @@
return this->entries_.insert(this->entries_.end(), new ConfigFileEntryValue(name, fallback, bString));
}
- std::list<ConfigFileEntry*>::const_iterator ConfigFileSection::getEntryIterator(const std::string& name, unsigned int index) const
- {
- for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
- {
- if (((*it)->getName() == name) && ((*it)->getIndex() == index))
- return it;
- }
- return this->entries_.end();
- }
-
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)
@@ -174,8 +173,12 @@
////////////////
// ConfigFile //
////////////////
- ConfigFile::ConfigFile(const std::string& filename)
+
+ const char* ConfigFile::DEFAULT_CONFIG_FOLDER = "defaultConfig";
+
+ ConfigFile::ConfigFile(const std::string& filename, bool bCopyFallbackFile)
: filename_(filename)
+ , bCopyFallbackFile_(bCopyFallbackFile)
, bUpdated_(false)
{
}
@@ -190,16 +193,28 @@
// Be sure we start from new in the memory
this->clear();
- // Get default file if necessary and available
- boost::filesystem::path filepath(PathConfig::getConfigPath() / this->filename_);
- if (!boost::filesystem::exists(filepath))
+ boost::filesystem::path filepath(this->filename_);
+ if (!filepath.is_complete())
{
- // Try to get default one from the data folder
- boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / "defaultConfig" / this->filename_);
- if (boost::filesystem::exists(defaultFilepath))
+ filepath = PathConfig::getConfigPath() / filepath;
+ if (this->bCopyFallbackFile_)
{
- COUT(3) << "Copied " << this->filename_ << " from the defaultConfig folder." << std::endl;
- boost::filesystem::copy_file(defaultFilepath, filepath);
+ // Look for default file in the data folder
+ if (!boost::filesystem::exists(filepath))
+ {
+ boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / DEFAULT_CONFIG_FOLDER / this->filename_);
+ if (boost::filesystem::exists(defaultFilepath))
+ {
+ // Try to copy default file from the data folder
+ try
+ {
+ boost::filesystem::copy_file(defaultFilepath, filepath);
+ COUT(3) << "Copied " << this->filename_ << " from the default config folder." << std::endl;
+ }
+ catch (const boost::filesystem::filesystem_error& ex)
+ { COUT(1) << "Error in ConfigFile: " << ex.what() << std::endl; }
+ }
+ }
}
}
@@ -294,8 +309,7 @@
COUT(3) << "Loaded config file \"" << this->filename_ << "\"." << std::endl;
- // Save the file in case something changed (like stripped white space)
- this->save();
+ // DO NOT save the file --> we can open supposedly read only config files
} // end file.is_open()
}
@@ -306,8 +320,11 @@
void ConfigFile::saveAs(const std::string& filename) const
{
+ boost::filesystem::path filepath(filename);
+ if (!filepath.is_complete())
+ filepath = PathConfig::getConfigPath() / filename;
std::ofstream file;
- file.open((PathConfig::getConfigPathString() + filename).c_str(), std::fstream::out);
+ file.open(filepath.string().c_str(), std::fstream::out);
file.setf(std::ios::fixed, std::ios::floatfield);
file.precision(6);
Modified: code/branches/gamestate/src/libraries/core/ConfigFileManager.h
===================================================================
--- code/branches/gamestate/src/libraries/core/ConfigFileManager.h 2010-01-01 20:52:45 UTC (rev 6436)
+++ code/branches/gamestate/src/libraries/core/ConfigFileManager.h 2010-01-01 21:05:56 UTC (rev 6437)
@@ -38,6 +38,7 @@
#include <boost/array.hpp>
#include "util/Singleton.h"
+#include "util/StringUtils.h"
namespace orxonox // tolua_export
{ // tolua_export
@@ -190,20 +191,30 @@
inline void setValue(const std::string& name, const std::string& value, bool bString)
{ this->getOrCreateEntry(name, value, bString)->setValue(value); }
- inline const std::string& getValue(const std::string& name, const std::string& fallback, bool bString) const
+ inline const std::string& getValue(const std::string& name, bool bString)
{
ConfigFileEntry* entry = this->getEntry(name);
- return (entry ? entry->getValue() : BLANKSTRING);
+ if (entry)
+ {
+ entry->setString(bString);
+ return entry->getValue();
+ }
+ return BLANKSTRING;
}
inline const std::string& getOrCreateValue(const std::string& name, const std::string& fallback, bool bString)
{ return this->getOrCreateEntry(name, fallback, bString)->getValue(); }
inline void setValue(const std::string& name, unsigned int index, const std::string& value, bool bString)
{ this->getOrCreateEntry(name, index, value, bString)->setValue(value); }
- inline const std::string& getValue(const std::string& name, unsigned int index) const
+ inline const std::string& getValue(const std::string& name, unsigned int index, bool bString)
{
ConfigFileEntry* entry = this->getEntry(name, index);
- return (entry ? entry->getValue() : BLANKSTRING);
+ if (entry)
+ {
+ entry->setString(bString);
+ return entry->getValue();
+ }
+ return BLANKSTRING;
}
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(); }
@@ -221,17 +232,13 @@
std::list<ConfigFileEntry*>::const_iterator getEntriesEnd() const
{ return this->entries_.end(); }
- std::list<ConfigFileEntry*>::const_iterator getEntryIterator(const std::string& name) const;
- std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString);
- std::list<ConfigFileEntry*>::const_iterator getEntryIterator(const std::string& name, unsigned int index) const;
- std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString);
+ std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString);
+ std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString);
- inline ConfigFileEntry* getEntry(const std::string& name) const
- { return (*this->getEntryIterator(name)); }
+ ConfigFileEntry* getEntry(const std::string& name) const;
inline ConfigFileEntry* getOrCreateEntry(const std::string& name, const std::string& fallback, bool bString)
{ return (*this->getOrCreateEntryIterator(name, fallback, bString)); }
- inline ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const
- { return (*this->getEntryIterator(name, index)); }
+ ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const;
inline ConfigFileEntry* getOrCreateEntry(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
{ return (*this->getOrCreateEntryIterator(name, index, fallback, bString)); }
@@ -248,7 +255,7 @@
class _CoreExport ConfigFile
{
public:
- ConfigFile(const std::string& filename);
+ ConfigFile(const std::string& filename, bool bCopyFallbackFile = true);
virtual ~ConfigFile();
virtual void load();
@@ -264,7 +271,7 @@
this->getOrCreateSection(section)->setValue(name, value, bString);
this->save();
}
- inline const std::string& getValue(const std::string& section, const std::string& name, bool bString) const
+ 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);
@@ -273,13 +280,13 @@
inline void setValue(const std::string& section, const std::string& name, unsigned int index, const std::string& value, bool bString)
{
- this->getSection(section)->setValue(name, index, value, bString);
+ this->getOrCreateSection(section)->setValue(name, index, value, bString);
this->save();
}
- inline const std::string& getValue(const std::string& section, const std::string& name, unsigned int index) const
+ 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) : BLANKSTRING);
+ 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);
@@ -290,6 +297,8 @@
return (sectionPtr ? sectionPtr->getVectorSize(name) : 0);
}
+ static const char* DEFAULT_CONFIG_FOLDER;
+
protected:
ConfigFileSection* getSection(const std::string& section) const;
ConfigFileSection* getOrCreateSection(const std::string& section);
@@ -299,6 +308,7 @@
private:
void saveIfUpdated();
const std::string filename_;
+ const bool bCopyFallbackFile_;
bool bUpdated_;
};
Modified: code/branches/gamestate/src/libraries/core/input/Button.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/input/Button.cc 2010-01-01 20:52:45 UTC (rev 6436)
+++ code/branches/gamestate/src/libraries/core/input/Button.cc 2010-01-01 21:05:56 UTC (rev 6437)
@@ -81,13 +81,15 @@
this->bindingString_.clear();
}
- void Button::readBinding(ConfigFile* configFile)
+ void Button::readBinding(ConfigFile* configFile, ConfigFile* fallbackFile)
{
- const std::string& binding = configFile->getOrCreateValue(groupName_, name_, "", true);
+ std::string binding = configFile->getOrCreateValue(groupName_, name_, "", true);
+ if (binding.empty() && fallbackFile)
+ binding = fallbackFile->getValue(groupName_, name_, true);
this->parse(binding);
}
- void Button::setBinding(ConfigFile* configFile, const std::string& binding, bool bTemporary)
+ void Button::setBinding(ConfigFile* configFile, ConfigFile* fallbackFile, const std::string& binding, bool bTemporary)
{
if (!bTemporary)
configFile->setValue(groupName_, name_, binding, true);
@@ -103,7 +105,7 @@
clear();
this->bindingString_ = binding;
- if (isEmpty(bindingString_))
+ if (isEmpty(bindingString_) || removeTrailingWhitespaces(getLowercase(binding)) == "nobinding")
return;
// reset this to false first when parsing (was true before when parsing for the first time)
Modified: code/branches/gamestate/src/libraries/core/input/Button.h
===================================================================
--- code/branches/gamestate/src/libraries/core/input/Button.h 2010-01-01 20:52:45 UTC (rev 6436)
+++ code/branches/gamestate/src/libraries/core/input/Button.h 2010-01-01 21:05:56 UTC (rev 6437)
@@ -51,8 +51,8 @@
virtual void clear();
virtual bool addParamCommand(ParamCommand* command) { return false; }
void parse(const std::string& binding);
- void readBinding(ConfigFile* configFile);
- void setBinding(ConfigFile* configFile, const std::string& binding, bool bTemporary);
+ void readBinding(ConfigFile* configFile, ConfigFile* fallbackFile);
+ void setBinding(ConfigFile* configFile, ConfigFile* fallbackFile, const std::string& binding, bool bTemporary);
bool execute(KeybindMode::Value mode, float abs = 1.0f, float rel = 1.0f);
//! The configured string value
Modified: code/branches/gamestate/src/libraries/core/input/KeyBinder.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/input/KeyBinder.cc 2010-01-01 20:52:45 UTC (rev 6436)
+++ code/branches/gamestate/src/libraries/core/input/KeyBinder.cc 2010-01-01 21:05:56 UTC (rev 6437)
@@ -36,6 +36,7 @@
#include "core/ConfigValueIncludes.h"
#include "core/CoreIncludes.h"
#include "core/ConfigFileManager.h"
+#include "core/PathConfig.h"
#include "InputCommands.h"
#include "JoyStick.h"
@@ -49,6 +50,7 @@
: deriveTime_(0.0f)
, filename_(filename)
, configFile_(NULL)
+ , fallbackConfigFile_(NULL)
{
mouseRelative_[0] = 0;
mouseRelative_[1] = 0;
@@ -113,6 +115,10 @@
{
// almost no destructors required because most of the arrays are static.
clearBindings(); // does some destruction work
+ if (this->configFile_)
+ delete this->configFile_;
+ if (this->fallbackConfigFile_)
+ delete this->fallbackConfigFile_;
}
/**
@@ -165,9 +171,9 @@
for (unsigned int iDev = oldValue; iDev < joySticks_.size(); ++iDev)
{
for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
- (*joyStickButtons_[iDev])[i].readBinding(this->configFile_);
+ (*joyStickButtons_[iDev])[i].readBinding(this->configFile_, this->fallbackConfigFile_);
for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
- (*joyStickAxes_[iDev])[i].readBinding(this->configFile_);
+ (*joyStickAxes_[iDev])[i].readBinding(this->configFile_, this->fallbackConfigFile_);
}
}
@@ -246,13 +252,27 @@
{
COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
- this->configFile_ = new ConfigFile(this->filename_);
+ this->configFile_ = new ConfigFile(this->filename_, !PathConfig::isDevelopmentRun());
this->configFile_->load();
+ if (PathConfig::isDevelopmentRun())
+ {
+ // Dev users should have combined key bindings files
+ std::string defaultFilepath(PathConfig::getDataPathString() + ConfigFile::DEFAULT_CONFIG_FOLDER + '/' + this->filename_);
+ std::ifstream file(defaultFilepath.c_str());
+ if (file.is_open())
+ {
+ file.close();
+ // Open the default file for later use (use absolute path!)
+ this->fallbackConfigFile_ = new ConfigFile(defaultFilepath, false);
+ this->fallbackConfigFile_->load();
+ }
+ }
+
// Parse bindings and create the ConfigValueContainers if necessary
for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
{
- it->second->readBinding(this->configFile_);
+ it->second->readBinding(this->configFile_, this->fallbackConfigFile_);
addButtonToCommand(it->second->bindingString_, it->second);
}
@@ -265,7 +285,10 @@
if (it != allButtons_.end())
{
addButtonToCommand(binding, it->second);
- it->second->setBinding(this->configFile_, binding, bTemporary);
+ std::string str = binding;
+ if (PathConfig::isDevelopmentRun() && binding.empty())
+ str = "NoBinding";
+ it->second->setBinding(this->configFile_, this->fallbackConfigFile_, binding, bTemporary);
return true;
}
else
Modified: code/branches/gamestate/src/libraries/core/input/KeyBinder.h
===================================================================
--- code/branches/gamestate/src/libraries/core/input/KeyBinder.h 2010-01-01 20:52:45 UTC (rev 6436)
+++ code/branches/gamestate/src/libraries/core/input/KeyBinder.h 2010-01-01 21:05:56 UTC (rev 6437)
@@ -157,6 +157,8 @@
const std::string filename_;
//! Config file used. NULL in case of KeyDetector. Also indicates whether we've already loaded.
ConfigFile* configFile_;
+ //! Config file from the data directory that only serves as fallback
+ ConfigFile* fallbackConfigFile_;
private:
void addButtonToCommand(const std::string& command, Button* button);
More information about the Orxonox-commit
mailing list