Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/core/BaseObject.cc @ 2505

Last change on this file since 2505 was 2485, checked in by landauf, 15 years ago

Merged objecthierarchy2 into presentation branch

Couln't merge 2 lines in Gamestate.cc and a whole block of code in GSDedicated.cc (it seems like oli implemented in both branches something like a network-tick-limiter but with different approaches)

Not yet tested in network mode and with bots
The SpaceShips movement is also not yet fully adopted to the new physics (see Engine class)

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