tSingleton.h

Engine/source/core/util/tSingleton.h

More...

Classes:

class

This is a managed singleton class with explict creation and destruction functions which must be called at startup and shutdown of the engine.

class

This is a simple thread safe singleton class based on the design of boost::singleton_default (see http://www.boost.org/).

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _TSINGLETON_H_
 25#define _TSINGLETON_H_
 26
 27#ifndef _PLATFORMASSERT_H_
 28#include "platform/platformAssert.h"
 29#endif
 30
 31/// This is a simple thread safe singleton class based on the 
 32/// design of boost::singleton_default (see http://www.boost.org/).
 33///
 34/// This singleton is guaranteed to be constructed before main() is called
 35/// and destroyed after main() exits.  It will also be created on demand
 36/// if Singleton<T>::instance() is called before main() begins.
 37/// 
 38/// This thread safety only works within the execution context of main().
 39/// Access to the singleton from multiple threads outside of main() is
 40/// is not guaranteed to be thread safe.
 41///
 42/// To create a singleton you only need to access it once in your code:
 43///
 44///   Singleton<MySingletonClass>::instance()->myFunction();
 45///
 46/// You do not need to derive from this class.
 47///
 48/// @note Generally stay away from this class (!!) except if your class T
 49///   has no meaningful constructor.  Otherwise, it is very easy to make
 50///   execution of global ctors ordering dependent.
 51template <typename T>
 52class Singleton
 53{
 54private:
 55
 56   // This is the creator object which ensures that the
 57   // singleton is created before main() begins.
 58   struct SingletonCreator
 59   {
 60      SingletonCreator() { Singleton<T>::instance(); } 
 61
 62      // This dummy function is used below to force 
 63      // singleton creation at startup.
 64      inline void forceSafeCreate() const {}
 65   };
 66
 67   // The creator object instance.
 68   static SingletonCreator smSingletonCreator;
 69   
 70   /// This is private on purpose.
 71   Singleton();
 72
 73public:
 74
 75   /// Returns the singleton instance.
 76   static T* instance()
 77   {
 78      // The singleton.
 79      static T theSingleton;
 80
 81      // This is here to force the compiler to create
 82      // the singleton before main() is called.
 83      smSingletonCreator.forceSafeCreate();
 84
 85      return &theSingleton;
 86   }
 87
 88};
 89
 90template <typename T> 
 91typename Singleton<T>::SingletonCreator Singleton<T>::smSingletonCreator;
 92
 93
 94/// This is a managed singleton class with explict creation
 95/// and destruction functions which must be called at startup
 96/// and shutdown of the engine.
 97///
 98/// Your class to be managed must implement the following
 99/// function:
100///
101/// static const char* getSingletonName() { return "YourClassName"; }
102///
103/// This allow us to provide better asserts.
104///
105template <typename T>
106class ManagedSingleton
107{
108private:
109
110   static T *smSingleton;
111
112public:
113
114   /// Create the singleton instance.
115   /// @note Asserts when the singleton instance has already been constructed.
116   static void createSingleton() 
117   {
118      AssertFatal( smSingleton == NULL, String::ToString( "%s::createSingleton() - The singleton is already created!", T::getSingletonName() ) );
119      smSingleton = new T(); 
120   }
121
122   /// Destroy the singleton instance.
123   /// @note Asserts when no singleton has been constructed.
124   static void deleteSingleton()
125   {
126      AssertFatal( smSingleton, String::ToString( "%s::deleteSingleton() - The singleton doest not exist!", T::getSingletonName() ) );
127      delete smSingleton;
128      smSingleton = NULL;
129   }
130
131   /// Return the singleton instance.
132   /// @note Asserts when called before createSingleton().
133   static T* instance() 
134   { 
135      AssertFatal( smSingleton, String::ToString( "%s::instance() - The singleton has not been created!", T::getSingletonName() ) );
136      return smSingleton; 
137   }
138
139   /// Return the singleton instance or NULL if it has been deleted or not yet constructed.
140   static T* instanceOrNull()
141   {
142      return smSingleton;
143   }
144};
145
146///
147template <typename T> 
148T* ManagedSingleton<T>::smSingleton = NULL;
149
150
151#endif //_TSINGLETON_H_
152
153