Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/script/src/orxonox/core/ClassManager.h @ 938

Last change on this file since 938 was 871, checked in by landauf, 17 years ago

merged core branch to trunk

File size: 5.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 */
27
28/**
29    @file ClassManager.h
30    @brief Definition and Implementation of the ClassManager template.
31
32    The ClassManager is a helper-class for ClassIdentifier. Because ClassIdentifiers must
33    be unique, they are created through the IdentifierDistributor-class to assure the
34    uniqueness of the ClassIdentifier. But accessing Identifiers through IdentifierDistributor
35    is slow, because it uses strings and a map. Thats why we use the ClassManager-template: It's
36    a singleton like ClassIdentifier, but it doesn't hurt if there are multiple instances in
37    different libraries, because they all store the same pointer to the unique ClassIdentifier
38    which they've retrieved through IdentifierDistributor.
39*/
40
41#ifndef _ClassManager_H__
42#define _ClassManager_H__
43
44#include <string>
45
46#include "Identifier.h"
47#include "IdentifierDistributor.h"
48
49#include "CorePrereqs.h"
50
51namespace orxonox
52{
53    //! ClassManager is a helper class to allow faster access on the ClassIdentifiers.
54    /**
55        Because accessing the IdentifierDistributor is slow, the ClassManager accesses it once
56        and stores the result in a member-variable. IdentifierDistributor assures the uniqueness
57        of the ClassIdentifier, even if there are multiple instances of the ClassManager-template
58        in different libraries.
59    */
60    template <class T>
61    class ClassManager
62    {
63        public:
64            static ClassManager<T>* getSingleton();
65            static ClassIdentifier<T>* getIdentifier();
66            static const std::string& getName();
67
68        private:
69            ClassManager();
70            ClassManager(const ClassIdentifier<T>& identifier) {}    // don't copy
71            ~ClassManager() {}                                       // don't delete
72
73            bool bInitialized_;                 //!< This is false until the ClassIdentifier gets assigned
74            ClassIdentifier<T>* identifier_;    //!< The unique ClassIdentifier for the class T
75    };
76
77    /**
78        @brief Constructor: Marks the ClassManager as uninitialized.
79    */
80    template <class T>
81    ClassManager<T>::ClassManager()
82    {
83        this->bInitialized_ = false;
84    }
85
86    /**
87        @brief Returns the one and only instance of this class for the template parameter T.
88        @return The instance
89    */
90    template <class T>
91    ClassManager<T>* ClassManager<T>::getSingleton()
92    {
93        static ClassManager<T> theOneAndOnlyInstance = ClassManager<T>();
94        return &theOneAndOnlyInstance;
95    }
96
97    /**
98        @brief Creates the only instance of this class for the template class T and retrieves a unique Identifier for the given name.
99        @return The unique Identifier
100    */
101    template <class T>
102    ClassIdentifier<T>* ClassManager<T>::getIdentifier()
103    {
104        // Check if the ClassManager is already initialized
105        if (!ClassManager<T>::getSingleton()->bInitialized_)
106        {
107            // Get the name of the class
108            std::string name = typeid(T).name();
109
110            // It's not -> retrieve the ClassIdentifier through IdentifierDistributor
111            COUT(4) << "*** ClassManager: Request Identifier Singleton for " << name << "." << std::endl;
112
113            // First create a ClassIdentifier in case there's no instance existing yet
114            ClassIdentifier<T>* temp = new ClassIdentifier<T>();
115
116            // Ask the IdentifierDistributor for the unique ClassIdentifier
117            ClassManager<T>::getSingleton()->identifier_ = (ClassIdentifier<T>*)IdentifierDistributor::getIdentifier(name, temp);
118
119            // If the retrieved Identifier differs from our proposal, we don't need the proposal any more
120            if (temp != ClassManager<T>::getSingleton()->identifier_)
121            {
122                COUT(4) << "*** ClassManager: Requested Identifier for " << name << " was already existing and got assigned." << std::endl;
123
124                // Delete the unnecessary proposal
125                delete temp;
126            }
127            else
128            {
129                COUT(4) << "*** ClassManager: Requested Identifier for " << name << " was not yet existing and got created." << std::endl;
130            }
131
132            ClassManager<T>::getSingleton()->bInitialized_ = true;
133        }
134
135        // Finally return the unique ClassIdentifier
136        return ClassManager<T>::getSingleton()->identifier_;
137    }
138
139    /**
140        @brief Returns the name of the class the ClassManager belongs to.
141        @return The name
142    */
143    template <class T>
144    const std::string& ClassManager<T>::getName()
145    {
146        static std::string unknownClassName = std::string("unknown");
147
148        if (ClassManager<T>::getSingleton()->bInitialized_)
149            return ClassManager<T>::getSingleton()->identifier_->getName();
150        else
151            return unknownClassName;
152    }
153}
154
155#endif /* _ClassManager_H__ */
Note: See TracBrowser for help on using the repository browser.