Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1412 was 1062, checked in by rgrieder, 17 years ago
  • changed header file inclusion order
File size: 14.9 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
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:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file ConfigValueContainer.cc
31    @brief Implementation of the ConfigValueContainer class.
32*/
33
34#include "ConfigValueContainer.h"
35
36#include <fstream>
37
38#include "util/SubString.h"
39#include "util/Convert.h"
40#include "Language.h"
41#include "Identifier.h"
42
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
44
45
46namespace orxonox
47{
48    /**
49        @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
50        @param type The type of the corresponding config-file
51        @param identifier The identifier of the class the variable belongs to
52        @param varname The name of the variable
53        @param defvalue The default-value
54    */
55    ConfigValueContainer::ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const MultiTypeMath& defvalue)
56    {
57        this->type_ = type;
58        this->identifier_ = identifier;
59        this->sectionname_ = identifier->getName();
60        this->varname_ = varname;
61
62        this->value_ = defvalue;
63        this->bAddedDescription_ = false;
64        this->bIsVector_ = false;
65
66        this->defvalueString_ = defvalue.toString();
67        this->update();
68    }
69
70    /**
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
76    */
77    ConfigValueContainer::ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const std::vector<MultiTypeMath>& defvalue)
78    {
79        this->type_ = type;
80        this->identifier_ = identifier;
81        this->sectionname_ = identifier->getName();
82        this->varname_ = varname;
83
84        this->valueVector_ = defvalue;
85        this->bAddedDescription_ = false;
86        this->bIsVector_ = true;
87
88        if (defvalue.size() > 0)
89            this->value_ = defvalue[0];
90
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));
93
94        for (unsigned int i = 0; i < defvalue.size(); i++)
95            this->defvalueStringVector_.push_back(defvalue[i].toString());
96
97        this->update();
98    }
99
100    /**
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
104    */
105    bool ConfigValueContainer::add(const std::string& input)
106    {
107        if (this->bIsVector_)
108            return this->set(this->valueVector_.size(), input);
109
110        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
111        return false;
112    }
113
114    /**
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
118    */
119    bool ConfigValueContainer::remove(unsigned int index)
120    {
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());
129
130                return true;
131            }
132            COUT(1) << "Error: Invalid vector-index." << std::endl;
133        }
134
135        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
136        return false;
137    }
138
139    /**
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
143    */
144    bool ConfigValueContainer::set(const std::string& input)
145    {
146        if (this->bIsVector_)
147        {
148            SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0');
149            int index = -1;
150            bool success = false;
151
152            if (token.size() > 0)
153                success = ConvertValue(&index, token[0]);
154
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            }
167
168            if (token.size() >= 2)
169                return this->set(index, token.subSet(1).join());
170            else
171                return this->set(index, "");
172        }
173
174        bool success = this->tset(input);
175        ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isA(MT_string));
176        return success;
177    }
178
179    /**
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
184    */
185    bool ConfigValueContainer::set(unsigned int index, const std::string& input)
186    {
187        if (this->bIsVector_)
188        {
189            bool success = this->tset(index, input);
190            ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isA(MT_string));
191            return success;
192        }
193
194        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
195        return false;
196    }
197
198    /**
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
202    */
203    bool ConfigValueContainer::tset(const std::string& input)
204    {
205        bool success = this->parse(input);
206        if (this->identifier_)
207            this->identifier_->updateConfigValues();
208        return success;
209    }
210
211    /**
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
216    */
217    bool ConfigValueContainer::tset(unsigned int index, const std::string& input)
218    {
219        if (this->bIsVector_)
220        {
221            bool success = this->parse(index, input);
222            if (this->identifier_)
223                this->identifier_->updateConfigValues();
224            return success;
225        }
226
227        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
228        return false;
229    }
230
231    /**
232        @brief Sets the value of the variable back to the default value and resets the config-file entry.
233    */
234    bool ConfigValueContainer::reset()
235    {
236        if (!this->bIsVector_)
237            return this->set(this->defvalueString_);
238        else
239        {
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;
246        }
247    }
248
249    /**
250        @brief Retrieves the configured value from the currently loaded config-file.
251    */
252    void ConfigValueContainer::update()
253    {
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
257        {
258            this->valueVector_.clear();
259            for (unsigned int i = 0; i < ConfigFileManager::getSingleton()->getVectorSize(this->type_, this->sectionname_, this->varname_); i++)
260            {
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_);
263            }
264        }
265    }
266
267    /**
268        @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
269        @param input The string to convert
270        @return True if the string was successfully parsed
271    */
272    bool ConfigValueContainer::parse(const std::string& input)
273    {
274        if (this->bIsVector_)
275        {
276            SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0');
277            int index = -1;
278            bool success = false;
279
280            if (token.size() > 0)
281                success = ConvertValue(&index, token[0]);
282
283            if (!success || index < 0 || index > MAX_VECTOR_INDEX)
284            {
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                }
293                return false;
294            }
295
296            if (token.size() >= 2)
297                return this->parse(index, token.subSet(1).join());
298            else
299                return this->parse(index, "");
300        }
301
302        MultiTypeMath temp = this->value_;
303        if (temp.fromString(input))
304        {
305            this->value_ = temp;
306            return true;
307        }
308        return false;
309    }
310
311    /**
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
314        @param input The string to convert
315        @return True if the string was successfully parsed
316    */
317    bool ConfigValueContainer::parse(unsigned int index, const std::string& input)
318    {
319        if (this->bIsVector_)
320        {
321            if (index >= this->valueVector_.size())
322            {
323                for (unsigned int i = this->valueVector_.size(); i <= index; i++)
324                {
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));
327                }
328            }
329
330            MultiTypeMath temp = this->value_;
331            if (temp.fromString(input))
332            {
333                this->valueVector_[index] = temp;
334                return true;
335            }
336            return false;
337        }
338
339        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
340        return false;
341    }
342
343    /**
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
348    */
349    bool ConfigValueContainer::parse(const std::string& input, const MultiTypeMath& defvalue)
350    {
351        if (this->parse(input))
352            return true;
353
354        this->value_ = defvalue;
355        return false;
356    }
357
358    /**
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
364    */
365    bool ConfigValueContainer::parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue)
366    {
367        if (this->bIsVector_)
368        {
369            if (this->parse(index, input))
370                return true;
371
372            this->valueVector_[index] = defvalue;
373            return false;
374        }
375
376        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
377        return false;
378    }
379
380    /**
381        @brief Adds a description to the config-value.
382        @param description The description
383    */
384    void ConfigValueContainer::description(const std::string& description)
385    {
386        if (!this->bAddedDescription_)
387        {
388            this->description_ = std::string("ConfigValueDescription::" + this->identifier_->getName() + "::" + this->varname_);
389            AddLanguageEntry(this->description_, description);
390            this->bAddedDescription_ = true;
391        }
392    }
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    }
402}
Note: See TracBrowser for help on using the repository browser.