Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/util/ScopedSingletonManager.h @ 7773

Last change on this file since 7773 was 7207, checked in by landauf, 14 years ago

moved ScopedSingletonManager to util

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