Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/libraries/core/ConfigValueContainer.h @ 6415

Last change on this file since 6415 was 6243, checked in by rgrieder, 15 years ago

Modified config value macros so you can use them as one-liner.
And the macro code also gone: it can now be easily debugged in an inline function.
(Changes do not apply to ModifyConfigValue because it was impossible to do).

  • Property svn:eol-style set to native
File size: 12.6 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 Definition of the ConfigValueContainer class.
32
33    The ConfigValueContainer class contains all needed information 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/MultiType.h"
52#include "ConfigFileManager.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 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 varname The name of the variable
121                @param defvalue The default-value
122            */
123            template <class D, class V>
124            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<D>& defvalue, const std::vector<V>& value)
125            {
126                this->init(type, identifier, sectionname, varname);
127
128                this->value_ = V();
129                for (unsigned int i = 0; i < defvalue.size(); i++)
130                    this->valueVector_.push_back(MultiType(defvalue[i]));
131
132                this->initVector();
133            }
134
135            ~ConfigValueContainer();
136
137            /**
138                @brief Returns the configured value.
139                @param value A pointer to the variable to store the value.
140                @param object The object calling this function
141                @return The ConfigValueContainer
142            */
143            template <typename T, class C>
144            ConfigValueContainer& getValue(T* value, C* object)
145            {
146                if ((this->callback_ && object) || this->bContainerIsNew_)
147                {
148                    T temp = *value;
149                    this->value_.getValue(value);
150                    if (this->bContainerIsNew_ || (*value) != temp)
151                    {
152                        this->bContainerIsNew_ = false;
153                        if (this->callback_ && object)
154                            this->callback_->call(object);
155                        else
156                            this->bDoInitialCallback_ = true;
157                    }
158                }
159                else
160                {
161                    this->value_.getValue(value);
162                }
163                return *this;
164            }
165
166            /**
167                @brief Returns the configured vector.
168                @param value A pointer to the vector to store the values.
169                @param object The object calling this function
170                @return The ConfigValueContainer
171            */
172            template <typename T, class C>
173            ConfigValueContainer& getValue(std::vector<T>* value, C* object)
174            {
175                if ((this->callback_ && object) || this->bContainerIsNew_)
176                {
177                    if (this->bContainerIsNew_)
178                        this->bContainerIsNew_ = false;
179
180                    std::vector<T> temp = *value;
181                    value->clear();
182                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
183                        value->push_back(this->valueVector_[i]);
184
185                    if (value->size() != temp.size())
186                    {
187                        if (this->callback_ && object)
188                            this->callback_->call(object);
189                        else
190                            this->bDoInitialCallback_ = true;
191                    }
192                    else
193                    {
194                        for (unsigned int i = 0; i < value->size(); ++i)
195                        {
196                            if ((*value)[i] != temp[i])
197                            {
198                                if (this->callback_ && object)
199                                    this->callback_->call(object);
200                                else
201                                    this->bDoInitialCallback_ = true;
202                                break;
203                            }
204                        }
205                    }
206                }
207                else
208                {
209                    value->clear();
210                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
211                        value->push_back(this->valueVector_[i]);
212                }
213                return *this;
214            }
215
216            /** @brief Returns the name of this container. */
217            inline const std::string& getName() const
218                { return this->varname_; }
219            /** @brief Retuns the name of the section this config value is in. */
220            inline const std::string& getSectionName() const
221                { return this->sectionname_; }
222            /** @brief Returns true if this config-value is a vector */
223            inline bool isVector() const
224                { return this->bIsVector_; }
225            /** @brief Returns the vectors size (or zero if it's not a vector). */
226            inline unsigned int getVectorSize() const
227                { return this->valueVector_.size(); }
228
229            ConfigValueContainer& description(const std::string& description);
230            const std::string& getDescription() const;
231
232            /**
233                @brief Adds a callback function, that gets called after getValue() if the newly assigned value differs from the old value of the variable.
234                @param object The object to call the function
235                @param function The callback function
236            */
237            template <class T>
238            inline ConfigValueContainer& callback(T* object, void (T::*function) (void))
239            {
240                if (!this->callback_)
241                {
242                    this->callback_ = new ConfigValueCallback<T>(function);
243
244                    if (this->bDoInitialCallback_)
245                    {
246                        this->bDoInitialCallback_ = false;
247                        this->callback_->call(object);
248                    }
249                }
250
251                return (*this);
252            }
253
254            bool set(const MultiType& input);
255            bool tset(const MultiType& input);
256
257            bool set(unsigned int index, const MultiType& input);
258            bool tset(unsigned int index, const MultiType& input);
259            bool add(const MultiType& input);
260            bool remove(unsigned int index);
261
262            bool reset();
263            void update();
264
265            /** @brief Converts the config-value to a string. @return The string */
266            inline std::string toString() const
267                { return this->value_; }
268            /** @brief Returns the typename of the assigned config-value. @return The typename */
269            inline std::string getTypename() const
270                { return this->value_.getTypename(); }
271
272        private:
273            void init(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname);
274            void initValue(const MultiType& defvalue);
275            void initVector();
276            bool callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiType&), const std::string& input);
277
278            bool                       bIsVector_;                  //!< True if the container contains a std::vector
279
280            ConfigFileType             type_;                       //!< The type of the corresponding config-file
281            Identifier*                identifier_;                 //!< The identifier of the class
282            std::string                sectionname_;                //!< The name of the class the variable belongs to
283            std::string                varname_;                    //!< The name of the variable
284            std::string                defvalueString_;             //!< The string of the default-value
285            std::vector<std::string>   defvalueStringVector_;       //!< A vector, containg the strings of the default-values in case we're storing a vector
286
287            MultiType                  value_;                      //!< The value
288            std::vector<MultiType>     valueVector_;                //!< A vector, containg the values in case we're storing a vector
289
290            bool                       bAddedDescription_;          //!< True if a description was added
291            LanguageEntryLabel         description_;                //!< The description
292            ConfigValueCallbackBase*   callback_;                   //!< A callback function to call after getValue if the value changed
293
294            bool                       bContainerIsNew_;            //!< True if it's the first time getValue() gets called
295            bool                       bDoInitialCallback_;         //!< True if the callback should be called as soon as it gets created
296    };
297}
298
299#endif /* _ConfigValueContainer_H__ */
Note: See TracBrowser for help on using the repository browser.