Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/core/Identifier.cc @ 1473

Last change on this file since 1473 was 1446, checked in by landauf, 16 years ago

merged console branch into network branch

after several heavy troubles it compiles, but there is still a bug I couldn't fix: orxonox crashes as soon as one presses a key after opening the console… maybe someone else sees the problem?

File size: 12.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 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 Initializes the Identifier with a list containing all parents of the class the Identifier belongs to.
79        @param parents A list containing all parents
80    */
81    void Identifier::initialize(std::set<const Identifier*>* parents)
82    {
83        COUT(4) << "*** Identifier: Initialize " << this->name_ << "-Singleton." << std::endl;
84        this->bCreatedOneObject_ = true;
85
86        if (parents)
87        {
88            this->parents_ = (*parents);
89            this->directParents_ = (*parents);
90
91            // Iterate through all parents
92            for (std::set<const Identifier*>::iterator it = parents->begin(); it != parents->end(); ++it)
93            {
94                // Tell the parent we're one of it's children
95                (*it)->getChildrenIntern().insert((*it)->getChildrenIntern().end(), this);
96
97                // Erase all parents of our parent from our direct-parent-list
98                for (std::set<const Identifier*>::const_iterator it1 = (*it)->getParents().begin(); it1 != (*it)->getParents().end(); ++it1)
99                {
100                    // Search for the parent's parent in our direct-parent-list
101                    for (std::set<const Identifier*>::iterator it2 = this->directParents_.begin(); it2 != this->directParents_.end(); ++it2)
102                    {
103                        if ((*it1) == (*it2))
104                        {
105                            // We've found a non-direct parent in our list: Erase it
106                            this->directParents_.erase(it2);
107                            break;
108                        }
109                    }
110                }
111            }
112
113            // Now iterate through all direct parents
114            for (std::set<const Identifier*>::iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
115            {
116                // Tell the parent we're one of it's direct children
117                (*it)->getDirectChildrenIntern().insert((*it)->getDirectChildrenIntern().end(), this);
118            }
119        }
120    }
121
122    /**
123        @brief Creates an object of the type the Identifier belongs to.
124        @return The new object
125    */
126    BaseObject* Identifier::fabricate()
127    {
128        if (this->factory_)
129        {
130            return this->factory_->fabricate(); // We have to return a BaseObject, because we don't know the exact type.
131        }
132        else
133        {
134            COUT(1) << "An error occurred in Identifier.cc:" << std::endl;
135            COUT(1) << "Error: Cannot fabricate an object of type '" << this->name_ << "'. Class has no factory." << std::endl;
136            COUT(1) << "Aborting..." << std::endl;
137            abort();
138            return NULL;
139        }
140    }
141
142    /**
143        @brief Sets the network ID to a new value and changes the entry in the Factory.
144        @param id The new network ID
145    */
146    void Identifier::setNetworkID(unsigned int id)
147    {
148        Factory::changeNetworkID(this, this->classID_, id);
149        this->classID_ = id;
150    }
151
152    /**
153        @brief Returns true, if the Identifier is at least of the given type.
154        @param identifier The identifier to compare with
155    */
156    bool Identifier::isA(const Identifier* identifier) const
157    {
158        return (identifier == this || (this->parents_.find(identifier) != this->parents_.end()));
159    }
160
161    /**
162        @brief Returns true, if the Identifier is exactly of the given type.
163        @param identifier The identifier to compare with
164    */
165    bool Identifier::isExactlyA(const Identifier* identifier) const
166    {
167        return (identifier == this);
168    }
169
170    /**
171        @brief Returns true, if the assigned identifier is a child of the given identifier.
172        @param identifier The identifier to compare with
173    */
174    bool Identifier::isChildOf(const Identifier* identifier) const
175    {
176        return (this->parents_.find(identifier) != this->parents_.end());
177    }
178
179    /**
180        @brief Returns true, if the assigned identifier is a direct child of the given identifier.
181        @param identifier The identifier to compare with
182    */
183    bool Identifier::isDirectChildOf(const Identifier* identifier) const
184    {
185        return (this->directParents_.find(identifier) != this->directParents_.end());
186    }
187
188    /**
189        @brief Returns true, if the assigned identifier is a parent of the given identifier.
190        @param identifier The identifier to compare with
191    */
192    bool Identifier::isParentOf(const Identifier* identifier) const
193    {
194        return (this->children_->find(identifier) != this->children_->end());
195    }
196
197    /**
198        @brief Returns true, if the assigned identifier is a direct parent of the given identifier.
199        @param identifier The identifier to compare with
200    */
201    bool Identifier::isDirectParentOf(const Identifier* identifier) const
202    {
203        return (this->directChildren_->find(identifier) != this->directChildren_->end());
204    }
205
206    /**
207        @brief Returns the map that stores all Identifiers.
208        @return The map
209    */
210    std::map<std::string, Identifier*>& Identifier::getIdentifierMapIntern()
211    {
212        static std::map<std::string, Identifier*> identifierMap;
213        return identifierMap;
214    }
215
216    /**
217        @brief Returns the map that stores all Identifiers.
218        @return The map
219    */
220    std::map<std::string, Identifier*>& Identifier::getLowercaseIdentifierMapIntern()
221    {
222        static std::map<std::string, Identifier*> lowercaseIdentifierMap;
223        return lowercaseIdentifierMap;
224    }
225
226    /**
227        @brief Adds the ConfigValueContainer of a variable, given by the string of its name.
228        @param varname The name of the variablee
229        @param container The container
230    */
231    void Identifier::addConfigValueContainer(const std::string& varname, ConfigValueContainer* container)
232    {
233        std::map<std::string, ConfigValueContainer*>::const_iterator it = this->configValues_.find(varname);
234        if (it != this->configValues_.end())
235        {
236            COUT(2) << "Warning: Overwriting config-value with name " << varname << " in class " << this->getName() << "." << std::endl;
237        }
238
239        this->bHasConfigValues_ = true;
240        this->configValues_[varname] = container;
241        this->configValues_LC_[getLowercase(varname)] = container;
242    }
243
244    /**
245        @brief Returns the ConfigValueContainer of a variable, given by the string of its name.
246        @param varname The name of the variable
247        @return The ConfigValueContainer
248    */
249    ConfigValueContainer* Identifier::getConfigValueContainer(const std::string& varname)
250    {
251        std::map<std::string, ConfigValueContainer*>::const_iterator it = configValues_.find(varname);
252        if (it != configValues_.end())
253            return ((*it).second);
254        else
255            return 0;
256    }
257
258    /**
259        @brief Returns the ConfigValueContainer of a variable, given by the string of its name in lowercase.
260        @param varname The name of the variable in lowercase
261        @return The ConfigValueContainer
262    */
263    ConfigValueContainer* Identifier::getLowercaseConfigValueContainer(const std::string& varname)
264    {
265        std::map<std::string, ConfigValueContainer*>::const_iterator it = configValues_LC_.find(varname);
266        if (it != configValues_LC_.end())
267            return ((*it).second);
268        else
269            return 0;
270    }
271
272    /**
273        @brief Adds a new console command of this class.
274        @param executor The executor of the command
275        @param bCreateShortcut If this is true a shortcut gets created so you don't have to add the classname to access this command
276        @return The executor of the command
277    */
278    ConsoleCommand& Identifier::addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut)
279    {
280        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(command->getName());
281        if (it != this->consoleCommands_.end())
282        {
283            COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << "." << std::endl;
284        }
285
286        this->bHasConsoleCommands_ = true;
287        this->consoleCommands_[command->getName()] = command;
288        this->consoleCommands_LC_[getLowercase(command->getName())] = command;
289
290        if (bCreateShortcut)
291            CommandExecutor::addConsoleCommandShortcut(command);
292
293        return (*command);
294    }
295
296    /**
297        @brief Returns the executor of a console command with given name.
298        @brief name The name of the requested console command
299        @return The executor of the requested console command
300    */
301    ConsoleCommand* Identifier::getConsoleCommand(const std::string& name) const
302    {
303        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(name);
304        if (it != this->consoleCommands_.end())
305            return (*it).second;
306        else
307            return 0;
308    }
309
310    /**
311        @brief Returns the executor of a console command with given name in lowercase.
312        @brief name The name of the requested console command in lowercae
313        @return The executor of the requested console command
314    */
315    ConsoleCommand* Identifier::getLowercaseConsoleCommand(const std::string& name) const
316    {
317        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_LC_.find(name);
318        if (it != this->consoleCommands_LC_.end())
319            return (*it).second;
320        else
321            return 0;
322    }
323
324    /**
325        @brief Lists the names of all Identifiers in a std::set<const Identifier*>.
326        @param out The outstream
327        @param list The list (or set) of Identifiers
328        @return The outstream
329    */
330    std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list)
331    {
332        for (std::set<const Identifier*>::const_iterator it = list.begin(); it != list.end(); ++it)
333            out << (*it)->getName() << " ";
334
335        return out;
336    }
337}
Note: See TracBrowser for help on using the repository browser.