Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core5/src/libraries/core/BaseObject.cc @ 5839

Last change on this file since 5839 was 5839, checked in by scheusso, 15 years ago

Fixed problem with scene and creators
creatorID is now always the objectID of the scene except for the case

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