Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/core/ConfigValueContainer.h @ 4454

Last change on this file since 4454 was 3196, checked in by rgrieder, 15 years ago

Merged pch branch back to trunk.

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