Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/ConfigValueContainer.cc @ 1062

Last change on this file since 1062 was 1062, checked in by rgrieder, 16 years ago
  • changed header file inclusion order
File size: 14.9 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)
89            this->value_ = defvalue[0];
[667]90
[1052]91        for (unsigned int i = 0; i < defvalue.size(); i++)
92            ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, defvalue[i].toString(), this->value_.isA(MT_string));
[667]93
[1052]94        for (unsigned int i = 0; i < defvalue.size(); i++)
95            this->defvalueStringVector_.push_back(defvalue[i].toString());
[667]96
[1052]97        this->update();
[667]98    }
99
100    /**
[1052]101        @brief Adds a new entry to the end of the vector.
102        @param input The new entry
103        @return True if the new entry was successfully added
[667]104    */
[1052]105    bool ConfigValueContainer::add(const std::string& input)
[667]106    {
[1052]107        if (this->bIsVector_)
108            return this->set(this->valueVector_.size(), input);
[667]109
[1052]110        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
111        return false;
[497]112    }
113
114    /**
[1052]115        @brief Removes an existing entry from the vector.
116        @param index The index of the entry
117        @return True if the entry was removed
[703]118    */
[1052]119    bool ConfigValueContainer::remove(unsigned int index)
[703]120    {
[1052]121        if (this->bIsVector_)
122        {
123            if (index < this->valueVector_.size())
124            {
125                this->valueVector_.erase(this->valueVector_.begin() + index);
126                for (unsigned int i = index; i < this->valueVector_.size(); i++)
127                    ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isA(MT_string));
128                ConfigFileManager::getSingleton()->deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->valueVector_.size());
[703]129
[1052]130                return true;
131            }
132            COUT(1) << "Error: Invalid vector-index." << std::endl;
133        }
[703]134
[1052]135        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
136        return false;
[703]137    }
138
139    /**
[1052]140        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
141        @param input The new value
142        @return True if the new value was successfully assigned
[703]143    */
[1052]144    bool ConfigValueContainer::set(const std::string& input)
[703]145    {
[1052]146        if (this->bIsVector_)
147        {
148            SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0');
149            int index = -1;
150            bool success = false;
[703]151
[1052]152            if (token.size() > 0)
153                success = ConvertValue(&index, token[0]);
[703]154
[1052]155            if (!success || index < 0 || index > MAX_VECTOR_INDEX)
156            {
157                if (!success)
158                {
159                    COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
160                }
161                else
162                {
163                    COUT(1) << "Error: Invalid vector-index." << std::endl;
164                }
165                return false;
166            }
[703]167
[1052]168            if (token.size() >= 2)
169                return this->set(index, token.subSet(1).join());
170            else
171                return this->set(index, "");
172        }
[703]173
[1052]174        bool success = this->tset(input);
175        ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isA(MT_string));
[871]176        return success;
[703]177    }
178
179    /**
[1052]180        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
181        @param index The index in the vector
182        @param input The new value
183        @return True if the new value was successfully assigned
[703]184    */
[1052]185    bool ConfigValueContainer::set(unsigned int index, const std::string& input)
[703]186    {
[1052]187        if (this->bIsVector_)
[703]188        {
[1052]189            bool success = this->tset(index, input);
190            ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isA(MT_string));
[871]191            return success;
[703]192        }
193
[1052]194        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
195        return false;
[703]196    }
197
198    /**
[1052]199        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
200        @param input The new value
201        @return True if the new value was successfully assigned
[703]202    */
[1052]203    bool ConfigValueContainer::tset(const std::string& input)
[703]204    {
[1052]205        bool success = this->parse(input);
206        if (this->identifier_)
207            this->identifier_->updateConfigValues();
208        return success;
[703]209    }
210
211    /**
[1052]212        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
213        @param index The index in the vector
214        @param input The new value
215        @return True if the new value was successfully assigned
[703]216    */
[1052]217    bool ConfigValueContainer::tset(unsigned int index, const std::string& input)
[703]218    {
[1052]219        if (this->bIsVector_)
[703]220        {
[1052]221            bool success = this->parse(index, input);
222            if (this->identifier_)
223                this->identifier_->updateConfigValues();
224            return success;
[703]225        }
226
[1052]227        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
[703]228        return false;
229    }
230
231    /**
[1052]232        @brief Sets the value of the variable back to the default value and resets the config-file entry.
[703]233    */
[1052]234    bool ConfigValueContainer::reset()
[703]235    {
[1052]236        if (!this->bIsVector_)
237            return this->set(this->defvalueString_);
238        else
[703]239        {
[1052]240            bool success = true;
241            for (unsigned int i = 0; i < this->defvalueStringVector_.size(); i++)
242                if (!this->set(i, this->defvalueStringVector_[i]))
243                    success = false;
244            ConfigFileManager::getSingleton()->deleteVectorEntries(this->type_, this->sectionname_, this->varname_, this->defvalueStringVector_.size());
245            return success;
[703]246        }
247    }
248
249    /**
[1052]250        @brief Retrieves the configured value from the currently loaded config-file.
[703]251    */
[1052]252    void ConfigValueContainer::update()
[703]253    {
[1052]254        if (!this->bIsVector_)
255            this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, this->defvalueString_, this->value_.isA(MT_string)));
256        else
[497]257        {
[1052]258            this->valueVector_.clear();
259            for (unsigned int i = 0; i < ConfigFileManager::getSingleton()->getVectorSize(this->type_, this->sectionname_, this->varname_); i++)
[703]260            {
[1052]261                this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isA(MT_string)));
262                this->valueVector_.push_back(this->value_);
[703]263            }
264        }
265    }
266
267    /**
[1052]268        @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
[703]269        @param input The string to convert
270        @return True if the string was successfully parsed
271    */
[1052]272    bool ConfigValueContainer::parse(const std::string& input)
[703]273    {
[1052]274        if (this->bIsVector_)
275        {
276            SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0');
277            int index = -1;
278            bool success = false;
[703]279
[1052]280            if (token.size() > 0)
281                success = ConvertValue(&index, token[0]);
282
283            if (!success || index < 0 || index > MAX_VECTOR_INDEX)
[703]284            {
[1052]285                if (!success)
286                {
287                    COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
288                }
289                else
290                {
291                    COUT(1) << "Error: Invalid vector-index." << std::endl;
292                }
[703]293                return false;
294            }
295
[1052]296            if (token.size() >= 2)
297                return this->parse(index, token.subSet(1).join());
298            else
299                return this->parse(index, "");
[497]300        }
[703]301
[1052]302        MultiTypeMath temp = this->value_;
303        if (temp.fromString(input))
[871]304        {
[1052]305            this->value_ = temp;
[871]306            return true;
307        }
308        return false;
309    }
310
311    /**
[1052]312        @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
313        @param index The index in the vector
[871]314        @param input The string to convert
315        @return True if the string was successfully parsed
316    */
[1052]317    bool ConfigValueContainer::parse(unsigned int index, const std::string& input)
[871]318    {
[1052]319        if (this->bIsVector_)
[497]320        {
[1052]321            if (index >= this->valueVector_.size())
[497]322            {
[1052]323                for (unsigned int i = this->valueVector_.size(); i <= index; i++)
[497]324                {
[1052]325                    this->valueVector_.push_back(MultiTypeMath());
326                    ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isA(MT_string));
[497]327                }
[1052]328            }
[497]329
[1052]330            MultiTypeMath temp = this->value_;
331            if (temp.fromString(input))
332            {
333                this->valueVector_[index] = temp;
334                return true;
[497]335            }
[1052]336            return false;
[497]337        }
338
[1052]339        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
340        return false;
[497]341    }
342
343    /**
[1052]344        @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
345        @param input The string to convert
346        @param defvalue The default value to assign if the parsing fails
347        @return True if the string was successfully parsed
[497]348    */
[1052]349    bool ConfigValueContainer::parse(const std::string& input, const MultiTypeMath& defvalue)
[497]350    {
[1052]351        if (this->parse(input))
[497]352            return true;
353
[1052]354        this->value_ = defvalue;
[497]355        return false;
356    }
357
358    /**
[1052]359        @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
360        @param index The index in the vector
361        @param input The string to convert
362        @param defvalue The default value to assign if the parsing fails
363        @return True if the string was successfully parsed
[497]364    */
[1052]365    bool ConfigValueContainer::parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue)
[497]366    {
[1052]367        if (this->bIsVector_)
[704]368        {
[1052]369            if (this->parse(index, input))
370                return true;
[704]371
[1052]372            this->valueVector_[index] = defvalue;
373            return false;
[497]374        }
375
[1052]376        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
377        return false;
[497]378    }
379
380    /**
[705]381        @brief Adds a description to the config-value.
382        @param description The description
383    */
[715]384    void ConfigValueContainer::description(const std::string& description)
[705]385    {
386        if (!this->bAddedDescription_)
387        {
[1052]388            this->description_ = std::string("ConfigValueDescription::" + this->identifier_->getName() + "::" + this->varname_);
[871]389            AddLanguageEntry(this->description_, description);
[705]390            this->bAddedDescription_ = true;
391        }
392    }
[871]393
394    /**
395        @brief Returns the description of the config-value.
396        @return The description
397    */
398    const std::string& ConfigValueContainer::getDescription() const
399    {
400        return GetLocalisation(this->description_);
401    }
[497]402}
Note: See TracBrowser for help on using the repository browser.