Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/core/Identifier.cc @ 1646

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