Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/ConfigValueContainer.h @ 8116

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

merged doc branch back to trunk

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