Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/core/BaseObject.cc @ 2173

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