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