Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/resource/src/core/ConfigValueContainer.h @ 4725

Last change on this file since 4725 was 3301, checked in by rgrieder, 15 years ago

Found even more casts. They sure aren't all of them, but I hope to have caught every pointer C-style cast because they can be very dangerous.
Note: I didn't do the pointer casts in the network library because that would have taken way too long.

  • 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            {
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 informations about a configurable variable.
82    /**
83        The ConfigValueContainer class contains all needed informations 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 V>
124            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<V>& defvalue)
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                    if (this->bContainerIsNew_)
149                        this->bContainerIsNew_ = false;
150
151                    T temp = *value;
152                    this->value_.getValue(value);
153                    if ((*value) != temp)
154                    {
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 Retuns the name of the section this config value is in. */
222            inline const std::string& getSectionName() const
223                { return this->sectionname_; }
224            /** @brief Returns true if this config-value is a vector */
225            inline bool isVector() const
226                { return this->bIsVector_; }
227            /** @brief Returns the vectors size (or zero if it's not a vector). */
228            inline unsigned int getVectorSize() const
229                { return this->valueVector_.size(); }
230
231            ConfigValueContainer& description(const std::string& description);
232            const std::string& getDescription() const;
233
234            /**
235                @brief Adds a callback function, that gets called after getValue() if the newly assigned value differs from the old value of the variable.
236                @param object The object to call the function
237                @param function The callback function
238            */
239            template <class T>
240            inline ConfigValueContainer& callback(T* object, void (T::*function) (void))
241            {
242                if (!this->callback_)
243                {
244                    this->callback_ = new ConfigValueCallback<T>(function);
245
246                    if (this->bDoInitialCallback_)
247                    {
248                        this->bDoInitialCallback_ = false;
249                        this->callback_->call(object);
250                    }
251                }
252
253                return (*this);
254            }
255
256            bool set(const MultiType& input);
257            bool tset(const MultiType& input);
258
259            bool set(unsigned int index, const MultiType& input);
260            bool tset(unsigned int index, const MultiType& input);
261            bool add(const MultiType& input);
262            bool remove(unsigned int index);
263
264            bool reset();
265            void update();
266
267            /** @brief Converts the config-value to a string. @return The string */
268            inline std::string toString() const
269                { return this->value_; }
270            /** @brief Returns the typename of the assigned config-value. @return The typename */
271            inline std::string getTypename() const
272                { return this->value_.getTypename(); }
273
274        private:
275            void init(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname);
276            void initValue(const MultiType& defvalue);
277            void initVector();
278            bool callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiType&), const std::string& input);
279
280            bool                       bIsVector_;                  //!< True if the container contains a std::vector
281
282            ConfigFileType             type_;                       //!< The type of the corresponding config-file
283            Identifier*                identifier_;                 //!< The identifier of the class
284            std::string                sectionname_;                //!< The name of the class the variable belongs to
285            std::string                varname_;                    //!< The name of the variable
286            std::string                defvalueString_;             //!< The string of the default-value
287            std::vector<std::string>   defvalueStringVector_;       //!< A vector, containg the strings of the default-values in case we're storing a vector
288
289            MultiType                  value_;                      //!< The value
290            std::vector<MultiType>     valueVector_;                //!< A vector, containg the values in case we're storing a vector
291
292            bool                       bAddedDescription_;          //!< True if a description was added
293            LanguageEntryLabel         description_;                //!< The description
294            ConfigValueCallbackBase*   callback_;                   //!< A callback function to call after getValue if the value changed
295
296            bool                       bContainerIsNew_;            //!< True if it's the first time getValue() gets called
297            bool                       bDoInitialCallback_;         //!< True if the callback should be called as soon as it gets created
298    };
299}
300
301#endif /* _ConfigValueContainer_H__ */
Note: See TracBrowser for help on using the repository browser.