Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands/src/libraries/core/ScopedSingletonManager.h @ 6372

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

Added preUpdate and postUpdate methods for all classes inheriting Singleton. Replaced update() with preUpdate except for the GraphicsManager (postUpdate).
However this does not apply to the Client and Server singletons in the network library. We should think about putting them in a scope as well.

  • Property svn:eol-style set to native
File size: 6.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 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 (...)
165                { COUT(1) << "Singleton creation failed: " << Exception::handleMessage() << std::endl; }
166        }
167
168        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
169        void deactivated()
170        {
171            if (singletonPtr_ != NULL)
172            {
173                this->destroy(singletonPtr_);
174                singletonPtr_ = NULL;
175            }
176        }
177
178        void destroy(OrxonoxClass* ptr)
179        {
180            singletonPtr_->destroy();
181        }
182        void destroy(void* ptr)
183        {
184            delete singletonPtr_;
185        }
186
187        //! Called every frame by the ScopedSingletonManager
188        void preUpdate(const Clock& time)
189        {
190            assert(Scope<scope>::isActive());
191            // assuming T inherits Singleton<T>
192            if (singletonPtr_ != NULL)
193                singletonPtr_->preUpdateSingleton(time);
194        }
195
196        //! Called every frame by the ScopedSingletonManager
197        void postUpdate(const Clock& time)
198        {
199            assert(Scope<scope>::isActive());
200            // assuming T inherits Singleton<T>
201            if (singletonPtr_ != NULL)
202                singletonPtr_->postUpdateSingleton(time);
203        }
204
205    private:
206        T* singletonPtr_;
207    };
208}
209
210#endif /* __ScopedSingletonManager_H__ */
Note: See TracBrowser for help on using the repository browser.