Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/ConfigValueContainer.cc @ 1049

Last change on this file since 1049 was 1049, checked in by landauf, 16 years ago

config-value accepts now strings with special chars like \n or \t and hopefully every other. strings are enclosed by "…", but the quotes are only visible in the config-file. if you want something like " ← whitespace" you must add quotes, otherwise this would be stripped to "← whitespace".

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