Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pch/src/core/BaseObject.cc @ 3133

Last change on this file since 3133 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

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