Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/core/BaseObject.cc @ 2743

Last change on this file since 2743 was 2539, checked in by rgrieder, 16 years ago

XML Attribute are case insensitive now. However this does not applay to tags since they refer to actual classes, which are case sensitive.

  • Property svn:eol-style set to native
File size: 11.2 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 Implementation of the BaseObject class.
32*/
33
34#include "BaseObject.h"
35#include "tinyxml/tinyxml.h"
36#include "CoreIncludes.h"
37#include "EventIncludes.h"
38#include "Functor.h"
39#include "XMLPort.h"
40#include "XMLFile.h"
41#include "XMLNameListener.h"
42#include "Template.h"
43#include "util/String.h"
44#include "util/mbool.h"
45
46namespace orxonox
47{
48    CreateFactory(BaseObject);
49
50    /**
51        @brief Constructor: Registers the object in the BaseObject-list.
52    */
53    BaseObject::BaseObject(BaseObject* creator) : bInitialized_(false)
54    {
55        RegisterRootObject(BaseObject);
56
57        this->bInitialized_ = true;
58
59        this->bActive_ = true;
60        this->bVisible_ = true;
61        this->oldGametype_ = 0;
62
63        this->lastLoadedXMLElement_ = 0;
64
65        this->functorSetMainState_ = 0;
66        this->functorGetMainState_ = 0;
67
68        this->setCreator(creator);
69        if (this->creator_)
70        {
71            this->setFile(this->creator_->getFile());
72            this->setNamespace(this->creator_->getNamespace());
73            this->setScene(this->creator_->getScene());
74            this->setGametype(this->creator_->getGametype());
75        }
76        else
77        {
78            this->file_ = 0;
79            this->namespace_ = 0;
80            this->scene_ = 0;
81            this->gametype_ = 0;
82        }
83    }
84
85    /**
86        @brief Destructor
87    */
88    BaseObject::~BaseObject()
89    {
90        if (this->isInitialized())
91        {
92            for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
93                (*it)->unregisterEventListener(this);
94
95            for (std::map<BaseObject*, std::string>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
96                it->first->removeEvent(this);
97
98            if (this->functorSetMainState_)
99                delete this->functorSetMainState_;
100            if (this->functorGetMainState_)
101                delete this->functorGetMainState_;
102        }
103    }
104
105    /**
106        @brief XML loading and saving.
107        @param xmlelement The XML-element
108        @param loading Loading (true) or saving (false)
109        @return The XML-element
110    */
111    void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode)
112    {
113        XMLPortParam(BaseObject, "name", setXMLName, getName, xmlelement, mode);
114        XMLPortParam(BaseObject, "visible", setVisible, isVisible, xmlelement, mode);
115        XMLPortParam(BaseObject, "active", setActive, isActive, xmlelement, mode);
116        XMLPortParam(BaseObject, "mainstate", setMainStateName, getMainStateName, xmlelement, mode);
117
118        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
119
120        Element* events = xmlelement.FirstChildElement("events", false);
121
122        if (events)
123        {
124            std::list<std::string> eventnames;
125
126            if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
127            {
128                for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++)
129                    eventnames.push_back(child->Value());
130            }
131            else if (mode == XMLPort::SaveObject)
132            {
133                for (std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->getIdentifier()->getXMLPortEventMapBegin(); it != this->getIdentifier()->getXMLPortEventMapEnd(); ++it)
134                    eventnames.push_back(it->first);
135            }
136
137            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
138            {
139                std::string sectionname = (*it);
140                ExecutorMember<BaseObject>* loadexecutor = createExecutor(createFunctor(&BaseObject::addEvent), std::string( "BaseObject" ) + "::" + "addEvent");
141                ExecutorMember<BaseObject>* saveexecutor = createExecutor(createFunctor(&BaseObject::getEvent), std::string( "BaseObject" ) + "::" + "getEvent");
142                loadexecutor->setDefaultValue(1, sectionname);
143
144                XMLPortClassObjectContainer<BaseObject, BaseObject>* container = 0;
145                container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(this->getIdentifier()->getXMLPortEventContainer(sectionname));
146                if (!container)
147                {
148                    container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(sectionname, this->getIdentifier(), loadexecutor, saveexecutor, false, true);
149                    this->getIdentifier()->addXMLPortEventContainer(sectionname, container);
150                }
151                container->port(this, *events, mode);
152            }
153        }
154    }
155
156    /**
157        @brief Loads the name of the object through XML and calls all XMLNameListener.
158        @param name The name of the object
159    */
160    void BaseObject::setXMLName(const std::string& name)
161    {
162        this->setName(name);
163
164        for (ObjectList<XMLNameListener>::iterator it = ObjectList<XMLNameListener>::begin(); it != ObjectList<XMLNameListener>::end(); ++it)
165            it->loadedNewXMLName(this);
166    }
167
168    /**
169        @brief Returns the levelfile that loaded this object.
170        @return The levelfile
171    */
172    const std::string& BaseObject::getFilename() const
173    {
174        if (this->file_)
175            return this->file_->getFilename();
176        else
177            return BLANKSTRING;
178    }
179
180    /**
181        @brief Adds a Template to the object.
182        @param name The name of the Template
183    */
184    void BaseObject::addTemplate(const std::string& name)
185    {
186        Template* temp = Template::getTemplate(name);
187        if (temp)
188            this->addTemplate(temp);
189        else
190            COUT(1) << "Error: \"" << name << "\" is not a valid Template name (in class: " << this->getIdentifier()->getName() << ", name: " << this->getName() << ")." << std::endl;
191    }
192
193    /**
194        @brief Adds a Template to the object.
195        @param temp The Template
196    */
197    void BaseObject::addTemplate(Template* temp)
198    {
199        this->templates_.insert(temp);
200        temp->applyOn(this);
201    }
202
203    /**
204        @brief Returns the Template with the given index.
205        @param index The index
206    */
207    Template* BaseObject::getTemplate(unsigned int index) const
208    {
209        unsigned int i = 0;
210        for (std::set<Template*>::const_iterator it = this->templates_.begin(); it != this->templates_.end(); ++it)
211        {
212            if (i == index)
213                return (*it);
214            i++;
215        }
216        return 0;
217    }
218
219    void BaseObject::addEvent(BaseObject* event, const std::string& sectionname)
220    {
221        event->registerEventListener(this, sectionname);
222        this->events_.push_back(event);
223    }
224
225    void BaseObject::removeEvent(BaseObject* event)
226    {
227        this->events_.remove(event);
228    }
229
230    BaseObject* BaseObject::getEvent(unsigned int index) const
231    {
232        unsigned int i = 0;
233        for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
234        {
235            if (i == index)
236                return (*it);
237            ++i;
238        }
239        return 0;
240    }
241
242    void BaseObject::addEventContainer(const std::string& sectionname, EventContainer* container)
243    {
244        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
245        if (it != this->eventContainers_.end())
246        {
247            COUT(2) << "Warning: Overwriting EventContainer in class " << this->getIdentifier()->getName() << "." << std::endl;
248            delete (it->second);
249        }
250
251        this->eventContainers_[sectionname] = container;
252    }
253
254    EventContainer* BaseObject::getEventContainer(const std::string& sectionname) const
255    {
256        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
257        if (it != this->eventContainers_.end())
258            return ((*it).second);
259        else
260            return 0;
261    }
262
263    void BaseObject::fireEvent()
264    {
265        this->fireEvent(true);
266        this->fireEvent(false);
267    }
268
269    void BaseObject::fireEvent(bool activate)
270    {
271        this->fireEvent(activate, this);
272    }
273
274    void BaseObject::fireEvent(bool activate, BaseObject* originator)
275    {
276        Event event(activate, originator);
277
278        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
279        {
280            event.sectionname_ = it->second;
281            it->first->processEvent(event);
282        }
283    }
284
285    void BaseObject::fireEvent(Event& event)
286    {
287        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
288            it->first->processEvent(event);
289    }
290
291    void BaseObject::processEvent(Event& event)
292    {
293        SetEvent(BaseObject, "activity", setActive, event);
294        SetEvent(BaseObject, "visibility", setVisible, event);
295    }
296
297    void BaseObject::setMainStateName(const std::string& name)
298    {
299        if (this->mainStateName_ != name)
300        {
301            this->mainStateName_ = name;
302            if (this->functorSetMainState_)
303                delete this->functorSetMainState_;
304            if (this->functorGetMainState_)
305                delete this->functorGetMainState_;
306            this->changedMainState();
307            if (!this->functorSetMainState_)
308                COUT(2) << "Warning: \"" << name << "\" is not a valid MainState." << std::endl;
309        }
310    }
311
312    void BaseObject::setMainState(bool state)
313    {
314        if (this->functorSetMainState_)
315            (*this->functorSetMainState_)(state);
316        else
317            COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
318    }
319
320    bool BaseObject::getMainState() const
321    {
322        if (this->functorGetMainState_)
323        {
324            (*this->functorGetMainState_)();
325            return this->functorGetMainState_->getReturnvalue();
326        }
327        else
328        {
329            COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
330            return false;
331        }
332    }
333
334    void BaseObject::changedMainState()
335    {
336        SetMainState(BaseObject, "activity",   setActive,  isActive);
337        SetMainState(BaseObject, "visibility", setVisible, isVisible);
338    }
339}
Note: See TracBrowser for help on using the repository browser.