Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

use the generic UpdateListener interface to receive calls to preUpdate() and postUpdate() instead of limiting this functionality to singletons.

  • Property svn:eol-style set to native
File size: 8.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#define ManageScopedSingleton(className, scope, allowedToFail) \
65    className* className::singletonPtr_s = NULL; \
66    static ClassScopedSingletonManager<className, scope, allowedToFail> className##ScopedSingletonManager(#className)
67
68namespace orxonox
69{
70    /**
71        @brief Base class of ClassScopedSingletonManager. Keeps track of all existing ScopedSingletonManagers
72        and stores them in a map, sorted by the scope they belong to.
73    */
74    class _CoreExport ScopedSingletonManager
75    {
76        public:
77            /// Constructor: Initializes all the values
78            ScopedSingletonManager(const std::string& className, ScopeID::Value scope)
79                : className_(className)
80                , scope_(scope)
81            { }
82            virtual ~ScopedSingletonManager() { }
83
84            /// Adds a new instance of ScopedSingletonManager to the map.
85            static void addManager(ScopedSingletonManager* manager);
86
87            static std::map<std::string, ScopedSingletonManager*>& getManagers();
88            typedef std::multimap<ScopeID::Value, ScopedSingletonManager*> ManagerMultiMap;
89
90        protected:
91            const std::string className_;   ///< The name of the scoped singleton class that is managed by this object
92            const ScopeID::Value scope_;    ///< The scope of the singleton that is managed by this object
93    };
94
95    /**
96        @anchor ClassScopedSingletonManager
97
98        @brief Manages a scoped singleton for a given scope.
99        @param T The managed singleton class
100        @param scope The scope in which the singleton @a T should be active
101        @param allowedToFail If true, a specialization of this template is used, that uses try-catch blocks to handle possible failures.
102
103        This class inherits from ScopeListener for the given scope and thus its functions
104        activated() and deactivated() are called whenever the Scope changes its state.
105
106        If the Scope is activated, a new instance of @a T (which must be a singleton) is created.
107        If the Scope is deactivated, the singleton is destroyed.
108
109        @see Singleton
110    */
111    template <class T, ScopeID::Value scope, bool allowedToFail>
112    class ClassScopedSingletonManager : public ScopedSingletonManager, public ScopeListener
113    {
114    public:
115        //! Constructor: Initializes the singleton pointer and passes the scope to ScopedSingletonManager and ScopeListener
116        ClassScopedSingletonManager(const std::string& className)
117            : ScopedSingletonManager(className, scope)
118            , ScopeListener(scope)
119            , singletonPtr_(NULL)
120        {
121            ScopedSingletonManager::addManager(this);
122        }
123
124        ~ClassScopedSingletonManager()
125        {
126        }
127
128        //! Called if the Scope of the Singleton gets active (creates the instance)
129        void activated()
130        {
131            assert(singletonPtr_ == NULL);
132            singletonPtr_ = new T();
133        }
134
135        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
136        void deactivated()
137        {
138            assert(singletonPtr_ != NULL);
139            this->destroy(singletonPtr_);
140            singletonPtr_ = NULL;
141        }
142
143        //! Destroys the singleton instance - overloaded for Destroyable, calls Destroyable::destroy()
144        void destroy(Destroyable*)
145        {
146            singletonPtr_->destroy();
147        }
148        //! Destroys the singleton instance - overloaded for all other pointers, calls delete
149        void destroy(void*)
150        {
151            delete singletonPtr_;
152        }
153
154    private:
155        T* singletonPtr_;   ///< Unique instance of the singleton class @a T
156    };
157
158    /**
159        @brief This class partially spezializes ClassScopedSingletonManager for classes @a T that are allowed to fail.
160        @param T The managed singleton class
161        @param scope The scope in which the singleton @a T should be active
162
163        Because @a T could fail when being created, this partial spezialization of ClassScopedSingletonManager
164        uses a try-catch block to handle exceptions.
165
166        See @ref ClassScopedSingletonManager for a full documentation of the basis template.
167    */
168    template <class T, ScopeID::Value scope>
169    class ClassScopedSingletonManager<T, scope, true> : public ScopedSingletonManager, public ScopeListener
170    {
171    public:
172        //! Constructor: Initializes the singleton pointer and passes the scope to ScopedSingletonManager and ScopeListener
173        ClassScopedSingletonManager(const std::string& className)
174            : ScopedSingletonManager(className, scope)
175            , ScopeListener(scope)
176            , singletonPtr_(NULL)
177        {
178            ScopedSingletonManager::addManager(this);
179        }
180
181        ~ClassScopedSingletonManager()
182        {
183        }
184
185        //! Called if the Scope of the Singleton gets active (creates the instance)
186        void activated()
187        {
188            assert(singletonPtr_ == NULL);
189            try
190                { singletonPtr_ = new T(); }
191            catch (const InitialisationAbortedException& ex)
192                { orxout(internal_error) << ex.getDescription() << endl; }
193            catch (...)
194                { orxout(internal_error) << "Singleton creation failed: " << Exception::handleMessage() << endl; }
195        }
196
197        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
198        void deactivated()
199        {
200            if (singletonPtr_ != NULL)
201            {
202                this->destroy(singletonPtr_);
203                singletonPtr_ = NULL;
204            }
205        }
206
207        //! Destroys the singleton instance - overloaded for Destroyable, calls Destroyable::destroy()
208        void destroy(Destroyable*)
209        {
210            singletonPtr_->destroy();
211        }
212        //! Destroys the singleton instance - overloaded for void*, calls delete
213        void destroy(void*)
214        {
215            delete singletonPtr_;
216        }
217
218    private:
219        T* singletonPtr_;   ///< Unique instance of the singleton class @a T
220    };
221}
222
223#endif /* __ScopedSingletonManager_H__ */
Note: See TracBrowser for help on using the repository browser.