Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/core/ConfigValueContainer.cc @ 1546

Last change on this file since 1546 was 1327, checked in by landauf, 17 years ago

sync with notebook

File size: 13.1 KB
RevLine 
[513]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
[1056]3 *                    > www.orxonox.net <
[513]4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
[670]23 *      Fabian 'x3n' Landau
[513]24 *   Co-authors:
25 *      ...
26 *
27 */
28
[871]29/**
30    @file ConfigValueContainer.cc
31    @brief Implementation of the ConfigValueContainer class.
32*/
33
[1062]34#include "ConfigValueContainer.h"
35
[497]36#include <fstream>
[682]37
[1062]38#include "util/SubString.h"
39#include "util/Convert.h"
[1052]40#include "Language.h"
41#include "Identifier.h"
[497]42
[1052]43#define MAX_VECTOR_INDEX 255 // to avoid up to 4*10^9 vector entries in the config file after accidentally using a wrong argument
[497]44
[1052]45
[497]46namespace orxonox
47{
48    /**
[667]49        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
[1052]50        @param type The type of the corresponding config-file
51        @param identifier The identifier of the class the variable belongs to
[497]52        @param varname The name of the variable
53        @param defvalue The default-value
54    */
[1052]55    ConfigValueContainer::ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const MultiTypeMath& defvalue)
[497]56    {
[1052]57        this->type_ = type;
58        this->identifier_ = identifier;
59        this->sectionname_ = identifier->getName();
[667]60        this->varname_ = varname;
[497]61
[1052]62        this->value_ = defvalue;
63        this->bAddedDescription_ = false;
64        this->bIsVector_ = false;
[497]65
[1052]66        this->defvalueString_ = defvalue.toString();
67        this->update();
[497]68    }
69
70    /**
[1052]71        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
72        @param type The type of the corresponding config-file
73        @param identifier The identifier of the class the variable belongs to
74        @param varname The name of the variable
75        @param defvalue The default-value
[497]76    */
[1052]77    ConfigValueContainer::ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const std::vector<MultiTypeMath>& defvalue)
[667]78    {
[1052]79        this->type_ = type;
80        this->identifier_ = identifier;
81        this->sectionname_ = identifier->getName();
82        this->varname_ = varname;
[667]83
[1052]84        this->valueVector_ = defvalue;
85        this->bAddedDescription_ = false;
86        this->bIsVector_ = true;
[667]87
[1052]88        if (defvalue.size() > 0)
[1325]89        {
90                this->value_ = defvalue[0];
[667]91
[1325]92            for (unsigned int i = 0; i < defvalue.size(); i++)
93            {
94                ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, defvalue[i].toString(), this->value_.isA(MT_string));
95                this->defvalueStringVector_.push_back(defvalue[i].toString());
96            }
[667]97
[1325]98            this->update();
99        }
[667]100    }
101
102    /**
[1321]103        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
104        @param input The new value
105        @return True if the new value was successfully assigned
[667]106    */
[1321]107    bool ConfigValueContainer::set(const MultiTypeMath& input)
[667]108    {
[1052]109        if (this->bIsVector_)
[1321]110        {
[1324]111            return this->callFunctionWithIndex(&ConfigValueContainer::set, input.toString());
[1321]112        }
113        else
114        {
115            if (this->tset(input))
116            {
[1324]117                ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input.toString(), this->value_.isA(MT_string));
[1321]118                return true;
119            }
120        }
[1052]121        return false;
[497]122    }
123
124    /**
[1321]125        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
126        @param index The index in the vector
127        @param input The new value
128        @return True if the new value was successfully assigned
[703]129    */
[1321]130    bool ConfigValueContainer::set(unsigned int index, const MultiTypeMath& input)
[703]131    {
[1052]132        if (this->bIsVector_)
133        {
[1321]134            if (this->tset(index, input))
[1052]135            {
[1324]136                ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input.toString(), this->value_.isA(MT_string));
[1052]137                return true;
138            }
139        }
[1321]140        else
141        {
142            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
143        }
[1052]144        return false;
[703]145    }
146
147    /**
[1321]148        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
[1052]149        @param input The new value
150        @return True if the new value was successfully assigned
[703]151    */
[1321]152    bool ConfigValueContainer::tset(const MultiTypeMath& input)
[703]153    {
[1052]154        if (this->bIsVector_)
155        {
[1324]156            return this->callFunctionWithIndex(&ConfigValueContainer::tset, input.toString());
[1321]157        }
158        else
159        {
160            MultiTypeMath temp = this->value_;
161            if (temp.assimilate(input))
162            {
163                this->value_ = temp;
164                if (this->identifier_)
165                    this->identifier_->updateConfigValues();
[703]166
[1321]167                return true;
[1052]168            }
169        }
[1321]170        return false;
[703]171    }
172
173    /**
[1321]174        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
[1052]175        @param index The index in the vector
176        @param input The new value
177        @return True if the new value was successfully assigned
[703]178    */
[1321]179    bool ConfigValueContainer::tset(unsigned int index, const MultiTypeMath& input)
[703]180    {
[1052]181        if (this->bIsVector_)
[703]182        {
[1321]183            if (index > MAX_VECTOR_INDEX)
184            {
185                COUT(1) << "Error: Index " << index << " is too large." << std::endl;
186                return false;
187            }
188
189            if (index >= this->valueVector_.size())
190            {
191                for (unsigned int i = this->valueVector_.size(); i <= index; i++)
192                {
193                    this->valueVector_.push_back(MultiTypeMath());
194                }
195            }
196
[1324]197            MultiTypeMath temp = this->value_;
[1321]198            if (temp.assimilate(input))
199            {
200                this->valueVector_[index] = temp;
201
202                if (this->identifier_)
203                    this->identifier_->updateConfigValues();
204
205                return true;
206            }
[703]207        }
[1321]208        else
209        {
210            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
211        }
[1052]212        return false;
[703]213    }
214
215    /**
[1321]216        @brief Adds a new entry to the end of the vector.
217        @param input The new entry
218        @return True if the new entry was successfully added
[703]219    */
[1321]220    bool ConfigValueContainer::add(const MultiTypeMath& input)
[703]221    {
[1321]222        if (this->bIsVector_)
223            return this->set(this->valueVector_.size(), input);
224
225        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
226        return false;
[703]227    }
228
229    /**
[1321]230        @brief Removes an existing entry from the vector.
231        @param index The index of the entry
232        @return True if the entry was removed
[703]233    */
[1321]234    bool ConfigValueContainer::remove(unsigned int index)
[703]235    {
[1052]236        if (this->bIsVector_)
[703]237        {
[1321]238            if (index < this->valueVector_.size())
239            {
240                // Erase the entry from the vector, change (shift) all entries beginning with index in the config file, remove the last entry from the file
241                this->valueVector_.erase(this->valueVector_.begin() + index);
242                for (unsigned int i = index; i < this->valueVector_.size(); i++)
243                    ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isA(MT_string));
244                ConfigFileManager::getSingleton()->deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->valueVector_.size());
245
246                return true;
247            }
248            COUT(1) << "Error: Invalid vector-index." << std::endl;
[703]249        }
250
[1052]251        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
[703]252        return false;
253    }
254
255    /**
[1052]256        @brief Sets the value of the variable back to the default value and resets the config-file entry.
[703]257    */
[1052]258    bool ConfigValueContainer::reset()
[703]259    {
[1052]260        if (!this->bIsVector_)
261            return this->set(this->defvalueString_);
262        else
[703]263        {
[1052]264            bool success = true;
265            for (unsigned int i = 0; i < this->defvalueStringVector_.size(); i++)
266                if (!this->set(i, this->defvalueStringVector_[i]))
267                    success = false;
268            ConfigFileManager::getSingleton()->deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->defvalueStringVector_.size());
269            return success;
[703]270        }
271    }
272
273    /**
[1052]274        @brief Retrieves the configured value from the currently loaded config-file.
[703]275    */
[1052]276    void ConfigValueContainer::update()
[703]277    {
[1052]278        if (!this->bIsVector_)
279            this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isA(MT_string)));
280        else
[497]281        {
[1052]282            this->valueVector_.clear();
283            for (unsigned int i = 0; i < ConfigFileManager::getSingleton()->getVectorSize(this->type_, this->sectionname_, this->varname_); i++)
[703]284            {
[1321]285                if (i < this->defvalueStringVector_.size())
[1325]286                {
[1321]287                    this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isA(MT_string)));
[1325]288                }
[1321]289                else
[1325]290                {
[1327]291                    this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, MultiTypeMath(), this->value_.isA(MT_string)));
[1325]292                }
[1321]293
[1052]294                this->valueVector_.push_back(this->value_);
[703]295            }
296        }
297    }
298
299    /**
[1321]300        @brief Calls the given function with parsed index and the parsed argument from the input string.
301        @param function The function to call
302        @param input The input string
303        @return The returnvalue of the functioncall
[703]304    */
[1321]305    bool ConfigValueContainer::callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiTypeMath&), const std::string& input)
[703]306    {
[1321]307        SubString token(input, " ", SubString::WhiteSpaces, true, '\\', false, '"', false, '(', ')', false, '\0');
308        int index = -1;
309        bool success = false;
[703]310
[1321]311        if (token.size() > 0)
312            success = ConvertValue(&index, token[0]);
[1052]313
[1321]314        if (!success || index < 0 || index > MAX_VECTOR_INDEX)
315        {
316            if (!success)
[703]317            {
[1321]318                COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
[703]319            }
[1052]320            else
[497]321            {
[1321]322                COUT(1) << "Error: Invalid vector-index." << std::endl;
[1052]323            }
324            return false;
[497]325        }
326
[1321]327        if (token.size() >= 2)
328            return (this->*function)(index, token.subSet(1).join());
329        else
330            return (this->*function)(index, "");
[497]331    }
332
333    /**
[705]334        @brief Adds a description to the config-value.
335        @param description The description
336    */
[715]337    void ConfigValueContainer::description(const std::string& description)
[705]338    {
339        if (!this->bAddedDescription_)
340        {
[1052]341            this->description_ = std::string("ConfigValueDescription::" + this->identifier_->getName() + "::" + this->varname_);
[871]342            AddLanguageEntry(this->description_, description);
[705]343            this->bAddedDescription_ = true;
344        }
345    }
[871]346
347    /**
348        @brief Returns the description of the config-value.
349        @return The description
350    */
351    const std::string& ConfigValueContainer::getDescription() const
352    {
353        return GetLocalisation(this->description_);
354    }
[497]355}
Note: See TracBrowser for help on using the repository browser.