| [23b547] | 1 | /* | 
|---|
|  | 2 | * Singleton.hpp | 
|---|
|  | 3 | * | 
|---|
|  | 4 | *  Created on: Mar 10, 2010 | 
|---|
|  | 5 | *      Author: crueger | 
|---|
|  | 6 | */ | 
|---|
|  | 7 |  | 
|---|
|  | 8 | #ifndef SINGLETON_HPP_ | 
|---|
|  | 9 | #define SINGLETON_HPP_ | 
|---|
|  | 10 |  | 
|---|
| [d7940e] | 11 | #include <cassert> | 
|---|
|  | 12 | #include <boost/thread.hpp> | 
|---|
| [23b547] | 13 |  | 
|---|
|  | 14 | #include "defs.hpp" | 
|---|
|  | 15 |  | 
|---|
|  | 16 | /** | 
|---|
|  | 17 | * This template produces the generic singleton pattern using the CRTP idiom. | 
|---|
| [c3dbe0] | 18 | * | 
|---|
|  | 19 | * <h1> Singleton Howto </h1> | 
|---|
|  | 20 | * <h2> Introduction </h2> | 
|---|
|  | 21 | * | 
|---|
|  | 22 | * A Singleton is a class of which there can only be a single Object in the programm. It is | 
|---|
|  | 23 | * described as an design-pattern in Gof:96 (the famous design-pattern book). In the | 
|---|
|  | 24 | * molecuilder there are so far several Singletons serving a wide range of purposes: | 
|---|
|  | 25 | * | 
|---|
|  | 26 | * - the World, which handles all atoms, molecules and bonds | 
|---|
|  | 27 | * - the ActionRegistry, which stores all created actions by name for later use | 
|---|
|  | 28 | * - the UIFactory, which is an AbstractFactory (another design-pattern from Gof:96) and | 
|---|
|  | 29 | *   handles all creation of gui elements to ensure a single type throughout the programm | 
|---|
|  | 30 | * - the logger and errorLogger classes, that can be used to output messages on the screen | 
|---|
|  | 31 | *   depending on certain conditions | 
|---|
|  | 32 | * | 
|---|
|  | 33 | * Because those classes can only be instantiated once you cannot simply call <code>new World()</code> | 
|---|
|  | 34 | * or <code>delete</code> on them. Rather they have to be constructed and accessed using the singleton | 
|---|
|  | 35 | * mechanism. This mechanism consists of four static functions (and a fifth that is used internally, | 
|---|
|  | 36 | * but we will get to that later). These functions are: | 
|---|
|  | 37 | * | 
|---|
|  | 38 | * - <code>Singleton& Singleton::getInstance()</code> : returns the instance of the singleton as | 
|---|
|  | 39 | *    a reference | 
|---|
|  | 40 | * - <code>Singleton* Singleton::getPointer()</code> : returns the instance of the singleton as a | 
|---|
|  | 41 | *    pointer | 
|---|
|  | 42 | * - <code>void Singleton::purgeInstance()</code> : destroys the single Instance of the singleton | 
|---|
|  | 43 | * - <code>Singleton& Singleton::resetInstance()</code> : resets the Singleton, i.e. destroys the | 
|---|
|  | 44 | *    old instance and creates a new one | 
|---|
|  | 45 | * | 
|---|
|  | 46 | * If you need the instance of the singleton it is usually fine just to use one off the accessor | 
|---|
|  | 47 | * functions (i.e. <code>getInstance()</code> or <code>getPointer()</code>. Any creation of the | 
|---|
|  | 48 | * Singleton is then handled by these functions, so that the same object will be returned whenever | 
|---|
|  | 49 | * one of these functions is called. This easy process is true for most singletons you will need | 
|---|
|  | 50 | * to use. The only special singleton is the UIFactory. | 
|---|
|  | 51 | * | 
|---|
|  | 52 | * <h3>Special functions of the UIFactory</h3> | 
|---|
|  | 53 | * | 
|---|
|  | 54 | * If you simply call the <code>getInstance()</code> method of the UIFactory class the program | 
|---|
|  | 55 | * will crash. This happens, because the UIFactory in itself is abstract and needs to know what | 
|---|
|  | 56 | * kind of user interface it should produce later on. You need to tell the class the type of UI | 
|---|
|  | 57 | * using the void <code>UIFactory::makeUserInterface(InterfaceTypes type)</code> method. This will | 
|---|
|  | 58 | * also take care of creating the sole instance, so that the accessor functions will work afterwards. | 
|---|
|  | 59 | * What this also means is, that you cannot <code>reset()</code> the UIFactory, because at that | 
|---|
|  | 60 | * point it wont know anymore what to construct. A sequence of <code>UIFactory::purgeInstance()</code>, | 
|---|
|  | 61 | * <code>UIFactory::makeUserInterface()</code> and <code>UIFactory::getInstance()</code> will work | 
|---|
|  | 62 | * though. | 
|---|
|  | 63 | * | 
|---|
|  | 64 | * In order to make life easier and propagate changes to the singleton mechanism to all those | 
|---|
|  | 65 | * classes, there is a simple framework class that can be used to make any other class a | 
|---|
|  | 66 | * singleton through inheritance. This class can be found in the Pattern directory. | 
|---|
|  | 67 | * | 
|---|
|  | 68 | * <h2>How to make a class Singleton</h2> | 
|---|
|  | 69 | * | 
|---|
|  | 70 | * Most of the time you will only need singletons that don't require additional | 
|---|
|  | 71 | * information for creation. So I will cover the basic case for constructing singletons | 
|---|
|  | 72 | * first and then explain what has to be changed to make it accept special parameters. | 
|---|
|  | 73 | * Singletons are created by inheriting from the <code>Singleton<class T></code> template | 
|---|
|  | 74 | * using the Curiously recurring template pattern (CRTP). What this means is, that the | 
|---|
|  | 75 | * class they inherit from carries the inheriting class as a template parameter. For example | 
|---|
|  | 76 | * <code>class MySingletonExaple : public Singleton<MySingletonExample>{...}</code>. If you | 
|---|
|  | 77 | * want to know more about this idiom have a look at the | 
|---|
|  | 78 | * <A HREF="http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern">wikipedia | 
|---|
|  | 79 | * page for this idiom</A>, but don't worry if you don't quite get how this works for now, for | 
|---|
|  | 80 | * the use of the singleton framework this is not important. | 
|---|
|  | 81 | * | 
|---|
|  | 82 | * If you want to make a class a singleton you can use the following sequence of steps. | 
|---|
|  | 83 | * | 
|---|
|  | 84 | * - Inherit from the singleton pattern using the CRTP as above:<br> | 
|---|
|  | 85 | *   @code | 
|---|
|  | 86 | *     class MySingletonExaple : public Singleton<MySingletonExample>{ ...} | 
|---|
|  | 87 | *   @endcode | 
|---|
|  | 88 | * - Make constructor and destructor private to avoid creation or destruction from | 
|---|
|  | 89 | *   outside the class:<br> | 
|---|
|  | 90 | *    @code | 
|---|
|  | 91 | *      class MySingletonExaple : public Singleton<MySingletonExample>{ | 
|---|
|  | 92 | *        private: | 
|---|
|  | 93 | *          MySingletonExample(); | 
|---|
|  | 94 | *          ~MySingletonExample(); | 
|---|
|  | 95 | *      ...} | 
|---|
|  | 96 | *    @endcode | 
|---|
|  | 97 | * - give the inherited class access to the class internals using a friend declaration:<br> | 
|---|
|  | 98 | *    @code | 
|---|
|  | 99 | *       class MySingletonExaple : public Singleton<MySingletonExample>{ | 
|---|
|  | 100 | *         friend class Singleton<MySingletonExample>; // don't forget the template parameters here | 
|---|
|  | 101 | *         private: | 
|---|
|  | 102 | *           MySingletonExample(); | 
|---|
|  | 103 | *           ~MySingletonExample(); | 
|---|
|  | 104 | *       ...} | 
|---|
|  | 105 | *    @endcode | 
|---|
|  | 106 | * | 
|---|
|  | 107 | * - include the file "Patterns/Singleton_impl.hpp" that carries the implementation details of | 
|---|
|  | 108 | *   the singleton functions in your implementation file of the class. | 
|---|
|  | 109 | * - make the compiler construct the template instantiations. For this you can use the defined | 
|---|
|  | 110 | *   keyword <code>CONSTRUCT_SINGLETON(name)</code> at any toplevel point in the implementation | 
|---|
|  | 111 | *   file:<br> | 
|---|
|  | 112 | *    @code | 
|---|
|  | 113 | *       void MySingletonExample::foo(){...} | 
|---|
|  | 114 | *       void MySingletonExample::bar(){...} | 
|---|
|  | 115 | *       CONSTRUCT_SINGLETON(MySingletonExample) // no ; after this | 
|---|
|  | 116 | *     @endcode | 
|---|
|  | 117 | * | 
|---|
|  | 118 | * <h3>Singleton with initialization parameters</h3> | 
|---|
|  | 119 | * | 
|---|
|  | 120 | * Sometimes it is necessary for a singleton to be passed some initilization parameters. For | 
|---|
|  | 121 | * example the UIFactory mentioned above needs to know what kind of user interface it has to | 
|---|
|  | 122 | * produce. Making a singleton that takes initialization parameters is only sligtly different | 
|---|
|  | 123 | * from the steps lined out above. Here are all the differences: | 
|---|
|  | 124 | * | 
|---|
|  | 125 | * - pass an extra <code>false</code> to the template to deactivate the standard instantiation | 
|---|
|  | 126 | *   mechanism | 
|---|
|  | 127 | * - write a method that handles the special parameters and instantiation. In this method you | 
|---|
|  | 128 | *   can use the <code>setInstance(T*)</code> method inherited from the singleton pattern to set | 
|---|
|  | 129 | *   the created instance. The <code>setInstance()</code> method will only work when the | 
|---|
|  | 130 | *   <code>false<code> template parameter has been set and produce errors otherwise. | 
|---|
|  | 131 | * | 
|---|
| [23b547] | 132 | */ | 
|---|
|  | 133 | template <class T, bool _may_create=true> | 
|---|
|  | 134 | class Singleton | 
|---|
|  | 135 | { | 
|---|
|  | 136 | private: | 
|---|
| [c3dbe0] | 137 | /** | 
|---|
|  | 138 | * simple auto_ptr that is used by Singleton template | 
|---|
|  | 139 | * | 
|---|
|  | 140 | * This ptr_t allows destruction of the object using a private destructor, | 
|---|
|  | 141 | * when only the Singleton pattern is friend with the class | 
|---|
|  | 142 | * | 
|---|
|  | 143 | * All methods have similar sematics to auto_ptr | 
|---|
|  | 144 | */ | 
|---|
| [23b547] | 145 | class ptr_t { | 
|---|
|  | 146 | public: | 
|---|
|  | 147 | ptr_t(); | 
|---|
|  | 148 | ptr_t(T* _content); | 
|---|
|  | 149 | ~ptr_t(); | 
|---|
|  | 150 | T& operator*(); | 
|---|
|  | 151 | T* get(); | 
|---|
|  | 152 | void reset(T* _content); | 
|---|
|  | 153 | void reset(); | 
|---|
| [0f6f3a] | 154 | ptr_t& operator=(const ptr_t& rhs); | 
|---|
| [23b547] | 155 | private: | 
|---|
| [0f6f3a] | 156 | mutable T* content; | 
|---|
| [23b547] | 157 | }; | 
|---|
|  | 158 |  | 
|---|
|  | 159 | /** | 
|---|
| [c3dbe0] | 160 | * This object handles the actual creation inside the singleton | 
|---|
|  | 161 | * | 
|---|
|  | 162 | * Using template specialization this will allways know what it can | 
|---|
|  | 163 | * do or cannot do at compile time | 
|---|
| [23b547] | 164 | */ | 
|---|
|  | 165 | template<class creator_T, bool creator_may_create> | 
|---|
|  | 166 | struct creator_t { | 
|---|
| [c3dbe0] | 167 | inline static creator_T* make(); | 
|---|
|  | 168 | inline static void set(creator_T*&,creator_T*); | 
|---|
| [23b547] | 169 | }; | 
|---|
|  | 170 |  | 
|---|
|  | 171 | // specialization to allow fast creations | 
|---|
|  | 172 |  | 
|---|
| [c3dbe0] | 173 | /** | 
|---|
|  | 174 | * Specialized template that allows automatic construction only | 
|---|
|  | 175 | */ | 
|---|
| [23b547] | 176 | template<class creator_T> | 
|---|
|  | 177 | struct creator_t<creator_T,true>{ | 
|---|
| [c3dbe0] | 178 | inline static creator_T* make(){ | 
|---|
| [23b547] | 179 | return new creator_T(); | 
|---|
|  | 180 | } | 
|---|
|  | 181 |  | 
|---|
| [c3dbe0] | 182 | inline static void set(creator_T*&,creator_T*){ | 
|---|
| [23b547] | 183 | assert(0 && "Cannot set the Instance for a singleton of this type"); | 
|---|
|  | 184 | } | 
|---|
|  | 185 | }; | 
|---|
|  | 186 |  | 
|---|
| [c3dbe0] | 187 | /** | 
|---|
|  | 188 | * specialized template that allows setting only | 
|---|
|  | 189 | */ | 
|---|
| [23b547] | 190 | template<class creator_T> | 
|---|
|  | 191 | struct creator_t<creator_T,false>{ | 
|---|
| [c3dbe0] | 192 | inline static creator_T* make(){ | 
|---|
| [23b547] | 193 | assert(0 && "Cannot create a singleton of this type directly"); | 
|---|
|  | 194 | } | 
|---|
| [c3dbe0] | 195 | inline static void set(ptr_t& dest,creator_T* src){ | 
|---|
| [23b547] | 196 | dest.reset(src); | 
|---|
|  | 197 | } | 
|---|
|  | 198 | }; | 
|---|
|  | 199 |  | 
|---|
| [c3dbe0] | 200 | // this is used for creation | 
|---|
|  | 201 | typedef creator_t<T,_may_create> creator; //< the creator used | 
|---|
| [23b547] | 202 |  | 
|---|
| [c3dbe0] | 203 | public: | 
|---|
| [23b547] | 204 | // make the state of this singleton accessible | 
|---|
| [c3dbe0] | 205 | static const bool may_create=_may_create; //!< the type of singleton that we have | 
|---|
| [23b547] | 206 |  | 
|---|
| [c3dbe0] | 207 | /** | 
|---|
|  | 208 | * returns the instance of this Singleton as a reference | 
|---|
|  | 209 | * | 
|---|
|  | 210 | * If no Singleton exists at this point and we are allowed to create one | 
|---|
|  | 211 | * a new one is created and stored inside the singleton | 
|---|
|  | 212 | * | 
|---|
|  | 213 | * If no automatic creation is allowed, make sure to create an instance first | 
|---|
|  | 214 | * using the appropriate methods of the derived class. Otherwise this method | 
|---|
|  | 215 | * would fail. | 
|---|
|  | 216 | */ | 
|---|
| [23b547] | 217 | static T& getInstance(); | 
|---|
| [c3dbe0] | 218 |  | 
|---|
|  | 219 | /** | 
|---|
|  | 220 | * returns the instance of this singleton as a pointer | 
|---|
|  | 221 | * | 
|---|
|  | 222 | * If no Singleton exists at this point and we are allowed to create one | 
|---|
|  | 223 | * a new one is created and stored inside the singleton. | 
|---|
|  | 224 | * | 
|---|
|  | 225 | * If no automatic creation is allowed, make sure to create an instance first | 
|---|
|  | 226 | * using the appropriate methods of the derived class. Otherwise this method | 
|---|
|  | 227 | * would fail. | 
|---|
|  | 228 | */ | 
|---|
| [23b547] | 229 | static T* getPointer(); | 
|---|
|  | 230 |  | 
|---|
| [c3dbe0] | 231 | /** | 
|---|
|  | 232 | * destroys the current instance of this singleton | 
|---|
|  | 233 | */ | 
|---|
| [23b547] | 234 | static void purgeInstance(); | 
|---|
| [c3dbe0] | 235 |  | 
|---|
|  | 236 | /** | 
|---|
|  | 237 | * destroys the current instance of the singleton and immidiately constructs | 
|---|
|  | 238 | * a new one. Similar to using <code>purgeInstance()</code> and <code>getInstance()</code> | 
|---|
|  | 239 | * but plays more nicely when observers are present. Especially the new instance is created | 
|---|
|  | 240 | * before the old one is destroyed so observers can switch their targets, when they are notified | 
|---|
|  | 241 | * of the destruction. | 
|---|
|  | 242 | * | 
|---|
|  | 243 | * If no automatic creation is allowed this method wont work. | 
|---|
|  | 244 | */ | 
|---|
| [23b547] | 245 | static T&   resetInstance(); | 
|---|
|  | 246 |  | 
|---|
|  | 247 | protected: | 
|---|
| [c3dbe0] | 248 | /** | 
|---|
|  | 249 | * Method used to set the instance, when no automatic creation is allowed. | 
|---|
|  | 250 | * | 
|---|
|  | 251 | * Call this after the instantiation method in the derived class has created | 
|---|
|  | 252 | * it's instance and want's the singleton mechanism to keep it around for later | 
|---|
|  | 253 | * use. | 
|---|
|  | 254 | * | 
|---|
|  | 255 | * This method will always fail when automatic creation is enabled. | 
|---|
|  | 256 | */ | 
|---|
|  | 257 | static void setInstance(T*); | 
|---|
|  | 258 |  | 
|---|
|  | 259 |  | 
|---|
|  | 260 | /** | 
|---|
|  | 261 | * empty constructor to allow creation of subclases | 
|---|
|  | 262 | */ | 
|---|
| [0f6f3a] | 263 | Singleton(); | 
|---|
| [23b547] | 264 |  | 
|---|
|  | 265 | private: | 
|---|
| [c3dbe0] | 266 | /** | 
|---|
|  | 267 | * the copy constructor is private to avoid accidental copying of Singletons, for example | 
|---|
|  | 268 | * when passing singletons to functions by value instead of by reference. If you | 
|---|
|  | 269 | * need copying of singletons call the default constructor in the copy constructor | 
|---|
|  | 270 | * of the derived object. The copyied object wont be known to the singleton mechanism. | 
|---|
|  | 271 | */ | 
|---|
| [0f6f3a] | 272 | Singleton(const Singleton&); | 
|---|
|  | 273 |  | 
|---|
| [c3dbe0] | 274 | static boost::recursive_mutex instanceLock; //!< a lock for the pointer of the instance | 
|---|
|  | 275 | static ptr_t theInstance; //!< the actual instance of the singleton | 
|---|
| [23b547] | 276 | }; | 
|---|
|  | 277 |  | 
|---|
|  | 278 | #endif /* SINGLETON_HPP_ */ | 
|---|