[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