Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixed a bug in the event system
fixed a bug in Trigger and tweaked some features

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