Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core3/src/core/ConfigValueContainer.h @ 1610

Last change on this file since 1610 was 1610, checked in by landauf, 16 years ago
  • fixed bug #1 in ConfigValueContainer (callback not being called the first time)
  • fixed another bug in XMLPort, caused by the recently added support for extern types
  • Property svn:eol-style set to native
File size: 10.1 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 ConfigValueContainer.h
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/Math.h"
52#include "util/MultiTypeMath.h"
53#include "ConfigFileManager.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                { (((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            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const MultiTypeMath& defvalue);
98            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& varname, const std::vector<MultiTypeMath>& defvalue);
99            ~ConfigValueContainer();
100
101            /** @brief Returns the configured value. @param value A pointer to the variable to store the value. @return The ConfigValueContainer */
102            template <typename T, class C>
103            ConfigValueContainer& getValue(T* value, C* object)
104            {
105std::cout << "start: " << this->getName() << std::endl;
106                if ((this->callback_ && object) || this->bContainerIsNew_)
107                {
108                    if (this->bContainerIsNew_)
109                        this->bContainerIsNew_ = false;
110
111                    T temp = *value;
112                    this->value_.getValue(value);
113                    if ((*value) != temp)
114                    {
115                        if (this->callback_ && object)
116                            this->callback_->call(object);
117                        else
118                            this->bDoInitialCallback_ = true;
119                    }
120                }
121                else
122                {
123                    this->value_.getValue(value);
124                }
125std::cout << "end" << std::endl;
126                return *this;
127            }
128
129            /** @brief Returns the configured vector. @param value A pointer to the vector to store the values. @return The ConfigValueContainer */
130            template <typename T, class C>
131            ConfigValueContainer& getValue(std::vector<T>* value, C* object)
132            {
133                if ((this->callback_ && object) || this->bContainerIsNew_)
134                {
135                    if (this->bContainerIsNew_)
136                        this->bContainerIsNew_ = false;
137
138                    std::vector<T> temp = *value;
139                    value->clear();
140                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
141                        value->push_back(this->valueVector_[i]);
142
143                    if (value->size() != temp.size())
144                    {
145                        if (this->callback_ && object)
146                            this->callback_->call(object);
147                        else
148                            this->bDoInitialCallback_ = true;
149                    }
150                    else
151                    {
152                        for (unsigned int i = 0; i < value->size(); ++i)
153                        {
154                            if ((*value)[i] != temp[i])
155                            {
156                                if (this->callback_ && object)
157                                    this->callback_->call(object);
158                                else
159                                    this->bDoInitialCallback_ = true;
160                                break;
161                            }
162                        }
163                    }
164                }
165                else
166                {
167                    value->clear();
168                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
169                        value->push_back(this->valueVector_[i]);
170                }
171                return *this;
172            }
173
174            template <typename T>
175            inline void setVectorType(const std::vector<T>& value)
176            {
177                this->value_ = T();
178                this->update();
179            }
180
181            inline const std::string& getName() const
182                { return this->varname_; }
183            inline bool isVector() const
184                { return this->bIsVector_; }
185            inline unsigned int getVectorSize() const
186                { return this->valueVector_.size(); }
187
188            ConfigValueContainer& description(const std::string& description);
189            const std::string& getDescription() const;
190
191            template <class T>
192            inline ConfigValueContainer& callback(T* object, void (T::*function) (void))
193            {
194                if (!this->callback_)
195                {
196                    this->callback_ = new ConfigValueCallback<T>(function);
197
198                    if (this->bDoInitialCallback_)
199                    {
200                        this->bDoInitialCallback_ = false;
201                        this->callback_->call(object);
202                    }
203                }
204
205                return (*this);
206            }
207
208            bool set(const MultiTypeMath& input);
209            bool tset(const MultiTypeMath& input);
210
211            bool set(unsigned int index, const MultiTypeMath& input);
212            bool tset(unsigned int index, const MultiTypeMath& input);
213            bool add(const MultiTypeMath& input);
214            bool remove(unsigned int index);
215
216            bool reset();
217            void update();
218
219            /** @brief Converts the config-value to a string. @return The string */
220            inline std::string toString() const
221                { return this->value_.toString(); }
222            /** @brief Returns the typename of the assigned config-value. @return The typename */
223            inline std::string getTypename() const
224                { return this->value_.getTypename(); }
225
226        private:
227            bool callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiTypeMath&), const std::string& input);
228
229            bool                       bIsVector_;                  //!< True if the container contains a std::vector
230
231            ConfigFileType             type_;                       //!< The type of the corresponding config-file
232            Identifier*                identifier_;                 //!< The identifier of the class
233            std::string                sectionname_;                //!< The name of the class the variable belongs to
234            std::string                varname_;                    //!< The name of the variable
235            std::string                defvalueString_;             //!< The string of the default-value
236            std::vector<std::string>   defvalueStringVector_;       //!< A vector, containg the strings of the default-values in case we're storing a vector
237
238            MultiTypeMath              value_;                      //!< The value
239            std::vector<MultiTypeMath> valueVector_;                //!< A vector, containg the values in case we're storing a vector
240
241            bool                       bAddedDescription_;          //!< True if a description was added
242            LanguageEntryLabel         description_;                //!< The description
243            ConfigValueCallbackBase*   callback_;                   //!< A callback function to call after getValue if the value changed
244
245            bool                       bContainerIsNew_;            //!< True if it's the first time getValue() gets called
246            bool                       bDoInitialCallback_;         //!< True if the callback should be called as soon as it gets created
247    };
248}
249
250#endif /* _ConfigValueContainer_H__ */
Note: See TracBrowser for help on using the repository browser.