Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/ConfigValueContainer.cc @ 8538

Last change on this file since 8538 was 8351, checked in by rgrieder, 14 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

  • No support for CEGUI 0.5, Ogre 1.4 and boost 1.35 - 1.39 any more
  • In game console is not working in main menu for CEGUI 0.7
  • Tolua (just the C lib, not the application) and CEGUILua libraries are no longer in our repository. —> You will need to get these as well when compiling Orxonox
  • And of course lots of new bugs we don't yet know about
  • Property svn:eol-style set to native
File size: 12.5 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
31    @brief Implementation of the ConfigValueContainer class.
32*/
33
34#include "ConfigValueContainer.h"
35
36#include "util/Convert.h"
37#include "util/SubString.h"
38#include "ConfigFileManager.h"
39#include "Language.h"
40
41namespace orxonox
42{
43    const unsigned int 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    /**
46        @brief Initializes the ConfigValueContainer with default values.
47    */
48    void ConfigValueContainer::init(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname)
49    {
50        this->type_ = type;
51        this->identifier_ = identifier;
52        this->sectionname_ = sectionname;
53        this->varname_ = varname;
54        this->callback_ = 0;
55        this->bContainerIsNew_ = true;
56        this->bDoInitialCallback_ = false;
57        this->bAddedDescription_ = false;
58
59        // Register containers for general settings
60        if (this->type_ == ConfigFileType::Settings)
61            SettingsConfigFile::getInstance().addConfigValueContainer(this);
62    }
63
64    /**
65        @brief Does some special initialization for single config-values.
66    */
67    void ConfigValueContainer::initValue(const MultiType& defvalue)
68    {
69        this->value_ = defvalue;
70        this->bIsVector_ = false;
71
72        this->defvalueString_ = this->value_.getString();
73        this->update();
74    }
75
76    /**
77        @brief Does some special initialization for vector config-values.
78    */
79    void ConfigValueContainer::initVector()
80    {
81        this->bIsVector_ = true;
82
83        for (unsigned int i = 0; i < this->valueVector_.size(); i++)
84        {
85            ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String));
86            this->defvalueStringVector_.push_back(this->valueVector_[i]);
87        }
88
89        this->update();
90    }
91
92    /**
93        @brief Destructor: Deletes the callback object if necessary.
94    */
95    ConfigValueContainer::~ConfigValueContainer()
96    {
97        if (this->callback_)
98            delete this->callback_;
99
100        // Unregister general settings containers
101        if (this->type_ == ConfigFileType::Settings && SettingsConfigFile::exists())
102            SettingsConfigFile::getInstance().removeConfigValueContainer(this);
103    }
104
105    /**
106        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
107        @param input The new value
108        @return True if the new value was successfully assigned
109    */
110    bool ConfigValueContainer::set(const MultiType& input)
111    {
112        if (this->bIsVector_)
113        {
114            return this->callFunctionWithIndex(&ConfigValueContainer::set, input);
115        }
116        else
117        {
118            if (this->tset(input))
119            {
120                ConfigFileManager::getInstance().getConfigFile(this->type_)->setValue(this->sectionname_, this->varname_, input, this->value_.isType(MT_Type::String));
121                return true;
122            }
123        }
124        return false;
125    }
126
127    /**
128        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
129        @param index The index in the vector
130        @param input The new value
131        @return True if the new value was successfully assigned
132    */
133    bool ConfigValueContainer::set(unsigned int index, const MultiType& input)
134    {
135        if (this->bIsVector_)
136        {
137            if (this->tset(index, input))
138            {
139                ConfigFileManager::getInstance().getConfigFile(this->type_)->setValue(this->sectionname_, this->varname_, index, input, this->value_.isType(MT_Type::String));
140                return true;
141            }
142        }
143        else
144        {
145            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
146        }
147        return false;
148    }
149
150    /**
151        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
152        @param input The new value. If bIsVector_ then write "index value"
153        @return True if the new value was successfully assigned
154    */
155    bool ConfigValueContainer::tset(const MultiType& input)
156    {
157        if (this->bIsVector_)
158        {
159            return this->callFunctionWithIndex(&ConfigValueContainer::tset, input);
160        }
161        else
162        {
163            this->value_ = input;
164
165            if (this->identifier_)
166                this->identifier_->updateConfigValues();
167
168            return true;
169        }
170    }
171
172    /**
173        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
174        @param index The index in the vector
175        @param input The new value
176        @return True if the new value was successfully assigned
177    */
178    bool ConfigValueContainer::tset(unsigned int index, const MultiType& input)
179    {
180        if (this->bIsVector_)
181        {
182            if (index > MAX_VECTOR_INDEX)
183            {
184                COUT(1) << "Error: Index " << index << " is too large." << std::endl;
185                return false;
186            }
187
188            if (index >= this->valueVector_.size())
189            {
190                for (unsigned int i = this->valueVector_.size(); i <= index; i++)
191                {
192                    this->valueVector_.push_back(MultiType());
193                }
194            }
195
196            this->valueVector_[index] = input;
197
198            if (this->identifier_)
199                this->identifier_->updateConfigValues();
200
201            return true;
202        }
203        else
204        {
205            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
206            return false;
207        }
208    }
209
210    /**
211        @brief Adds a new entry to the end of the vector.
212        @param input The new entry
213        @return True if the new entry was successfully added
214    */
215    bool ConfigValueContainer::add(const MultiType& input)
216    {
217        if (this->bIsVector_)
218            return this->set(this->valueVector_.size(), input);
219
220        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
221        return false;
222    }
223
224    /**
225        @brief Removes an existing entry from the vector.
226        @param index The index of the entry
227        @return True if the entry was removed
228    */
229    bool ConfigValueContainer::remove(unsigned int index)
230    {
231        if (this->bIsVector_)
232        {
233            if (index < this->valueVector_.size())
234            {
235                // Erase the entry from the vector, change (shift) all entries beginning with index in the config file, remove the last entry from the file
236                this->valueVector_.erase(this->valueVector_.begin() + index);
237                for (unsigned int i = index; i < this->valueVector_.size(); i++)
238                    ConfigFileManager::getInstance().getConfigFile(this->type_)->setValue(this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String));
239                ConfigFileManager::getInstance().getConfigFile(this->type_)->deleteVectorEntries(this->sectionname_, this->varname_, this->valueVector_.size());
240
241                return true;
242            }
243            COUT(1) << "Error: Invalid vector-index." << std::endl;
244        }
245
246        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
247        return false;
248    }
249
250    /**
251        @brief Sets the value of the variable back to the default value and resets the config-file entry.
252    */
253    bool ConfigValueContainer::reset()
254    {
255        if (!this->bIsVector_)
256            return this->set(this->defvalueString_);
257        else
258        {
259            bool success = true;
260            for (unsigned int i = 0; i < this->defvalueStringVector_.size(); i++)
261                if (!this->set(i, this->defvalueStringVector_[i]))
262                    success = false;
263            ConfigFileManager::getInstance().getConfigFile(this->type_)->deleteVectorEntries(this->sectionname_, this->varname_, this->defvalueStringVector_.size());
264            return success;
265        }
266    }
267
268    /**
269        @brief Retrieves the configured value from the currently loaded config-file.
270    */
271    void ConfigValueContainer::update()
272    {
273        if (!this->bIsVector_)
274            this->value_ = ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, this->defvalueString_, this->value_.isType(MT_Type::String));
275        else
276        {
277            this->valueVector_.clear();
278            unsigned int vectorSize = ConfigFileManager::getInstance().getConfigFile(this->type_)->getVectorSize(this->sectionname_, this->varname_);
279            for (unsigned int i = 0; i < vectorSize; i++)
280            {
281                if (i < this->defvalueStringVector_.size())
282                {
283                    this->value_ = ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isType(MT_Type::String));
284                }
285                else
286                {
287                    this->value_ = ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, i, MultiType(), this->value_.isType(MT_Type::String));
288                }
289
290                this->valueVector_.push_back(this->value_);
291            }
292        }
293    }
294
295    /**
296        @brief Calls the given function with parsed index and the parsed argument from the input string.
297        @param function The function to call
298        @param input The input string
299        @return The returnvalue of the functioncall
300    */
301    bool ConfigValueContainer::callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiType&), const std::string& input)
302    {
303        SubString token(input, " ", SubString::WhiteSpaces, true, '\\', false, '"', false, '\0', '\0', false, '\0');
304        int index = -1;
305        bool success = false;
306
307        if (token.size() > 0)
308            success = convertValue(&index, token[0]);
309
310        if (!success || index < 0 || index > (signed int)MAX_VECTOR_INDEX)
311        {
312            if (!success)
313            {
314                COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
315            }
316            else
317            {
318                COUT(1) << "Error: Invalid vector-index." << std::endl;
319            }
320            return false;
321        }
322
323        if (token.size() >= 2)
324            return (this->*function)(index, token.subSet(1).join());
325        else
326            return (this->*function)(index, "");
327    }
328
329    /**
330        @brief Adds a description to the config-value.
331        @param description The description
332    */
333    ConfigValueContainer& ConfigValueContainer::description(const std::string& description)
334    {
335        if (!this->bAddedDescription_)
336        {
337            this->description_ = std::string("ConfigValueDescription::" + this->sectionname_ + "::" + this->varname_);
338            AddLanguageEntry(this->description_, description);
339            this->bAddedDescription_ = true;
340        }
341        return (*this);
342    }
343
344    /**
345        @brief Returns the description of the config-value.
346        @return The description
347    */
348    const std::string& ConfigValueContainer::getDescription() const
349    {
350        return GetLocalisation(this->description_);
351    }
352}
Note: See TracBrowser for help on using the repository browser.