Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Added config value to disable sound entirely.
Also added InitialisationAbortedException to be used by singletons in order not to be constructed, but nicely telling the user (only for those singletons who are allowed to fail!).

  • Property svn:eol-style set to native
File size: 6.7 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 preUpdate(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->preUpdate(time);
62            }
63            virtual void preUpdate(const Clock& time) = 0;
64            template<ScopeID::Value scope>
65            static void postUpdate(const Clock& time)
66            {
67                assert(Scope<scope>::isActive());
68                for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(scope); it != getManagersByScope().upper_bound(scope); ++it)
69                    it->second->postUpdate(time);
70            }
71            virtual void postUpdate(const Clock& time) = 0;
72
73            static std::map<std::string, ScopedSingletonManager*>& getManagers();
74            typedef std::multimap<ScopeID::Value, ScopedSingletonManager*> ManagerMultiMap;
75            static ManagerMultiMap& getManagersByScope();
76
77        protected:
78            const std::string className_;
79            const ScopeID::Value scope_;
80    };
81
82    template <class T, ScopeID::Value scope, bool allowedToFail>
83    class ClassScopedSingletonManager : public ScopedSingletonManager, public ScopeListener
84    {
85    public:
86        ClassScopedSingletonManager(const std::string& className)
87            : ScopedSingletonManager(className, scope)
88            , ScopeListener(scope)
89            , singletonPtr_(NULL)
90        {
91            ScopedSingletonManager::addManager(this);
92        }
93
94        ~ClassScopedSingletonManager()
95        {
96        }
97
98        //! Called if the Scope of the Singleton gets active (creates the instance)
99        void activated()
100        {
101            assert(singletonPtr_ == NULL);
102            singletonPtr_ = new T();
103        }
104
105        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
106        void deactivated()
107        {
108            assert(singletonPtr_ != NULL);
109            this->destroy(singletonPtr_);
110            singletonPtr_ = NULL;
111        }
112
113        void destroy(OrxonoxClass*)
114        {
115            singletonPtr_->destroy();
116        }
117        void destroy(void*)
118        {
119            delete singletonPtr_;
120        }
121
122        //! Called every frame by the ScopedSingletonManager
123        void preUpdate(const Clock& time)
124        {
125            assert(Scope<scope>::isActive());
126            // assuming T inherits Singleton<T>
127            singletonPtr_->preUpdateSingleton(time);
128        }
129
130        //! Called every frame by the ScopedSingletonManager
131        void postUpdate(const Clock& time)
132        {
133            assert(Scope<scope>::isActive());
134            // assuming T inherits Singleton<T>
135            singletonPtr_->postUpdateSingleton(time);
136        }
137
138    private:
139        T* singletonPtr_;
140    };
141
142    template <class T, ScopeID::Value scope>
143    class ClassScopedSingletonManager<T, scope, true> : public ScopedSingletonManager, public ScopeListener
144    {
145    public:
146        ClassScopedSingletonManager(const std::string& className)
147            : ScopedSingletonManager(className, scope)
148            , ScopeListener(scope)
149            , singletonPtr_(NULL)
150        {
151            ScopedSingletonManager::addManager(this);
152        }
153
154        ~ClassScopedSingletonManager()
155        {
156        }
157
158        //! Called if the Scope of the Singleton gets active (creates the instance)
159        void activated()
160        {
161            assert(singletonPtr_ == NULL);
162            try
163                { singletonPtr_ = new T(); }
164            catch (const InitialisationAbortedException& ex)
165                { COUT(3) << ex.getDescription() << std::endl; }
166            catch (...)
167                { COUT(1) << "Singleton creation failed: " << Exception::handleMessage() << std::endl; }
168        }
169
170        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
171        void deactivated()
172        {
173            if (singletonPtr_ != NULL)
174            {
175                this->destroy(singletonPtr_);
176                singletonPtr_ = NULL;
177            }
178        }
179
180        void destroy(OrxonoxClass* ptr)
181        {
182            singletonPtr_->destroy();
183        }
184        void destroy(void* ptr)
185        {
186            delete singletonPtr_;
187        }
188
189        //! Called every frame by the ScopedSingletonManager
190        void preUpdate(const Clock& time)
191        {
192            assert(Scope<scope>::isActive());
193            // assuming T inherits Singleton<T>
194            if (singletonPtr_ != NULL)
195                singletonPtr_->preUpdateSingleton(time);
196        }
197
198        //! Called every frame by the ScopedSingletonManager
199        void postUpdate(const Clock& time)
200        {
201            assert(Scope<scope>::isActive());
202            // assuming T inherits Singleton<T>
203            if (singletonPtr_ != NULL)
204                singletonPtr_->postUpdateSingleton(time);
205        }
206
207    private:
208        T* singletonPtr_;
209    };
210}
211
212#endif /* __ScopedSingletonManager_H__ */
Note: See TracBrowser for help on using the repository browser.