Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/ConfigValueContainer.h @ 1762

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

merged core3 back to trunk

  • Property svn:eol-style set to native
File size: 12.1 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.h
31    @brief Definition of the ConfigValueContainer class.
32
33    The ConfigValueContainer class contains all needed informations about a configurable variable:
34     - the name of the variable
35     - the name of the class the variable belongs to
36     - the default value
37     - the user-specified value
38     - a pointer to the entry in the config-file
39
40    This is needed to assign the configured values to all newly created objects.
41*/
42
43#ifndef _ConfigValueContainer_H__
44#define _ConfigValueContainer_H__
45
46#include "CorePrereqs.h"
47
48#include <string>
49#include <vector>
50
51#include "util/Math.h"
52#include "util/MultiType.h"
53#include "ConfigFileManager.h"
54
55namespace orxonox
56{
57    class ConfigValueCallbackBase
58    {
59        public:
60            virtual void call(void* object) = 0;
61            inline virtual ~ConfigValueCallbackBase() {}
62    };
63
64    template <class T>
65    class ConfigValueCallback: public ConfigValueCallbackBase
66    {
67        public:
68            inline ConfigValueCallback(void (T::*function) (void)) : function_(function) {}
69            inline virtual ~ConfigValueCallback() {}
70            inline virtual void call(void* object)
71                { (((T*)object)->*this->function_)(); }
72
73        private:
74            void (T::*function_) (void);
75    };
76
77
78    //! The ConfigValuecontainer contains all needed informations about a configurable variable.
79    /**
80        The ConfigValueContainer class contains all needed informations about a configurable variable:
81         - the name of the variable
82         - the name of the class the variable belongs to
83         - the default value
84         - the user-specified value
85         - a pointer to the entry in the config-file
86
87        This is needed to assign the configured values to all newly created objects.
88
89        The container searches for the entry in the config file.
90        If there is an entry, it parses the specified value and assigns it to the variable of the right type.
91        If there is no entry, it adds the entry with the default-value to the section of the variables class.
92        If there is no section, the section and the entry are added to the end of the config-file.
93    */
94    class _CoreExport ConfigValueContainer
95    {
96        public:
97            /**
98                @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
99                @param type The type of the corresponding config-file
100                @param identifier The identifier of the class the variable belongs to
101                @param varname The name of the variable
102                @param defvalue The default-value
103                @param value Only needed do determine the right type.
104            */
105            template <class D, class V>
106            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const D& defvalue, const V& value)
107            {
108                this->init(type, identifier, varname);
109                this->initValue((V)defvalue);
110            }
111
112            /**
113                @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
114                @param type The type of the corresponding config-file
115                @param identifier The identifier of the class the variable belongs to
116                @param varname The name of the variable
117                @param defvalue The default-value
118            */
119            template <class V>
120            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const std::vector<V>& defvalue)
121            {
122                this->init(type, identifier, varname);
123
124                this->value_ = V();
125                for (unsigned int i = 0; i < defvalue.size(); i++)
126                    this->valueVector_.push_back(MultiType(defvalue[i]));
127
128                this->initVector();
129            }
130
131            ~ConfigValueContainer();
132
133            /**
134                @brief Returns the configured value.
135                @param value A pointer to the variable to store the value.
136                @param object The object calling this function
137                @return The ConfigValueContainer
138            */
139            template <typename T, class C>
140            ConfigValueContainer& getValue(T* value, C* object)
141            {
142                if ((this->callback_ && object) || this->bContainerIsNew_)
143                {
144                    if (this->bContainerIsNew_)
145                        this->bContainerIsNew_ = false;
146
147                    T temp = *value;
148                    this->value_.getValue(value);
149                    if ((*value) != temp)
150                    {
151                        if (this->callback_ && object)
152                            this->callback_->call(object);
153                        else
154                            this->bDoInitialCallback_ = true;
155                    }
156                }
157                else
158                {
159                    this->value_.getValue(value);
160                }
161                return *this;
162            }
163
164            /**
165                @brief Returns the configured vector.
166                @param value A pointer to the vector to store the values.
167                @param object The object calling this function
168                @return The ConfigValueContainer
169            */
170            template <typename T, class C>
171            ConfigValueContainer& getValue(std::vector<T>* value, C* object)
172            {
173                if ((this->callback_ && object) || this->bContainerIsNew_)
174                {
175                    if (this->bContainerIsNew_)
176                        this->bContainerIsNew_ = false;
177
178                    std::vector<T> temp = *value;
179                    value->clear();
180                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
181                        value->push_back(this->valueVector_[i]);
182
183                    if (value->size() != temp.size())
184                    {
185                        if (this->callback_ && object)
186                            this->callback_->call(object);
187                        else
188                            this->bDoInitialCallback_ = true;
189                    }
190                    else
191                    {
192                        for (unsigned int i = 0; i < value->size(); ++i)
193                        {
194                            if ((*value)[i] != temp[i])
195                            {
196                                if (this->callback_ && object)
197                                    this->callback_->call(object);
198                                else
199                                    this->bDoInitialCallback_ = true;
200                                break;
201                            }
202                        }
203                    }
204                }
205                else
206                {
207                    value->clear();
208                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
209                        value->push_back(this->valueVector_[i]);
210                }
211                return *this;
212            }
213
214            /** @brief Returns the name of this container. */
215            inline const std::string& getName() const
216                { return this->varname_; }
217            /** @brief Returns true if this config-value is a vector */
218            inline bool isVector() const
219                { return this->bIsVector_; }
220            /** @brief Returns the vectors size (or zero if it's not a vector). */
221            inline unsigned int getVectorSize() const
222                { return this->valueVector_.size(); }
223
224            ConfigValueContainer& description(const std::string& description);
225            const std::string& getDescription() const;
226
227            /**
228                @brief Adds a callback function, that gets called after getValue() if the newly assigned value differs from the old value of the variable.
229                @param object The object to call the function
230                @param function The callback function
231            */
232            template <class T>
233            inline ConfigValueContainer& callback(T* object, void (T::*function) (void))
234            {
235                if (!this->callback_)
236                {
237                    this->callback_ = new ConfigValueCallback<T>(function);
238
239                    if (this->bDoInitialCallback_)
240                    {
241                        this->bDoInitialCallback_ = false;
242                        this->callback_->call(object);
243                    }
244                }
245
246                return (*this);
247            }
248
249            bool set(const MultiType& input);
250            bool tset(const MultiType& input);
251
252            bool set(unsigned int index, const MultiType& input);
253            bool tset(unsigned int index, const MultiType& input);
254            bool add(const MultiType& input);
255            bool remove(unsigned int index);
256
257            bool reset();
258            void update();
259
260            /** @brief Converts the config-value to a string. @return The string */
261            inline std::string toString() const
262                { return this->value_; }
263            /** @brief Returns the typename of the assigned config-value. @return The typename */
264            inline std::string getTypename() const
265                { return this->value_.getTypename(); }
266
267        private:
268            void init(ConfigFileType type, Identifier* identifier, const std::string& varname);
269            void initValue(const MultiType& defvalue);
270            void initVector();
271            bool callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiType&), const std::string& input);
272
273            bool                       bIsVector_;                  //!< True if the container contains a std::vector
274
275            ConfigFileType             type_;                       //!< The type of the corresponding config-file
276            Identifier*                identifier_;                 //!< The identifier of the class
277            std::string                sectionname_;                //!< The name of the class the variable belongs to
278            std::string                varname_;                    //!< The name of the variable
279            std::string                defvalueString_;             //!< The string of the default-value
280            std::vector<std::string>   defvalueStringVector_;       //!< A vector, containg the strings of the default-values in case we're storing a vector
281
282            MultiType                  value_;                      //!< The value
283            std::vector<MultiType>     valueVector_;                //!< A vector, containg the values in case we're storing a vector
284
285            bool                       bAddedDescription_;          //!< True if a description was added
286            LanguageEntryLabel         description_;                //!< The description
287            ConfigValueCallbackBase*   callback_;                   //!< A callback function to call after getValue if the value changed
288
289            bool                       bContainerIsNew_;            //!< True if it's the first time getValue() gets called
290            bool                       bDoInitialCallback_;         //!< True if the callback should be called as soon as it gets created
291    };
292}
293
294#endif /* _ConfigValueContainer_H__ */
Note: See TracBrowser for help on using the repository browser.