Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6536 was 6536, checked in by rgrieder, 14 years ago

Merged revisions 6430-6440 from the gamestate branch to the trunk.
This adds keybindings merging functionality.

(from log of r6437)
When running development builds, the keybinder will merge the local file and the one from the data folder.
Catch: if you want to remove a binding, you'll have to write "NoBinding" (not case sensitive) to override the default command

The keybind command already does that for you though.

  • Property svn:eol-style set to native
File size: 12.8 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 "Identifier.h"
53
54namespace orxonox
55{
56    class ConfigValueCallbackBase
57    {
58        public:
59            virtual void call(void* object) = 0;
60            inline virtual ~ConfigValueCallbackBase() {}
61    };
62
63    template <class T>
64    class ConfigValueCallback: public ConfigValueCallbackBase
65    {
66        public:
67            inline ConfigValueCallback(void (T::*function) (void)) : function_(function) {}
68            inline virtual ~ConfigValueCallback() {}
69            inline virtual void call(void* object)
70            {
71                if (!Identifier::isCreatingHierarchy())
72                    (static_cast<T*>(object)->*this->function_)();
73            }
74
75        private:
76            void (T::*function_) (void);
77    };
78
79
80    //! The ConfigValuecontainer contains all needed information about a configurable variable.
81    /**
82        The ConfigValueContainer class contains all needed information about a configurable variable:
83         - the name of the variable
84         - the name of the class the variable belongs to
85         - the default value
86         - the user-specified value
87         - a pointer to the entry in the config-file
88
89        This is needed to assign the configured values to all newly created objects.
90
91        The container searches for the entry in the config file.
92        If there is an entry, it parses the specified value and assigns it to the variable of the right type.
93        If there is no entry, it adds the entry with the default-value to the section of the variables class.
94        If there is no section, the section and the entry are added to the end of the config-file.
95    */
96    class _CoreExport ConfigValueContainer
97    {
98        public:
99            /**
100                @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
101                @param type The type of the corresponding config-file
102                @param identifier The identifier of the class the variable belongs to
103                @param sectionname Name of the section the configValue should be put in.
104                @param varname The name of the variable
105                @param defvalue The default-value
106                @param value Only needed do determine the right type.
107            */
108            template <class D, class V>
109            ConfigValueContainer(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const D& defvalue, const V& value)
110            {
111                this->init(type, identifier, sectionname, varname);
112                this->initValue(static_cast<V>(defvalue));
113            }
114
115            /**
116                @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
117                @param type The type of the corresponding config-file
118                @param identifier The identifier of the class the variable belongs to
119                @param varname The name of the variable
120                @param defvalue The default-value
121            */
122            template <class D, class V>
123            ConfigValueContainer(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<D>& defvalue, const std::vector<V>& value)
124            {
125                this->init(type, identifier, sectionname, varname);
126
127                this->value_ = V();
128                for (unsigned int i = 0; i < defvalue.size(); i++)
129                    this->valueVector_.push_back(MultiType(defvalue[i]));
130
131                this->initVector();
132            }
133
134            ~ConfigValueContainer();
135
136            /**
137                @brief Returns the configured value.
138                @param value A pointer to the variable to store the value.
139                @param object The object calling this function
140                @return The ConfigValueContainer
141            */
142            template <typename T, class C>
143            ConfigValueContainer& getValue(T* value, C* object)
144            {
145                if ((this->callback_ && object) || this->bContainerIsNew_)
146                {
147                    T temp = *value;
148                    this->value_.getValue(value);
149                    if (this->bContainerIsNew_ || (*value) != temp)
150                    {
151                        this->bContainerIsNew_ = false;
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 Returns the name of the section this config value is in. */
219            inline const std::string& getSectionName() const
220                { return this->sectionname_; }
221            /** @brief Returns the associated identifier (can be NULL). */
222            inline Identifier* getIdentifier() const
223                { return this->identifier_; }
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::Value 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::Value      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.