Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/doc/src/libraries/core/ConfigValueContainer.h @ 7363

Last change on this file since 7363 was 7363, checked in by landauf, 14 years ago

assigned a group to each header file in the core library

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