Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core6/src/libraries/core/class/Identifier.cc @ 9564

Last change on this file since 9564 was 9564, checked in by landauf, 11 years ago

moved static functions from Identifier.cc/h to IdentifierManager.cc/h (still static though)

  • Property svn:eol-style set to native
File size: 13.5 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 Identifier class.
32*/
33
34#include "Identifier.h"
35
36#include <ostream>
37
38#include "util/StringUtils.h"
39#include "core/config/ConfigValueContainer.h"
40#include "core/XMLPort.h"
41#include "core/object/ClassFactory.h"
42
43namespace orxonox
44{
45    // ###############################
46    // ###       Identifier        ###
47    // ###############################
48    /**
49        @brief Constructor: No factory, no object created, new ObjectList and a unique networkID.
50    */
51    Identifier::Identifier()
52        : classID_(IdentifierManager::classIDCounter_s++)
53    {
54        this->objects_ = new ObjectListBase(this);
55
56        this->bCreatedOneObject_ = false;
57        this->bSetName_ = false;
58        this->factory_ = 0;
59        this->bLoadable_ = false;
60
61        this->bHasConfigValues_ = false;
62
63        // Default network ID is the class ID
64        this->networkID_ = this->classID_;
65    }
66
67    /**
68        @brief Destructor: Deletes the list containing the children.
69    */
70    Identifier::~Identifier()
71    {
72        delete this->objects_;
73
74        if (this->factory_)
75            delete this->factory_;
76
77        for (std::map<std::string, ConfigValueContainer*>::iterator it = this->configValues_.begin(); it != this->configValues_.end(); ++it)
78            delete (it->second);
79        for (std::map<std::string, XMLPortParamContainer*>::iterator it = this->xmlportParamContainers_.begin(); it != this->xmlportParamContainers_.end(); ++it)
80            delete (it->second);
81        for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportObjectContainers_.begin(); it != this->xmlportObjectContainers_.end(); ++it)
82            delete (it->second);
83    }
84
85    /**
86        @brief Registers a class, which means that the name and the parents get stored.
87        @param parents A list, containing the Identifiers of all parents of the class
88        @param bRootClass True if the class is either an Interface or the BaseObject itself
89    */
90    void Identifier::initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass)
91    {
92        // Check if at least one object of the given type was created
93        if (!this->bCreatedOneObject_ && IdentifierManager::isCreatingHierarchy())
94        {
95            // If no: We have to store the information and initialize the Identifier
96            orxout(verbose, context::identifier) << "Register Class in ClassIdentifier<" << this->getName() << ">-Singleton -> Initialize Singleton." << endl;
97            if (bRootClass)
98                this->initialize(0); // If a class is derived from two interfaces, the second interface might think it's derived from the first because of the order of constructor-calls. Thats why we set parents to zero in that case.
99            else
100                this->initialize(parents);
101        }
102    }
103
104    /**
105        @brief Initializes the Identifier with a list containing all parents of the class the Identifier belongs to.
106        @param parents A list containing all parents
107    */
108    void Identifier::initialize(std::set<const Identifier*>* parents)
109    {
110        orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << this->name_ << ">-Singleton." << endl;
111        this->bCreatedOneObject_ = true;
112
113        if (parents)
114        {
115            this->parents_ = (*parents);
116            this->directParents_ = (*parents);
117
118            // Iterate through all parents
119            for (std::set<const Identifier*>::iterator it = parents->begin(); it != parents->end(); ++it)
120            {
121                // Tell the parent we're one of it's children
122                (*it)->children_.insert((*it)->children_.end(), this);
123
124                // Erase all parents of our parent from our direct-parent-list
125                for (std::set<const Identifier*>::const_iterator it1 = (*it)->getParents().begin(); it1 != (*it)->getParents().end(); ++it1)
126                {
127                    // Search for the parent's parent in our direct-parent-list
128                    for (std::set<const Identifier*>::iterator it2 = this->directParents_.begin(); it2 != this->directParents_.end(); ++it2)
129                    {
130                        if ((*it1) == (*it2))
131                        {
132                            // We've found a non-direct parent in our list: Erase it
133                            this->directParents_.erase(it2);
134                            break;
135                        }
136                    }
137                }
138            }
139
140            // Now iterate through all direct parents
141            for (std::set<const Identifier*>::iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
142            {
143                // Tell the parent we're one of it's direct children
144                (*it)->directChildren_.insert((*it)->directChildren_.end(), this);
145
146                // Create the super-function dependencies
147                (*it)->createSuperFunctionCaller();
148            }
149        }
150    }
151
152    /**
153        @brief Sets the name of the class.
154    */
155    void Identifier::setName(const std::string& name)
156    {
157        if (!this->bSetName_)
158        {
159            this->name_ = name;
160            this->bSetName_ = true;
161            IdentifierManager::getStringIdentifierMapIntern()[name] = this;
162            IdentifierManager::getLowercaseStringIdentifierMapIntern()[getLowercase(name)] = this;
163            IdentifierManager::getIDIdentifierMapIntern()[this->networkID_] = this;
164        }
165    }
166
167    /**
168        @brief Creates an object of the type the Identifier belongs to.
169        @return The new object
170    */
171    OrxonoxClass* Identifier::fabricate(BaseObject* creator)
172    {
173        if (this->factory_)
174        {
175            return this->factory_->fabricate(creator);
176        }
177        else
178        {
179            orxout(user_error) << "An error occurred in Identifier.cc:" << endl;
180            orxout(user_error) << "Cannot fabricate an object of type '" << this->name_ << "'. Class has no factory." << endl;
181            orxout(user_error) << "Aborting..." << endl;
182            abort();
183            return 0;
184        }
185    }
186
187    /**
188        @brief Sets the network ID to a new value and changes the entry in the ID-Identifier-map.
189    */
190    void Identifier::setNetworkID(uint32_t id)
191    {
192//        Identifier::getIDIdentifierMapIntern().erase(this->networkID_);
193        IdentifierManager::getIDIdentifierMapIntern()[id] = this;
194        this->networkID_ = id;
195    }
196
197    /**
198        @brief Returns true, if the Identifier is at least of the given type.
199        @param identifier The identifier to compare with
200    */
201    bool Identifier::isA(const Identifier* identifier) const
202    {
203        return (identifier == this || (this->parents_.find(identifier) != this->parents_.end()));
204    }
205
206    /**
207        @brief Returns true, if the Identifier is exactly of the given type.
208        @param identifier The identifier to compare with
209    */
210    bool Identifier::isExactlyA(const Identifier* identifier) const
211    {
212        return (identifier == this);
213    }
214
215    /**
216        @brief Returns true, if the assigned identifier is a child of the given identifier.
217        @param identifier The identifier to compare with
218    */
219    bool Identifier::isChildOf(const Identifier* identifier) const
220    {
221        return (this->parents_.find(identifier) != this->parents_.end());
222    }
223
224    /**
225        @brief Returns true, if the assigned identifier is a direct child of the given identifier.
226        @param identifier The identifier to compare with
227    */
228    bool Identifier::isDirectChildOf(const Identifier* identifier) const
229    {
230        return (this->directParents_.find(identifier) != this->directParents_.end());
231    }
232
233    /**
234        @brief Returns true, if the assigned identifier is a parent of the given identifier.
235        @param identifier The identifier to compare with
236    */
237    bool Identifier::isParentOf(const Identifier* identifier) const
238    {
239        return (this->children_.find(identifier) != this->children_.end());
240    }
241
242    /**
243        @brief Returns true, if the assigned identifier is a direct parent of the given identifier.
244        @param identifier The identifier to compare with
245    */
246    bool Identifier::isDirectParentOf(const Identifier* identifier) const
247    {
248        return (this->directChildren_.find(identifier) != this->directChildren_.end());
249    }
250
251    /**
252        @brief Adds the ConfigValueContainer of a variable, given by the string of its name.
253        @param varname The name of the variablee
254        @param container The container
255    */
256    void Identifier::addConfigValueContainer(const std::string& varname, ConfigValueContainer* container)
257    {
258        std::map<std::string, ConfigValueContainer*>::const_iterator it = this->configValues_.find(varname);
259        if (it != this->configValues_.end())
260        {
261            orxout(internal_warning) << "Overwriting config-value with name " << varname << " in class " << this->getName() << '.' << endl;
262            delete (it->second);
263        }
264
265        this->bHasConfigValues_ = true;
266        this->configValues_[varname] = container;
267    }
268
269    /**
270        @brief Returns the ConfigValueContainer of a variable, given by the string of its name.
271        @param varname The name of the variable
272        @return The ConfigValueContainer
273    */
274    ConfigValueContainer* Identifier::getConfigValueContainer(const std::string& varname)
275    {
276        std::map<std::string, ConfigValueContainer*>::const_iterator it = configValues_.find(varname);
277        if (it != configValues_.end())
278            return it->second;
279        else
280            return 0;
281    }
282
283    /**
284        @brief Returns a XMLPortParamContainer that loads a parameter of this class.
285        @param paramname The name of the parameter
286        @return The container
287    */
288    XMLPortParamContainer* Identifier::getXMLPortParamContainer(const std::string& paramname)
289    {
290        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
291        if (it != this->xmlportParamContainers_.end())
292            return it->second;
293        else
294            return 0;
295    }
296
297    /**
298        @brief Adds a new XMLPortParamContainer that loads a parameter of this class.
299        @param paramname The name of the parameter
300        @param container The container
301    */
302    void Identifier::addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container)
303    {
304        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
305        if (it != this->xmlportParamContainers_.end())
306        {
307            orxout(internal_warning) << "Overwriting XMLPortParamContainer in class " << this->getName() << '.' << endl;
308            delete (it->second);
309        }
310
311        this->xmlportParamContainers_[paramname] = container;
312    }
313
314    /**
315        @brief Returns a XMLPortObjectContainer that attaches an object to this class.
316        @param sectionname The name of the section that contains the attachable objects
317        @return The container
318    */
319    XMLPortObjectContainer* Identifier::getXMLPortObjectContainer(const std::string& sectionname)
320    {
321        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
322        if (it != this->xmlportObjectContainers_.end())
323            return it->second;
324        else
325            return 0;
326    }
327
328    /**
329        @brief Adds a new XMLPortObjectContainer that attaches an object to this class.
330        @param sectionname The name of the section that contains the attachable objects
331        @param container The container
332    */
333    void Identifier::addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container)
334    {
335        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
336        if (it != this->xmlportObjectContainers_.end())
337        {
338            orxout(internal_warning) << "Overwriting XMLPortObjectContainer in class " << this->getName() << '.' << endl;
339            delete (it->second);
340        }
341
342        this->xmlportObjectContainers_[sectionname] = container;
343    }
344
345    /**
346        @brief Lists the names of all Identifiers in a std::set<const Identifier*>.
347        @param out The outstream
348        @param list The list (or set) of Identifiers
349        @return The outstream
350    */
351    std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list)
352    {
353        for (std::set<const Identifier*>::const_iterator it = list.begin(); it != list.end(); ++it)
354        {
355            if (it != list.begin())
356                out << ' ';
357            out << (*it)->getName();
358        }
359
360        return out;
361    }
362}
Note: See TracBrowser for help on using the repository browser.