Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/core/XMLPort.h @ 1473

Last change on this file since 1473 was 1446, checked in by landauf, 16 years ago

merged console branch into network branch

after several heavy troubles it compiles, but there is still a bug I couldn't fix: orxonox crashes as soon as one presses a key after opening the console… maybe someone else sees the problem?

File size: 19.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#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                    }
155                    catch (ticpp::Exception& ex)
156                    {
157                        COUT(1) << std::endl;
158                        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;
159                        COUT(1) << ex.what() << std::endl;
160                    }
161                }
162                else
163                {
164                    if (this->saveexecutor_)
165                    {
166//                        xmlelement.SetAttribute(this->paramname_, "...");
167                    }
168                }
169
170                return (*this);
171            }
172
173            XMLPortParamContainer& port(const ParseParams& parseParams)
174            {
175                return this->port(parseParams.object, *parseParams.xmlelement, parseParams.mode);
176            }
177
178            XMLPortParamContainer& portIfWaitingForDefaultValues(const ParseResult& result, const ParseParams& params)
179            {
180                if (result == PR_waiting_for_default_values)
181                    return this->port(params);
182                else
183                    return (*this);
184            }
185
186            virtual XMLPortParamContainer& description(const std::string description)
187                { this->loadexecutor_->setDescription(description); return (*this); }
188            virtual const std::string& getDescription()
189                { return this->loadexecutor_->getDescription(); }
190
191            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiTypeMath& param)
192            {
193                if (!this->loadexecutor_->defaultValueSet(index))
194                    this->loadexecutor_->setDefaultValue(index, param);
195                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
196            }
197            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1)
198            {
199                if (!this->loadexecutor_->defaultValueSet(0))
200                    this->loadexecutor_->setDefaultValues(param1);
201                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
202            }
203            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2)
204            {
205                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)))
206                    this->loadexecutor_->setDefaultValues(param1, param2);
207                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
208            }
209            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3)
210            {
211                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)))
212                    this->loadexecutor_->setDefaultValues(param1, param2, param3);
213                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
214            }
215            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4)
216            {
217                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)))
218                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4);
219                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
220            }
221            virtual XMLPortParamContainer& defaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4, const MultiTypeMath& param5)
222            {
223                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)) || (!this->loadexecutor_->defaultValueSet(4)))
224                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4, param5);
225                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
226            }
227
228        private:
229            ExecutorMember<T>* loadexecutor_;
230            ExecutorMember<T>* saveexecutor_;
231            ParseParams parseParams_;
232    };
233
234
235    // ################################
236    // ###  XMLPortObjectContainer  ###
237    // ################################
238    class _CoreExport XMLPortObjectContainer
239    {
240        public:
241            XMLPortObjectContainer()
242                { this->bApplyLoaderMask_ = false; }
243            virtual ~XMLPortObjectContainer() {}
244
245            inline const std::string& getName() const
246                { return this->sectionname_; }
247
248            virtual XMLPortObjectContainer& description(const std::string description) = 0;
249            virtual const std::string& getDescription() = 0;
250
251            bool identifierIsIncludedInLoaderMask(const Identifier* identifier);
252
253        protected:
254            std::string sectionname_;
255            bool bApplyLoaderMask_;
256            bool bLoadBefore_;
257    };
258
259    template <class T, class O>
260    class XMLPortClassObjectContainer : public XMLPortObjectContainer
261    {
262        public:
263            XMLPortClassObjectContainer(const std::string sectionname, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore)
264            {
265                this->sectionname_ = sectionname;
266                this->loadexecutor_ = loadexecutor;
267                this->saveexecutor_ = saveexecutor;
268                this->bApplyLoaderMask_ = bApplyLoaderMask;
269                this->bLoadBefore_ = bLoadBefore;
270            }
271
272            XMLPortObjectContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode)
273            {
274                if (mode == XMLPort::LoadObject)
275                {
276                    try
277                    {
278                        Element* xmlsubelement;
279                        if ((this->sectionname_ != "") && (this->sectionname_.size() > 0))
280                            xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
281                        else
282                            xmlsubelement = &xmlelement;
283
284                        if (xmlsubelement)
285                        {
286                            for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
287                            {
288                                Identifier* identifier = ID(child->Value());
289                                if (identifier)
290                                {
291                                    if (identifier->isA(Class(O)))
292                                    {
293                                        if (this->identifierIsIncludedInLoaderMask(identifier))
294                                        {
295                                            COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
296
297                                            BaseObject* newObject = identifier->fabricate();
298                                            newObject->setLoaderIndentation(((BaseObject*)object)->getLoaderIndentation() + "  ");
299                                            newObject->setLevel(((BaseObject*)object)->getLevel());
300                                            newObject->setNamespace(((BaseObject*)object)->getNamespace());
301
302                                            if (this->bLoadBefore_)
303                                            {
304                                                newObject->XMLPort(*child, XMLPort::LoadObject);
305                                                COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << object->getIdentifier()->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
306                                            }
307                                            else
308                                            {
309                                                COUT(4) << ((BaseObject*)object)->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << object->getIdentifier()->getName() << " (objectname " << ((BaseObject*)object)->getName() << ")" << std::endl;
310                                            }
311
312                                            COUT(5) << ((BaseObject*)object)->getLoaderIndentation();
313                                            (*this->loadexecutor_)(object, newObject);
314
315                                            if (!this->bLoadBefore_)
316                                                newObject->XMLPort(*child, XMLPort::LoadObject);
317
318                                            COUT(5) << ((BaseObject*)object)->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
319                                        }
320                                    }
321                                    else
322                                    {
323                                        COUT(2) << ((BaseObject*)object)->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << Class(O)->getName() << "'." << std::endl;
324                                    }
325                                }
326                                else
327                                {
328                                    COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
329                                }
330                            }
331                        }
332                    }
333                    catch (ticpp::Exception& ex)
334                    {
335                        COUT(1) << std::endl;
336                        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;
337                        COUT(1) << ex.what() << std::endl;
338                    }
339                }
340                else
341                {
342                }
343
344                return (*this);
345            }
346
347            virtual XMLPortObjectContainer& description(const std::string description)
348                { this->loadexecutor_->setDescription(description); return (*this); }
349            virtual const std::string& getDescription()
350                { return this->loadexecutor_->getDescription(); }
351
352        private:
353            ExecutorMember<T>* loadexecutor_;
354            ExecutorMember<T>* saveexecutor_;
355    };
356}
357
358#endif /* _XMLPort_H__ */
Note: See TracBrowser for help on using the repository browser.