Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/core/ConfigValueContainer.cc @ 1052

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

merged core2 back to trunk
there might be some errors, wasn't able to test it yet due to some strange g++ and linker behaviour.

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.