Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core3/src/core/Identifier.cc @ 1592

Last change on this file since 1592 was 1592, checked in by landauf, 16 years ago
  • Some small changes in XMLPortParam: It's now possible to add functions of another class. an example is setPosition and getPosition that are directly referred to Ogre::Node. Use XMLPortParamExtern if you need this. It takes the object to call the functions on as an additional argument (in our example: this→node_).
  • Removed loadParams functions and reduced the usage of XMLPortParamLoadOnly in several classes
  • Property svn:eol-style set to native
File size: 14.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 Identifier.cc
31    @brief Implementation of the Identifier class.
32*/
33
34#include "Identifier.h"
35
36#include <ostream>
37
38#include "Factory.h"
39#include "ConsoleCommand.h"
40#include "CommandExecutor.h"
41#include "Iterator.h"
42#include "ObjectList.h"
43#include "OrxonoxClass.h"
44#include "XMLPort.h"
45
46namespace orxonox
47{
48    // ###############################
49    // ###       Identifier        ###
50    // ###############################
51    int Identifier::hierarchyCreatingCounter_s = 0; // Set the static member variable hierarchyCreatingCounter_s to zero (this static member variable is ok: it's used in main(), not before)
52
53    /**
54        @brief Constructor: No factory, no object created, new ObjectList and a unique networkID.
55    */
56    Identifier::Identifier()
57    {
58        this->objects_ = new ObjectListBase(this);
59
60        this->bCreatedOneObject_ = false;
61        this->bSetName_ = false;
62        this->factory_ = 0;
63
64        this->bHasConfigValues_ = false;
65        this->bHasConsoleCommands_ = false;
66
67        this->children_ = new std::set<const Identifier*>();
68        this->directChildren_ = new std::set<const Identifier*>();
69
70        // Use a static variable because the classID gets created before main() and that's why we should avoid static member variables
71        static unsigned int classIDcounter_s = 0;
72        this->classID_ = classIDcounter_s++;
73    }
74
75    /**
76        @brief Destructor: Deletes the list containing the children.
77    */
78    Identifier::~Identifier()
79    {
80        delete this->children_;
81        delete this->directChildren_;
82    }
83
84    /**
85        @brief Returns an identifier by name and adds it if not available
86        @param name The name of the identifier as typeid().name() suggests
87        @param proposal A pointer to a newly created identifier for the case of non existance in the map
88        @return The identifier (unique instance)
89    */
90    Identifier* Identifier::getIdentifierSingleton(const std::string& name, Identifier* proposal)
91    {
92        static std::map<std::string, Identifier*> identifiers;    //!< The map to store all Identifiers.
93        std::map<std::string, Identifier*>::const_iterator it = identifiers.find(name);
94
95        if (it != identifiers.end())
96        {
97            // There is already an entry: return it and delete the proposal
98            delete proposal;
99            return (*it).second;
100        }
101        else
102        {
103            // There is no entry: put the proposal into the map and return it
104            identifiers[name] = proposal;
105            return proposal;
106        }
107    }
108
109    /**
110        @brief Initializes the Identifier with a list containing all parents of the class the Identifier belongs to.
111        @param parents A list containing all parents
112    */
113    void Identifier::initialize(std::set<const Identifier*>* parents)
114    {
115        COUT(4) << "*** Identifier: Initialize " << this->name_ << "-Singleton." << std::endl;
116        this->bCreatedOneObject_ = true;
117
118        if (parents)
119        {
120            this->parents_ = (*parents);
121            this->directParents_ = (*parents);
122
123            // Iterate through all parents
124            for (std::set<const Identifier*>::iterator it = parents->begin(); it != parents->end(); ++it)
125            {
126                // Tell the parent we're one of it's children
127                (*it)->getChildrenIntern().insert((*it)->getChildrenIntern().end(), this);
128
129                // Erase all parents of our parent from our direct-parent-list
130                for (std::set<const Identifier*>::const_iterator it1 = (*it)->getParents().begin(); it1 != (*it)->getParents().end(); ++it1)
131                {
132                    // Search for the parent's parent in our direct-parent-list
133                    for (std::set<const Identifier*>::iterator it2 = this->directParents_.begin(); it2 != this->directParents_.end(); ++it2)
134                    {
135                        if ((*it1) == (*it2))
136                        {
137                            // We've found a non-direct parent in our list: Erase it
138                            this->directParents_.erase(it2);
139                            break;
140                        }
141                    }
142                }
143            }
144
145            // Now iterate through all direct parents
146            for (std::set<const Identifier*>::iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
147            {
148                // Tell the parent we're one of it's direct children
149                (*it)->getDirectChildrenIntern().insert((*it)->getDirectChildrenIntern().end(), this);
150            }
151        }
152    }
153
154    /**
155        @brief Sets the name of the class.
156        @param name The name
157    */
158    void Identifier::setName(const std::string& name)
159    {
160        if (!this->bSetName_)
161        {
162            this->name_ = name;
163            this->bSetName_ = true;
164            Identifier::getIdentifierMapIntern()[name] = this;
165            Identifier::getLowercaseIdentifierMapIntern()[getLowercase(name)] = this;
166        }
167    }
168
169    /**
170        @brief Creates an object of the type the Identifier belongs to.
171        @return The new object
172    */
173    BaseObject* Identifier::fabricate()
174    {
175        if (this->factory_)
176        {
177            return this->factory_->fabricate(); // We have to return a BaseObject, because we don't know the exact type.
178        }
179        else
180        {
181            COUT(1) << "An error occurred in Identifier.cc:" << std::endl;
182            COUT(1) << "Error: Cannot fabricate an object of type '" << this->name_ << "'. Class has no factory." << std::endl;
183            COUT(1) << "Aborting..." << std::endl;
184            abort();
185            return NULL;
186        }
187    }
188
189    /**
190        @brief Sets the network ID to a new value and changes the entry in the Factory.
191        @param id The new network ID
192    */
193    void Identifier::setNetworkID(unsigned int id)
194    {
195        Factory::changeNetworkID(this, this->classID_, id);
196        this->classID_ = id;
197    }
198
199    /**
200        @brief Updates the config-values of all existing objects of this class by calling their setConfigValues() function.
201    */
202    void Identifier::updateConfigValues() const
203    {
204        for (BaseIterator it = this->getObjects()->begin(); it; ++it)
205            (*it)->setConfigValues();
206    }
207
208    /**
209        @brief Tells the container to which Identifier it belongs to.
210    */
211    void Identifier::addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container)
212    {
213        container->setIdentifier(this);
214    }
215
216    /**
217        @brief Returns true, if the Identifier is at least of the given type.
218        @param identifier The identifier to compare with
219    */
220    bool Identifier::isA(const Identifier* identifier) const
221    {
222        return (identifier == this || (this->parents_.find(identifier) != this->parents_.end()));
223    }
224
225    /**
226        @brief Returns true, if the Identifier is exactly of the given type.
227        @param identifier The identifier to compare with
228    */
229    bool Identifier::isExactlyA(const Identifier* identifier) const
230    {
231        return (identifier == this);
232    }
233
234    /**
235        @brief Returns true, if the assigned identifier is a child of the given identifier.
236        @param identifier The identifier to compare with
237    */
238    bool Identifier::isChildOf(const Identifier* identifier) const
239    {
240        return (this->parents_.find(identifier) != this->parents_.end());
241    }
242
243    /**
244        @brief Returns true, if the assigned identifier is a direct child of the given identifier.
245        @param identifier The identifier to compare with
246    */
247    bool Identifier::isDirectChildOf(const Identifier* identifier) const
248    {
249        return (this->directParents_.find(identifier) != this->directParents_.end());
250    }
251
252    /**
253        @brief Returns true, if the assigned identifier is a parent of the given identifier.
254        @param identifier The identifier to compare with
255    */
256    bool Identifier::isParentOf(const Identifier* identifier) const
257    {
258        return (this->children_->find(identifier) != this->children_->end());
259    }
260
261    /**
262        @brief Returns true, if the assigned identifier is a direct parent of the given identifier.
263        @param identifier The identifier to compare with
264    */
265    bool Identifier::isDirectParentOf(const Identifier* identifier) const
266    {
267        return (this->directChildren_->find(identifier) != this->directChildren_->end());
268    }
269
270    /**
271        @brief Returns the map that stores all Identifiers.
272        @return The map
273    */
274    std::map<std::string, Identifier*>& Identifier::getIdentifierMapIntern()
275    {
276        static std::map<std::string, Identifier*> identifierMap;
277        return identifierMap;
278    }
279
280    /**
281        @brief Returns the map that stores all Identifiers.
282        @return The map
283    */
284    std::map<std::string, Identifier*>& Identifier::getLowercaseIdentifierMapIntern()
285    {
286        static std::map<std::string, Identifier*> lowercaseIdentifierMap;
287        return lowercaseIdentifierMap;
288    }
289
290    /**
291        @brief Adds the ConfigValueContainer of a variable, given by the string of its name.
292        @param varname The name of the variablee
293        @param container The container
294    */
295    void Identifier::addConfigValueContainer(const std::string& varname, ConfigValueContainer* container)
296    {
297        std::map<std::string, ConfigValueContainer*>::const_iterator it = this->configValues_.find(varname);
298        if (it != this->configValues_.end())
299        {
300            COUT(2) << "Warning: Overwriting config-value with name " << varname << " in class " << this->getName() << "." << std::endl;
301        }
302
303        this->bHasConfigValues_ = true;
304        this->configValues_[varname] = container;
305        this->configValues_LC_[getLowercase(varname)] = container;
306    }
307
308    /**
309        @brief Returns the ConfigValueContainer of a variable, given by the string of its name.
310        @param varname The name of the variable
311        @return The ConfigValueContainer
312    */
313    ConfigValueContainer* Identifier::getConfigValueContainer(const std::string& varname)
314    {
315        std::map<std::string, ConfigValueContainer*>::const_iterator it = configValues_.find(varname);
316        if (it != configValues_.end())
317            return ((*it).second);
318        else
319            return 0;
320    }
321
322    /**
323        @brief Returns the ConfigValueContainer of a variable, given by the string of its name in lowercase.
324        @param varname The name of the variable in lowercase
325        @return The ConfigValueContainer
326    */
327    ConfigValueContainer* Identifier::getLowercaseConfigValueContainer(const std::string& varname)
328    {
329        std::map<std::string, ConfigValueContainer*>::const_iterator it = configValues_LC_.find(varname);
330        if (it != configValues_LC_.end())
331            return ((*it).second);
332        else
333            return 0;
334    }
335
336    /**
337        @brief Adds a new console command of this class.
338        @param executor The executor of the command
339        @param bCreateShortcut If this is true a shortcut gets created so you don't have to add the classname to access this command
340        @return The executor of the command
341    */
342    ConsoleCommand& Identifier::addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut)
343    {
344        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(command->getName());
345        if (it != this->consoleCommands_.end())
346        {
347            COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << "." << std::endl;
348        }
349
350        this->bHasConsoleCommands_ = true;
351        this->consoleCommands_[command->getName()] = command;
352        this->consoleCommands_LC_[getLowercase(command->getName())] = command;
353
354        if (bCreateShortcut)
355            CommandExecutor::addConsoleCommandShortcut(command);
356
357        return (*command);
358    }
359
360    /**
361        @brief Returns the executor of a console command with given name.
362        @brief name The name of the requested console command
363        @return The executor of the requested console command
364    */
365    ConsoleCommand* Identifier::getConsoleCommand(const std::string& name) const
366    {
367        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(name);
368        if (it != this->consoleCommands_.end())
369            return (*it).second;
370        else
371            return 0;
372    }
373
374    /**
375        @brief Returns the executor of a console command with given name in lowercase.
376        @brief name The name of the requested console command in lowercae
377        @return The executor of the requested console command
378    */
379    ConsoleCommand* Identifier::getLowercaseConsoleCommand(const std::string& name) const
380    {
381        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_LC_.find(name);
382        if (it != this->consoleCommands_LC_.end())
383            return (*it).second;
384        else
385            return 0;
386    }
387
388    /**
389        @brief Lists the names of all Identifiers in a std::set<const Identifier*>.
390        @param out The outstream
391        @param list The list (or set) of Identifiers
392        @return The outstream
393    */
394    std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list)
395    {
396        for (std::set<const Identifier*>::const_iterator it = list.begin(); it != list.end(); ++it)
397            out << (*it)->getName() << " ";
398
399        return out;
400    }
401}
Note: See TracBrowser for help on using the repository browser.