Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/core/ConfigValueContainer.cc @ 1494

Last change on this file since 1494 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 12.7 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        {
90                this->value_ = defvalue[0];
91
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            }
97
98            this->update();
99        }
100    }
101
102    /**
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
106    */
107    bool ConfigValueContainer::set(const MultiTypeMath& input)
108    {
109        if (this->bIsVector_)
110        {
111            return this->callFunctionWithIndex(&ConfigValueContainer::set, input.toString());
112        }
113        else
114        {
115            if (this->tset(input))
116            {
117                ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input.toString(), this->value_.isA(MT_string));
118                return true;
119            }
120        }
121        return false;
122    }
123
124    /**
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
129    */
130    bool ConfigValueContainer::set(unsigned int index, const MultiTypeMath& input)
131    {
132        if (this->bIsVector_)
133        {
134            if (this->tset(index, input))
135            {
136                ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input.toString(), this->value_.isA(MT_string));
137                return true;
138            }
139        }
140        else
141        {
142            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
143        }
144        return false;
145    }
146
147    /**
148        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
149        @param input The new value. If bIsVector_ then write "index value"
150        @return True if the new value was successfully assigned
151    */
152    bool ConfigValueContainer::tset(const MultiTypeMath& input)
153    {
154        if (this->bIsVector_)
155        {
156            return this->callFunctionWithIndex(&ConfigValueContainer::tset, input.toString());
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();
166
167                return true;
168            }
169        }
170        return false;
171    }
172
173    /**
174        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
175        @param index The index in the vector
176        @param input The new value
177        @return True if the new value was successfully assigned
178    */
179    bool ConfigValueContainer::tset(unsigned int index, const MultiTypeMath& input)
180    {
181        if (this->bIsVector_)
182        {
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
197            MultiTypeMath temp = this->value_;
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            }
207        }
208        else
209        {
210            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
211        }
212        return false;
213    }
214
215    /**
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
219    */
220    bool ConfigValueContainer::add(const MultiTypeMath& input)
221    {
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;
227    }
228
229    /**
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
233    */
234    bool ConfigValueContainer::remove(unsigned int index)
235    {
236        if (this->bIsVector_)
237        {
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;
249        }
250
251        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
252        return false;
253    }
254
255    /**
256        @brief Sets the value of the variable back to the default value and resets the config-file entry.
257    */
258    bool ConfigValueContainer::reset()
259    {
260        if (!this->bIsVector_)
261            return this->set(this->defvalueString_);
262        else
263        {
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;
270        }
271    }
272
273    /**
274        @brief Retrieves the configured value from the currently loaded config-file.
275    */
276    void ConfigValueContainer::update()
277    {
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
281        {
282            this->valueVector_.clear();
283            for (unsigned int i = 0; i < ConfigFileManager::getSingleton()->getVectorSize(this->type_, this->sectionname_, this->varname_); i++)
284            {
285                if (i < this->defvalueStringVector_.size())
286                {
287                    this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isA(MT_string)));
288                }
289                else
290                {
291                    this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, MultiTypeMath(), this->value_.isA(MT_string)));
292                }
293
294                this->valueVector_.push_back(this->value_);
295            }
296        }
297    }
298
299    /**
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
304    */
305    bool ConfigValueContainer::callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiTypeMath&), const std::string& input)
306    {
307        SubString token(input, " ", SubString::WhiteSpaces, true, '\\', false, '"', false, '(', ')', false, '\0');
308        int index = -1;
309        bool success = false;
310
311        if (token.size() > 0)
312            success = ConvertValue(&index, token[0]);
313
314        if (!success || index < 0 || index > MAX_VECTOR_INDEX)
315        {
316            if (!success)
317            {
318                COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
319            }
320            else
321            {
322                COUT(1) << "Error: Invalid vector-index." << std::endl;
323            }
324            return false;
325        }
326
327        if (token.size() >= 2)
328            return (this->*function)(index, token.subSet(1).join());
329        else
330            return (this->*function)(index, "");
331    }
332
333    /**
334        @brief Adds a description to the config-value.
335        @param description The description
336    */
337    void ConfigValueContainer::description(const std::string& description)
338    {
339        if (!this->bAddedDescription_)
340        {
341            this->description_ = std::string("ConfigValueDescription::" + this->identifier_->getName() + "::" + this->varname_);
342            AddLanguageEntry(this->description_, description);
343            this->bAddedDescription_ = true;
344        }
345    }
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    }
355}
Note: See TracBrowser for help on using the repository browser.