1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef COMMON_SINGLETON_H
24 #define COMMON_SINGLETON_H
25 
26 #include "common/noncopyable.h"
27 
28 namespace Common {
29 
30 /**
31  * @defgroup common_singleton Singleton
32  * @ingroup common
33  *
34  * @brief API for managing singletons.
35  *
36  * @{
37  */
38 
39 /**
40  * Generic template base class for implementing the singleton design pattern.
41  */
42 template<class T>
43 class Singleton : NonCopyable {
44 private:
45 	Singleton<T>(const Singleton<T> &);
46 	Singleton<T> &operator=(const Singleton<T> &);
47 
48 	/**
49 	 * The default object factory used by the template class Singleton.
50 	 * By specialising this template function, one can make a singleton use a
51 	 * custom object factory. For example, to support encapsulation, your
52 	 * singleton class might be pure virtual (or "abstract" in Java terminology),
53 	 * and you specialise makeInstance to return an instance of a subclass.
54 	 */
55 	//template<class T>
56 #if defined(__WINS__)
57 //FIXME verify if __WINS__ needs this still
58 public:
59 #endif
makeInstance()60 	static T *makeInstance() {
61 		return new T();
62 	}
63 
destroyInstance()64 	static void destroyInstance() {
65 		delete _singleton;
66 		_singleton = 0;
67 	}
68 
69 
70 public:
hasInstance()71 	static bool hasInstance() {
72 		return _singleton != 0;
73 	}
74 
instance()75 	static T& instance() {
76 		// TODO: We aren't thread safe. For now we ignore it since the
77 		// only thing using this singleton template is the config manager,
78 		// and that is first instantiated long before any threads.
79 		// TODO: We don't leak, but the destruction order is nevertheless
80 		// semi-random. If we use multiple singletons, the destruction
81 		// order might become an issue. There are various approaches
82 		// to solve that problem, but for now this is sufficient
83 		if (!_singleton)
84 			_singleton = T::makeInstance();
85 		return *_singleton;
86 	}
87 
destroy()88 	static void destroy() {
89 		T::destroyInstance();
90 	}
91 protected:
92 	Singleton<T>()		{ }
93 #ifdef __SYMBIAN32__
~Singleton()94 	virtual ~Singleton()	{ }
95 #else
96 	virtual ~Singleton<T>()	{ }
97 #endif
98 
99 	typedef T	SingletonBaseType;
100 
101 	static T *_singleton;
102 };
103 
104 /**
105  * Note that you need to use this macro from the Common namespace.
106  *
107  * This is because C++ requires initial explicit specialization
108  * to be placed in the same namespace as the template.
109  */
110 #define DECLARE_SINGLETON(T) \
111 	template<> T *Singleton<T>::_singleton = 0
112 
113 /** @} */
114 
115 } // End of namespace Common
116 
117 #endif
118