Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/core/singleton/ScopedSingletonManager.h @ 10418

Last change on this file since 10418 was 10418, checked in by landauf, 9 years ago

improved documentation

  • Property svn:eol-style set to native
File size: 9.1 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 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @ingroup SingletonScope
32    @brief Definition of orxonox::ScopedSingletonManager, orxonox::ClassScopedSingletonManager, and the ManageScopedSingleton macro.
33
34    ScopedSingletonManager is used to create and destroy Singletons that belong to
35    a given Scope. For each one of these singletons, the macro ManageScopedSingleton()
36    has to be called to register the singleton with orxonox::ScopedSingletonManager.
37
38    See @ref SingletonExample "this code" for an example.
39
40    @see orxonox::Singleton
41    @see orxonox::Scope
42*/
43
44#ifndef __ScopedSingletonManager_H__
45#define __ScopedSingletonManager_H__
46
47#include "core/CorePrereqs.h"
48
49#include <cassert>
50#include <map>
51#include "util/Exception.h"
52#include "util/Singleton.h"
53#include "Scope.h"
54
55/**
56    @brief Registers an orxonox::Singleton with orxonox::ScopedSingletonManager.
57    @param className The name of the singleton class
58    @param scope The scope in which the singleton should exist
59    @param allowedToFail If true, the singleton is allowed to fail and thus a try-catch block is used when creating the singleton.
60
61    If this macro is called for a singleton, it is registered with ScopedSingletonManager
62    and will thus be created if its scope becomes active and destroyed if is deactivated.
63
64
65    Usually a singleton gets created automatically when it is first used, but it will never
66    be destroyed (unless the singleton explicitly deletes itself). To allow controlled
67    construction and destruction, the singleton can be put within a virtual scope. This is
68    done by registering the singleton class with orxonox::ScopedSingletonManager. To
69    do so, the ManageScopedSingleton() macro has to be called:
70
71    @code
72    ManageScopedSingleton(TestSingleton, ScopeID::Graphics, false); // muste be called in a source (*.cc) file
73    @endcode
74
75    @b Important: If you call ManageScopedSingleton(), you don't have to initialize singletonPtr_s anymore,
76    because that's already done by the macro.
77
78    Now the singleton TestSingleton gets automatically created if the scope Graphics becomes
79    active and also gets destroyed if the scope is deactivated.
80
81    Note that not all singletons must register with a scope, but it's recommended.
82
83*/
84#define ManageScopedSingleton(className, scope, allowedToFail) \
85    className* className::singletonPtr_s = NULL; \
86    static ClassScopedSingletonManager<className, scope, allowedToFail> className##ScopedSingletonManager(#className)
87
88namespace orxonox
89{
90    /**
91        @brief Base class of ClassScopedSingletonManager. Keeps track of all existing ScopedSingletonManagers
92        and stores them in a map, sorted by the scope they belong to.
93    */
94    class _CoreExport ScopedSingletonManager
95    {
96        public:
97            /// Constructor: Initializes all the values
98            ScopedSingletonManager(const std::string& className, ScopeID::Value scope)
99                : className_(className)
100                , scope_(scope)
101            { }
102            virtual ~ScopedSingletonManager() { }
103
104            /// Adds a new instance of ScopedSingletonManager to the map.
105            static void addManager(ScopedSingletonManager* manager);
106
107            static std::map<std::string, ScopedSingletonManager*>& getManagers();
108            typedef std::multimap<ScopeID::Value, ScopedSingletonManager*> ManagerMultiMap;
109
110        protected:
111            const std::string className_;   ///< The name of the scoped singleton class that is managed by this object
112            const ScopeID::Value scope_;    ///< The scope of the singleton that is managed by this object
113    };
114
115    /**
116        @anchor ClassScopedSingletonManager
117
118        @brief Manages a scoped singleton for a given scope.
119        @param T The managed singleton class
120        @param scope The scope in which the singleton @a T should be active
121        @param allowedToFail If true, a specialization of this template is used, that uses try-catch blocks to handle possible failures.
122
123        This class inherits from ScopeListener for the given scope and thus its functions
124        activated() and deactivated() are called whenever the Scope changes its state.
125
126        If the Scope is activated, a new instance of @a T (which must be a singleton) is created.
127        If the Scope is deactivated, the singleton is destroyed.
128
129        @see Singleton
130    */
131    template <class T, ScopeID::Value scope, bool allowedToFail>
132    class ClassScopedSingletonManager : public ScopedSingletonManager, public ScopeListener
133    {
134    public:
135        //! Constructor: Initializes the singleton pointer and passes the scope to ScopedSingletonManager and ScopeListener
136        ClassScopedSingletonManager(const std::string& className)
137            : ScopedSingletonManager(className, scope)
138            , ScopeListener(scope)
139            , singletonPtr_(NULL)
140        {
141            ScopedSingletonManager::addManager(this);
142        }
143
144        ~ClassScopedSingletonManager()
145        {
146        }
147
148        //! Called if the Scope of the Singleton gets active (creates the instance)
149        void activated()
150        {
151            assert(singletonPtr_ == NULL);
152            singletonPtr_ = new T();
153        }
154
155        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
156        void deactivated()
157        {
158            assert(singletonPtr_ != NULL);
159            this->destroy(singletonPtr_);
160            singletonPtr_ = NULL;
161        }
162
163        //! Destroys the singleton instance - overloaded for Destroyable, calls Destroyable::destroy()
164        void destroy(Destroyable*)
165        {
166            singletonPtr_->destroy();
167        }
168        //! Destroys the singleton instance - overloaded for all other pointers, calls delete
169        void destroy(void*)
170        {
171            delete singletonPtr_;
172        }
173
174    private:
175        T* singletonPtr_;   ///< Unique instance of the singleton class @a T
176    };
177
178    /**
179        @brief This class partially spezializes ClassScopedSingletonManager for classes @a T that are allowed to fail.
180        @param T The managed singleton class
181        @param scope The scope in which the singleton @a T should be active
182
183        Because @a T could fail when being created, this partial spezialization of ClassScopedSingletonManager
184        uses a try-catch block to handle exceptions.
185
186        See @ref ClassScopedSingletonManager for a full documentation of the basis template.
187    */
188    template <class T, ScopeID::Value scope>
189    class ClassScopedSingletonManager<T, scope, true> : public ScopedSingletonManager, public ScopeListener
190    {
191    public:
192        //! Constructor: Initializes the singleton pointer and passes the scope to ScopedSingletonManager and ScopeListener
193        ClassScopedSingletonManager(const std::string& className)
194            : ScopedSingletonManager(className, scope)
195            , ScopeListener(scope)
196            , singletonPtr_(NULL)
197        {
198            ScopedSingletonManager::addManager(this);
199        }
200
201        ~ClassScopedSingletonManager()
202        {
203        }
204
205        //! Called if the Scope of the Singleton gets active (creates the instance)
206        void activated()
207        {
208            assert(singletonPtr_ == NULL);
209            try
210                { singletonPtr_ = new T(); }
211            catch (const InitialisationAbortedException& ex)
212                { orxout(internal_error) << ex.getDescription() << endl; }
213            catch (...)
214                { orxout(internal_error) << "Singleton creation failed: " << Exception::handleMessage() << endl; }
215        }
216
217        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
218        void deactivated()
219        {
220            if (singletonPtr_ != NULL)
221            {
222                this->destroy(singletonPtr_);
223                singletonPtr_ = NULL;
224            }
225        }
226
227        //! Destroys the singleton instance - overloaded for Destroyable, calls Destroyable::destroy()
228        void destroy(Destroyable*)
229        {
230            singletonPtr_->destroy();
231        }
232        //! Destroys the singleton instance - overloaded for void*, calls delete
233        void destroy(void*)
234        {
235            delete singletonPtr_;
236        }
237
238    private:
239        T* singletonPtr_;   ///< Unique instance of the singleton class @a T
240    };
241}
242
243#endif /* __ScopedSingletonManager_H__ */
Note: See TracBrowser for help on using the repository browser.