Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added mbool (bool with memory) to fix particlespawner-on-client problem. maybe further changes are needed if a similar problem affects other classes.

if the mbool changes from true to false and back to true within one server tick, the value stays true on the client, but a callback is called.
if you have to switch the state also on the client, a more advanced control logic is needed, but also possible with mbool (you could use 2 mbools, synchronize one and compare with the other).

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