Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy/src/core/BaseObject.cc @ 2118

Last change on this file since 2118 was 2074, checked in by landauf, 16 years ago
  • added EventListener: this class fires an event if another class with a specified name fires
  • added EventDispatcher: this class dispatches events to several other classes (EventTarget) if it gets an event itself
  • added EventTarget: used in EventDispatcher to access all classes with a specified name
  • added XMLNameListener: this listener gets called every time a new class was loaded through XML with a name != "". used to find classes with a given name even if they're not existing at the moment.
  • Property svn:eol-style set to native
File size: 9.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 "XMLPort.h"
39#include "XMLFile.h"
40#include "XMLNameListener.h"
41#include "Template.h"
42#include "util/String.h"
43
44namespace orxonox
45{
46    CreateFactory(BaseObject);
47
48    /**
49        @brief Constructor: Registers the object in the BaseObject-list.
50    */
51    BaseObject::BaseObject(BaseObject* creator) : bInitialized_(false)
52    {
53        RegisterRootObject(BaseObject);
54
55        this->bInitialized_ = true;
56
57        this->bActive_ = true;
58        this->bVisible_ = true;
59        this->oldGametype_ = 0;
60
61        this->setCreator(creator);
62        if (this->creator_)
63        {
64            this->setFile(this->creator_->getFile());
65            this->setNamespace(this->creator_->getNamespace());
66            this->setScene(this->creator_->getScene());
67            this->setGametype(this->creator_->getGametype());
68        }
69        else
70        {
71            this->file_ = 0;
72            this->namespace_ = 0;
73            this->scene_ = 0;
74            this->gametype_ = 0;
75        }
76    }
77
78    /**
79        @brief Destructor
80    */
81    BaseObject::~BaseObject()
82    {
83        for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
84            (*it)->unregisterEventListener(this);
85
86        for (std::map<BaseObject*, std::string>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
87            it->first->removeEvent(this);
88    }
89
90    /**
91        @brief XML loading and saving.
92        @param xmlelement The XML-element
93        @param loading Loading (true) or saving (false)
94        @return The XML-element
95    */
96    void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode)
97    {
98        XMLPortParam(BaseObject, "name", setXMLName, getName, xmlelement, mode);
99        XMLPortParam(BaseObject, "visible", setVisible, isVisible, xmlelement, mode);
100        XMLPortParam(BaseObject, "active", setActive, isActive, xmlelement, mode);
101
102        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
103
104        Element* events = xmlelement.FirstChildElement("events", false);
105
106        if (events)
107        {
108            std::list<std::string> eventnames;
109
110            if (mode == XMLPort::LoadObject)
111            {
112                for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++)
113                    eventnames.push_back(child->Value());
114            }
115            else if (mode == XMLPort::SaveObject)
116            {
117                for (std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->getIdentifier()->getXMLPortEventMapBegin(); it != this->getIdentifier()->getXMLPortEventMapEnd(); ++it)
118                    eventnames.push_back(it->first);
119            }
120
121            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
122            {
123                std::string sectionname = (*it);
124                ExecutorMember<BaseObject>* loadexecutor = createExecutor(createFunctor(&BaseObject::addEvent), std::string( "BaseObject" ) + "::" + "addEvent");
125                ExecutorMember<BaseObject>* saveexecutor = createExecutor(createFunctor(&BaseObject::getEvent), std::string( "BaseObject" ) + "::" + "getEvent");
126                loadexecutor->setDefaultValue(1, sectionname);
127
128                XMLPortClassObjectContainer<BaseObject, BaseObject>* container = 0;
129                container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(this->getIdentifier()->getXMLPortEventContainer(sectionname));
130                if (!container)
131                {
132                    container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(sectionname, this->getIdentifier(), loadexecutor, saveexecutor, false, true);
133                    this->getIdentifier()->addXMLPortEventContainer(sectionname, container);
134                }
135                container->port(this, *events, mode);
136            }
137        }
138    }
139
140    /**
141        @brief Loads the name of the object through XML and calls all XMLNameListener.
142        @param name The name of the object
143    */
144    void BaseObject::setXMLName(const std::string& name)
145    {
146        this->setName(name);
147
148        for (ObjectList<XMLNameListener>::iterator it = ObjectList<XMLNameListener>::begin(); it != ObjectList<XMLNameListener>::end(); ++it)
149            it->loadedNewXMLName(this);
150    }
151
152    /**
153        @brief Returns the levelfile that loaded this object.
154        @return The levelfile
155    */
156    const std::string& BaseObject::getFilename() const
157    {
158        if (this->file_)
159            return this->file_->getFilename();
160        else
161            return BLANKSTRING;
162    }
163
164    /**
165        @brief Adds a Template to the object.
166        @param name The name of the Template
167    */
168    void BaseObject::addTemplate(const std::string& name)
169    {
170        Template* temp = Template::getTemplate(name);
171        if (temp)
172            this->addTemplate(temp);
173        else
174            COUT(1) << "Error: \"" << name << "\" is not a valid Template name (in class: " << this->getIdentifier()->getName() << ", name: " << this->getName() << ")." << std::endl;
175    }
176
177    /**
178        @brief Adds a Template to the object.
179        @param temp The Template
180    */
181    void BaseObject::addTemplate(Template* temp)
182    {
183        this->templates_.insert(temp);
184        temp->applyOn(this);
185    }
186
187    /**
188        @brief Returns the Template with the given index.
189        @param index The index
190    */
191    Template* BaseObject::getTemplate(unsigned int index) const
192    {
193        unsigned int i = 0;
194        for (std::set<Template*>::const_iterator it = this->templates_.begin(); it != this->templates_.end(); ++it)
195        {
196            if (i == index)
197                return (*it);
198            i++;
199        }
200        return 0;
201    }
202
203    void BaseObject::addEvent(BaseObject* event, const std::string& sectionname)
204    {
205        event->registerEventListener(this, sectionname);
206        this->events_.push_back(event);
207    }
208
209    void BaseObject::removeEvent(BaseObject* event)
210    {
211        this->events_.remove(event);
212    }
213
214    BaseObject* BaseObject::getEvent(unsigned int index) const
215    {
216        unsigned int i = 0;
217        for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it)
218        {
219            if (i == index)
220                return (*it);
221            ++i;
222        }
223        return 0;
224    }
225
226    void BaseObject::addEventContainer(const std::string& sectionname, EventContainer* container)
227    {
228        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
229        if (it != this->eventContainers_.end())
230        {
231            COUT(2) << "Warning: Overwriting EventContainer in class " << this->getIdentifier()->getName() << "." << std::endl;
232            delete (it->second);
233        }
234
235        this->eventContainers_[sectionname] = container;
236    }
237
238    EventContainer* BaseObject::getEventContainer(const std::string& sectionname) const
239    {
240        std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname);
241        if (it != this->eventContainers_.end())
242            return ((*it).second);
243        else
244            return 0;
245    }
246
247    void BaseObject::fireEvent()
248    {
249        this->fireEvent(true);
250        this->fireEvent(false);
251    }
252
253    void BaseObject::fireEvent(bool activate)
254    {
255        this->fireEvent(activate, this);
256    }
257
258    void BaseObject::fireEvent(bool activate, BaseObject* originator)
259    {
260        Event event(activate, originator);
261
262        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
263        {
264            event.sectionname_ = it->second;
265            it->first->processEvent(event);
266        }
267    }
268
269    void BaseObject::fireEvent(Event& event)
270    {
271        for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
272            it->first->processEvent(event);
273    }
274
275    void BaseObject::processEvent(Event& event)
276    {
277        SetEvent(BaseObject, "activity", setActive, event);
278        SetEvent(BaseObject, "visibility", setVisible, event);
279    }
280}
Note: See TracBrowser for help on using the repository browser.