Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/BaseObject.cc @ 2663

Last change on this file since 2663 was 2662, checked in by rgrieder, 16 years ago

Merged presentation branch back to trunk.

  • 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.