Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/libraries/core/ScopedSingletonManager.h @ 6182

Last change on this file since 6182 was 6182, checked in by rgrieder, 15 years ago

Singleton pointer initialisation should be part of the ManageScopedSingleton macro to ensure the order.

  • Property svn:eol-style set to native
File size: 5.6 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#ifndef __ScopedSingletonManager_H__
30#define __ScopedSingletonManager_H__
31
32#include "CorePrereqs.h"
33
34#include <cassert>
35#include <map>
36#include "util/Exception.h"
37#include "util/Scope.h"
38#include "util/Singleton.h"
39
40#define ManageScopedSingleton(className, scope, allowedToFail) \
41    className* className::singletonPtr_s = NULL; \
42    static ClassScopedSingletonManager<className, scope, allowedToFail> className##ScopedSingletonManager(#className)
43
44namespace orxonox
45{
46    class _CoreExport ScopedSingletonManager
47    {
48        public:
49            ScopedSingletonManager(const std::string& className, ScopeID::Value scope)
50                : className_(className)
51                , scope_(scope)
52            { }
53            virtual ~ScopedSingletonManager() { }
54            static void addManager(ScopedSingletonManager* manager);
55
56            template<ScopeID::Value scope>
57            static void update(const Clock& time)
58            {
59                assert(Scope<scope>::isActive());
60                for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(scope); it != getManagersByScope().upper_bound(scope); ++it)
61                    it->second->update(time);
62            }
63            virtual void update(const Clock& time) = 0;
64
65            static std::map<std::string, ScopedSingletonManager*>& getManagers();
66            typedef std::multimap<ScopeID::Value, ScopedSingletonManager*> ManagerMultiMap;
67            static ManagerMultiMap& getManagersByScope();
68
69        protected:
70            const std::string className_;
71            const ScopeID::Value scope_;
72    };
73
74    template <class T, ScopeID::Value scope, bool allowedToFail>
75    class ClassScopedSingletonManager : public ScopedSingletonManager, public ScopeListener
76    {
77    public:
78        ClassScopedSingletonManager(const std::string& className)
79            : ScopedSingletonManager(className, scope)
80            , ScopeListener(scope)
81            , singletonPtr_(NULL)
82        {
83            ScopedSingletonManager::addManager(this);
84        }
85
86        ~ClassScopedSingletonManager()
87        {
88        }
89
90        //! Called if the Scope of the Singleton gets active (creates the instance)
91        void activated()
92        {
93            assert(singletonPtr_ == NULL);
94            singletonPtr_ = new T();
95        }
96
97        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
98        void deactivated()
99        {
100            assert(singletonPtr_ != NULL);
101            this->destroy(singletonPtr_);
102            singletonPtr_ = NULL;
103        }
104
105        void destroy(OrxonoxClass*)
106        {
107            singletonPtr_->destroy();
108        }
109        void destroy(void*)
110        {
111            delete singletonPtr_;
112        }
113
114        //! Called every frame by the ScopedSingletonManager
115        void update(const Clock& time)
116        {
117            assert(Scope<scope>::isActive());
118            // assuming T inherits Singleton<T>
119            singletonPtr_->updateSingleton(time);
120        }
121
122    private:
123        T* singletonPtr_;
124    };
125
126    template <class T, ScopeID::Value scope>
127    class ClassScopedSingletonManager<T, scope, true> : public ScopedSingletonManager, public ScopeListener
128    {
129    public:
130        ClassScopedSingletonManager(const std::string& className)
131            : ScopedSingletonManager(className, scope)
132            , ScopeListener(scope)
133            , singletonPtr_(NULL)
134        {
135            ScopedSingletonManager::addManager(this);
136        }
137
138        ~ClassScopedSingletonManager()
139        {
140        }
141
142        //! Called if the Scope of the Singleton gets active (creates the instance)
143        void activated()
144        {
145            assert(singletonPtr_ == NULL);
146            try
147                { singletonPtr_ = new T(); }
148            catch (...)
149                { COUT(1) << "Singleton creation failed: " << Exception::handleMessage() << std::endl; }
150        }
151
152        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
153        void deactivated()
154        {
155            if (singletonPtr_ != NULL)
156            {
157                this->destroy(singletonPtr_);
158                singletonPtr_ = NULL;
159            }
160        }
161
162        void destroy(OrxonoxClass* ptr)
163        {
164            singletonPtr_->destroy();
165        }
166        void destroy(void* ptr)
167        {
168            delete singletonPtr_;
169        }
170
171        //! Called every frame by the ScopedSingletonManager
172        void update(const Clock& time)
173        {
174            assert(Scope<scope>::isActive());
175            // assuming T inherits Singleton<T>
176            if (singletonPtr_ != NULL)
177                singletonPtr_->updateSingleton(time);
178        }
179
180    private:
181        T* singletonPtr_;
182    };
183}
184
185#endif /* __ScopedSingletonManager_H__ */
Note: See TracBrowser for help on using the repository browser.