Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/core/XMLPort.h @ 1844

Last change on this file since 1844 was 1638, checked in by rgrieder, 16 years ago

merged input branch into gui test branch (was about time)
svn save (it's still a mess and CMLs haven't been updated)
I'll have to create a special project to create the tolua_bind files for tolua itself anyway..

  • Property svn:eol-style set to native
File size: 19.3 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#ifndef _XMLPort_H__
30#define _XMLPort_H__
31
32#include "CorePrereqs.h"
33
34#include "util/XMLIncludes.h"
35#include "util/MultiTypeMath.h"
36#include "tinyxml/ticpp.h"
37#include "Executor.h"
38#include "Debug.h"
39#include "CoreIncludes.h"
40#include "BaseObject.h"
41
42
43#define XMLPortParam(classname, paramname, loadfunction, savefunction, xmlelement, mode) \
44    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, paramname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), #savefunction), xmlelement, mode)
45#define XMLPortParam_Template(classname, paramname, loadtemplate, loadfunction, savetemplate, savefunction, xmlelement, mode) \
46    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, paramname, orxonox::createExecutor(orxonox::createFunctor loadtemplate (&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor savetemplate (&classname::savefunction), #savefunction), xmlelement, mode)
47
48#define XMLPortParamLoadOnly(classname, paramname, loadfunction, xmlelement, mode) \
49    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, paramname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), #loadfunction), 0, xmlelement, mode)
50#define XMLPortParamLoadOnly_Template(classname, paramname, loadtemplate, loadfunction, xmlelement, mode) \
51    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, paramname, orxonox::createExecutor(orxonox::createFunctor loadtemplate (&classname::loadfunction), #loadfunction), 0, xmlelement, mode)
52
53#define XMLPortParamGeneric(containername, classname, paramname, loadexecutor, saveexecutor, xmlelement, mode) \
54    orxonox::XMLPortClassParamContainer<classname>* containername = (orxonox::XMLPortClassParamContainer<classname>*)(this->getIdentifier()->getXMLPortParamContainer(paramname)); \
55    if (!containername) \
56    { \
57        containername = new orxonox::XMLPortClassParamContainer<classname>(std::string(paramname), loadexecutor, saveexecutor); \
58        this->getIdentifier()->addXMLPortParamContainer(paramname, containername); \
59    } \
60    containername->port(this, xmlelement, mode)
61
62
63#define XMLPortObject(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
64    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), #savefunction), xmlelement, mode, bApplyLoaderMask, bLoadBefore)
65#define XMLPortObject_Template(classname, objectclass, sectionname, loadtemplate, loadfunction, savetemplate, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
66    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, orxonox::createExecutor(orxonox::createFunctor loadtemplate (&classname::loadfunction), #loadfunction), orxonox::createExecutor(orxonox::createFunctor savetemplate (&classname::savefunction), #savefunction), xmlelement, mode, bApplyLoaderMask, bLoadBefore)
67
68#define XMLPortObjectGeneric(containername, classname, objectclass, sectionname, loadexecutor, saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
69    orxonox::XMLPortClassObjectContainer<classname, objectclass>* containername = (orxonox::XMLPortClassObjectContainer<classname, objectclass>*)(this->getIdentifier()->getXMLPortObjectContainer(sectionname)); \
70    if (!containername) \
71    { \
72        containername = new orxonox::XMLPortClassObjectContainer<classname, objectclass>(std::string(sectionname), loadexecutor, saveexecutor, bApplyLoaderMask, bLoadBefore); \
73        this->getIdentifier()->addXMLPortObjectContainer(sectionname, containername); \
74    } \
75    containername->port(this, xmlelement, mode)
76
77
78namespace orxonox
79{
80    // ###############################
81    // ###  XMLPortParamContainer  ###
82    // ###############################
83    class _CoreExport XMLPortParamContainer
84    {
85    public:
86        enum ParseResult
87        {
88            PR_not_started,
89            PR_finished,
90            PR_waiting_for_default_values
91        };
92
93        public:
94            XMLPortParamContainer()
95                { this->parseResult_ = PR_not_started; }
96            virtual ~XMLPortParamContainer() {}
97
98            inline const std::string& getName() const
99                { return this->paramname_; }
100
101            virtual XMLPortParamContainer& description(const std::string description) = 0;
102            virtual const std::string& getDescription() = 0;
103
104            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiTypeMath& param) = 0;
105            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1) = 0;
106            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2) = 0;
107            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3) = 0;
108            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4) = 0;
109            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4, const MultiTypeMath& param5) = 0;
110
111        protected:
112            std::string paramname_;
113            ParseResult parseResult_;
114
115    };
116
117    template <class T>
118    class XMLPortClassParamContainer : public XMLPortParamContainer
119    {
120        struct ParseParams
121        {
122            T* object;
123            Element* xmlelement;
124            XMLPort::Mode mode;
125        };
126
127        public:
128            XMLPortClassParamContainer(const std::string paramname, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor)
129            {
130                this->paramname_ = paramname;
131                this->loadexecutor_ = loadexecutor;
132                this->saveexecutor_ = saveexecutor;
133            }
134
135            XMLPortParamContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode)
136            {
137                this->parseParams_.object = object;
138                this->parseParams_.xmlelement = &xmlelement;
139                this->parseParams_.mode = mode;
140
141                if (mode == XMLPort::LoadObject)
142                {
143                    try
144                    {
145                        std::string attribute = xmlelement.GetAttribute(this->paramname_);
146                        if ((attribute.size() > 0) || (this->loadexecutor_->allDefaultValuesSet()))
147                        {
148                            COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "Loading parameter " << this->paramname_ << " in " << object->getIdentifier()->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")." << std::endl << ((BaseObject*)object)->getLoaderIndentation();
149                            if (this->loadexecutor_->parse(object, attribute, ","))
150                                this->parseResult_ = PR_finished;
151                            else
152                                this->parseResult_ = PR_waiting_for_default_values;
153                        }
154                        else
155                            this->parseResult_ = PR_waiting_for_default_values;
156                    }
157                    catch (ticpp::Exception& ex)
158                    {
159                        COUT(1) << std::endl;
160                        COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << object->getIdentifier()->getName() << "' (objectname: " << ((BaseObject*)object)->getName() << ") in " << ((BaseObject*)object)->getLevelfile() << ":" << std::endl;
161                        COUT(1) << ex.what() << std::endl;
162                    }
163                }
164                else
165                {
166                    if (this->saveexecutor_)
167                    {
168//                        xmlelement.SetAttribute(this->paramname_, "...");
169                    }
170                }
171
172                return (*this);
173            }
174
175            XMLPortParamContainer& port(const ParseParams& parseParams)
176            {
177                return this->port(parseParams.object, *parseParams.xmlelement, parseParams.mode);
178            }
179
180            XMLPortParamContainer& portIfWaitingForDefaultValues(const ParseResult& result, const ParseParams& params)
181            {
182                if (result == PR_waiting_for_default_values)
183                    return this->port(params);
184                else
185                    return (*this);
186            }
187
188            virtual XMLPortParamContainer& description(const std::string description)
189                { this->loadexecutor_->setDescription(description); return (*this); }
190            virtual const std::string& getDescription()
191                { return this->loadexecutor_->getDescription(); }
192
193            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiTypeMath& param)
194            {
195                if (!this->loadexecutor_->defaultValueSet(index))
196                    this->loadexecutor_->setDefaultValue(index, param);
197                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
198            }
199            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1)
200            {
201                if (!this->loadexecutor_->defaultValueSet(0))
202                    this->loadexecutor_->setDefaultValues(param1);
203                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
204            }
205            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2)
206            {
207                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)))
208                    this->loadexecutor_->setDefaultValues(param1, param2);
209                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
210            }
211            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3)
212            {
213                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)))
214                    this->loadexecutor_->setDefaultValues(param1, param2, param3);
215                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
216            }
217            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4)
218            {
219                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)))
220                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4);
221                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
222            }
223            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4, const MultiTypeMath& param5)
224            {
225                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)) || (!this->loadexecutor_->defaultValueSet(4)))
226                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4, param5);
227                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
228            }
229
230        private:
231            ExecutorMember<T>* loadexecutor_;
232            ExecutorMember<T>* saveexecutor_;
233            ParseParams parseParams_;
234    };
235
236
237    // ################################
238    // ###  XMLPortObjectContainer  ###
239    // ################################
240    class _CoreExport XMLPortObjectContainer
241    {
242        public:
243            XMLPortObjectContainer()
244                { this->bApplyLoaderMask_ = false; }
245            virtual ~XMLPortObjectContainer() {}
246
247            inline const std::string& getName() const
248                { return this->sectionname_; }
249
250            virtual XMLPortObjectContainer& description(const std::string description) = 0;
251            virtual const std::string& getDescription() = 0;
252
253            bool identifierIsIncludedInLoaderMask(const Identifier* identifier);
254
255        protected:
256            std::string sectionname_;
257            bool bApplyLoaderMask_;
258            bool bLoadBefore_;
259    };
260
261    template <class T, class O>
262    class XMLPortClassObjectContainer : public XMLPortObjectContainer
263    {
264        public:
265            XMLPortClassObjectContainer(const std::string sectionname, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore)
266            {
267                this->sectionname_ = sectionname;
268                this->loadexecutor_ = loadexecutor;
269                this->saveexecutor_ = saveexecutor;
270                this->bApplyLoaderMask_ = bApplyLoaderMask;
271                this->bLoadBefore_ = bLoadBefore;
272            }
273
274            XMLPortObjectContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode)
275            {
276                if (mode == XMLPort::LoadObject)
277                {
278                    try
279                    {
280                        Element* xmlsubelement;
281                        if ((this->sectionname_ != "") && (this->sectionname_.size() > 0))
282                            xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
283                        else
284                            xmlsubelement = &xmlelement;
285
286                        if (xmlsubelement)
287                        {
288                            for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
289                            {
290                                Identifier* identifier = GetIdentifier(child->Value());
291                                if (identifier)
292                                {
293                                    if (identifier->isA(Class(O)))
294                                    {
295                                        if (this->identifierIsIncludedInLoaderMask(identifier))
296                                        {
297                                            COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
298
299                                            BaseObject* newObject = identifier->fabricate();
300                                            newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + "  ");
301                                            newObject->setLevel(((BaseObject*)object)->getLevel());
302                                            newObject->setNamespace(((BaseObject*)object)->getNamespace());
303
304                                            if (this->bLoadBefore_)
305                                            {
306                                                newObject->XMLPort(*child, XMLPort::LoadObject);
307                                                COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << object->getIdentifier()->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
308                                            }
309                                            else
310                                            {
311                                                COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << object->getIdentifier()->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
312                                            }
313
314                                            COUT(5) << ((BaseObject*)object)->getLoaderIndentation();
315                                            (*this->loadexecutor_)(object, newObject);
316
317                                            if (!this->bLoadBefore_)
318                                                newObject->XMLPort(*child, XMLPort::LoadObject);
319
320                                            COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
321                                        }
322                                    }
323                                    else
324                                    {
325                                        COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << Class(O)->getName() << "'." << std::endl;
326                                    }
327                                }
328                                else
329                                {
330                                    COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
331                                }
332                            }
333                        }
334                    }
335                    catch (ticpp::Exception& ex)
336                    {
337                        COUT(1) << std::endl;
338                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << Class(O)->getName() << "' in '" << this->sectionname_ << "' of '" << object->getIdentifier()->getName() << "' (objectname: " << ((BaseObject*)object)->getName() << ") in " << object->getLevelfile() << ":" << std::endl;
339                        COUT(1) << ex.what() << std::endl;
340                    }
341                }
342                else
343                {
344                }
345
346                return (*this);
347            }
348
349            virtual XMLPortObjectContainer& description(const std::string description)
350                { this->loadexecutor_->setDescription(description); return (*this); }
351            virtual const std::string& getDescription()
352                { return this->loadexecutor_->getDescription(); }
353
354        private:
355            ExecutorMember<T>* loadexecutor_;
356            ExecutorMember<T>* saveexecutor_;
357    };
358}
359
360#endif /* _XMLPort_H__ */
Note: See TracBrowser for help on using the repository browser.