]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/SkySingleton.hpp
Clouds3D crashes because there is no Light
[simgear.git] / simgear / scene / sky / clouds3d / SkySingleton.hpp
1 //------------------------------------------------------------------------------
2 // File : SkySingleton.hpp
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 //                                              The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its 
8 // documentation for any purpose is hereby granted without fee, provided that 
9 // the above copyright notice appear in all copies and that both that copyright 
10 // notice and this permission notice appear in supporting documentation. 
11 // Binaries may be compiled with this software without any royalties or 
12 // restrictions. 
13 //
14 // The author(s) and The University of North Carolina at Chapel Hill make no 
15 // representations about the suitability of this software for any purpose. 
16 // It is provided "as is" without express or 
17 // implied warranty.
18 /**
19  * @file SkySingleton.hpp
20  * 
21  * A generic singleton template wrapper to make classes into singletons
22  */
23 #ifndef __SKYSINGLETON_HPP__
24 #define __SKYSINGLETON_HPP__
25
26 #include "SkyUtil.hpp"
27 #include <assert.h>
28 #include <stdlib.h>
29
30 //------------------------------------------------------------------------------
31 /**
32  * @class SkySingleton
33  * @brief A singleton template class.
34  * 
35  * Usage : Use this template container class to make any class into a
36  *         singleton.  I usually do this:
37  *
38  * @code   
39  * class MyClass       
40  * {       
41  * public:       
42  *   // normal class stuff, but don't put ctor/dtor here.       
43  *   int GetData() { return _someData; }       
44  * protected:       
45  *   // Make the ctor(s)/dtor protected, so this can only be       
46  *   // instantiated as a singleton.  Note: singleton will still       
47  *   // work on classes that do not follow this (public ctors)       
48  *   // but violation of the singleton is possible then, since non-       
49  *   // singleton versions of the class can be instantiated.       
50  *   MyClass() : _someData(5) {}       
51  *   MyClass(int arg) : _someData(arg) {} // etc...       
52  *   // don't implement the copy constructor, because singletons       
53  *   // shouldn't be copied!       
54  *   MyClass(const MyClass& mc) {}       
55  *   ~MyClass() {}       
56  * private:       
57  *   int _someData;       
58  * };
59  *
60  * // now create a singleton of MyClass       
61  * typedef SkySingleton<MyClass> MyClassSingleton;
62  *
63  * @endcode
64  * Later, in your program code, you can instantiate the singleton and access
65  * its members like so:
66  *
67  * @code   
68  * void somefunc()        
69  * {        
70  *   // instantiate the MyClassSingleton        
71  *   MyClassSingleton::Instantiate();        
72  *   // could also call MyClassSingleton::Instantiate(10);        
73  *   // since we have a constructor of that form in MyClass.
74  *         
75  *   // access the methods in MyClass:        
76  *   int data1 = MyClassSingleton::InstancePtr()->GetData();        
77  *   // or...        
78  *   int data2 = MyClassSingleton::InstanceRef().GetData();
79  *         
80  *   // now destroy the singleton        
81  *   MyClassSingleton::Destroy();        
82  * }
83  * @endcode
84  */
85 template <class T>
86 class SkySingleton : protected T
87 {
88 public:
89   
90   //------------------------------------------------------------------------------
91   // Function             : Instantiate
92   // Description            : 
93   //------------------------------------------------------------------------------
94   /**
95    * @fn Instantiate()
96    * @brief Creates the singleton instance for class T.
97    *
98    * Assures (by assertion) that the instance will only be created once.
99    * This works for default constructors.
100    */ 
101   static void Instantiate()
102   {
103     assert(!s_pInstance);
104     s_pInstance = new SkySingleton();
105   }
106   
107   //------------------------------------------------------------------------------
108   // Function             : Destroy
109   // Description            : 
110   //------------------------------------------------------------------------------
111   /**
112    * @fn Destroy()           { SAFE_DELETE(s_pInstance);                 }
113    * @brief Destructor, deletes the instance
114    */ 
115   static void Destroy()           { SAFE_DELETE(s_pInstance);                 }
116   
117   //------------------------------------------------------------------------------
118   // Function             : InstancePtr
119   // Description            : 
120   //------------------------------------------------------------------------------
121   /**
122    * @fn InstancePtr()         { assert(s_pInstance); return s_pInstance;  }
123    * @brief Returns a pointer to the instance
124    */ 
125   static T* InstancePtr()         { assert(s_pInstance); return s_pInstance;  }
126
127   //------------------------------------------------------------------------------
128   // Function             : InstanceRef
129   // Description            : 
130   //------------------------------------------------------------------------------
131   /**
132    * @fn InstanceRef()         { assert(s_pInstance); return *s_pInstance; }
133    * @brief Returns a reference to the instance
134    */ 
135   static T& InstanceRef()         { assert(s_pInstance); return *s_pInstance; }
136
137   //------------------------------------------------------------------------------
138   // Function             :  static void Instantiate
139   // Description            : 
140   //------------------------------------------------------------------------------
141   /**
142    * @fn  static void Instantiate(const A& a)
143    * @brief Instantiates class of type T that have constructors with an argument
144    *
145    * This might be a source of confusion.  These templatized
146    * functions are used to instantiate classes of type T that
147    * have constructors with arguments.  For n arguments, you
148    * to add a function below with n arguments.  Note, these will
149    * only be created if they are used, since they are templates.
150    * I've added 4 below, for 1-4 arguments.  If you get a
151    * compilation error, add one for the number of arguments you
152    * need.  Also need a SkySingleton protected constructor with
153    * the same number of arguments.
154    */ 
155   template<class A>
156   static void Instantiate(const A& a)
157   {
158     assert(!s_pInstance);
159     s_pInstance = new SkySingleton(a);
160   }
161
162   //------------------------------------------------------------------------------
163   // Function             : Instantiate
164   // Description            : 
165   //------------------------------------------------------------------------------
166   /**
167    * @fn Instantiate(const A& a, const B& b)
168    * @brief Instantiates class of type T that have constructors with 2 args
169    */ 
170   template<class A, class B>
171   static void Instantiate(const A& a, const B& b)
172   {
173     assert(!s_pInstance);
174     s_pInstance = new SkySingleton(a, b);
175   }
176
177   //------------------------------------------------------------------------------
178   // Function             : Instantiate
179   // Description            : 
180   //------------------------------------------------------------------------------
181   /**
182    * @fn Instantiate(const A& a, const B& b, const C& c)
183    * @brief Instantiates class of type T that have constructors with 3 args
184    */ 
185   template<class A, class B, class C>
186   static void Instantiate(const A& a, const B& b, const C& c)
187   {
188     assert(!s_pInstance);
189     s_pInstance = new SkySingleton(a, b, c);
190   }
191
192   //------------------------------------------------------------------------------
193   // Function             : Instantiate
194   // Description            : 
195   //------------------------------------------------------------------------------
196   /**
197    * @fn Instantiate(const A& a, const B& b, const C& c, const D& d)
198    * @brief Instantiates class of type T that have constructors with 4 args
199    */ 
200   template<class A, class B, class C, class D> 
201   static void Instantiate(const A& a, const B& b, const C& c, const D& d)
202   {
203     assert(!s_pInstance);
204     s_pInstance = new SkySingleton(a, b, c, d);
205   }
206   
207 protected:
208   // although the instance is of type SkySingleton<T>, the Instance***() funcs 
209   // above implicitly cast it to type T.
210   static SkySingleton* s_pInstance;
211   
212 private:
213
214   //------------------------------------------------------------------------------
215   // Function             : SkySingleton
216   // Description            : 
217   //------------------------------------------------------------------------------
218   /**
219    * @fn SkySingleton()
220    * @brief Hidden so that the singleton can only be instantiated via public static Instantiate function.
221    */ 
222   SkySingleton() : T() {}
223   
224   //------------------------------------------------------------------------------
225   // Function             : Singleton
226   // Description            : 
227   //------------------------------------------------------------------------------
228   /**
229    * @fn Singleton(const A& a)
230    * @brief Used by the templatized public Instantiate() functions.
231    */ 
232   template<class A> 
233   SkySingleton(const A& a) : T(a) {}
234
235   //------------------------------------------------------------------------------
236   // Function             : Singleton
237   // Description            : 
238   //------------------------------------------------------------------------------
239   /**
240    * @fn Singleton(const A& a, const B& b)
241    * @brief Used by the templatized public Instantiate() functions.
242    */ 
243   template<class A, class B> 
244   SkySingleton(const A& a, const B& b) : T(a, b) {}
245
246   //------------------------------------------------------------------------------
247   // Function             : Singleton
248   // Description            : 
249   //------------------------------------------------------------------------------
250   /**
251    * @fn Singleton(const A& a, const B& b, const C& c)
252    * @brief Used by the templatized public Instantiate() functions.
253    */ 
254   template<class A, class B, class C> 
255   SkySingleton(const A& a, const B& b, const C& c) : T(a, b, c) {}
256
257   //------------------------------------------------------------------------------
258   // Function             : Singleton
259   // Description            : 
260   //------------------------------------------------------------------------------
261   /**
262    * @fn Singleton(const A& a, const B& b, const C &c, const D& d)
263    * @brief Used by the templatized public Instantiate() functions.
264    */ 
265   template<class A, class B, class C, class D> 
266   SkySingleton(const A& a, const B& b, const C &c, const D& d) : T(a, b, c, d) {}
267
268   //------------------------------------------------------------------------------
269   // Function             : SkySingleton
270   // Description            : 
271   //------------------------------------------------------------------------------
272   /**
273    * @fn SkySingleton(const SkySingleton&)
274    * @brief Hidden because you can't copy a singleton!
275    */ 
276   SkySingleton(const SkySingleton&) {}  // hide the copy ctor: singletons can'
277
278   //------------------------------------------------------------------------------
279   // Function             : ~SkySingleton
280   // Description            : 
281   //------------------------------------------------------------------------------
282   /**
283    * @fn ~SkySingleton()
284    * @brief Destructor, hidden, destroy via the public static Destroy() method.
285    */ 
286   ~SkySingleton()                  {}  // hide the dtor: 
287 };
288
289 // declare the static instance pointer
290 template<class T> SkySingleton<T>* SkySingleton<T>::s_pInstance = NULL;
291
292 #endif //__SKYSINGLETON_HPP__