OVR_System.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /************************************************************************************
  2. PublicHeader: OVR
  3. Filename : OVR_System.h
  4. Content : General kernel initialization/cleanup, including that
  5. of the memory allocator.
  6. Created : September 19, 2012
  7. Notes :
  8. Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
  9. Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
  10. you may not use the Oculus VR Rift SDK except in compliance with the License,
  11. which is provided at the time of installation or download, or which
  12. otherwise accompanies this software in either electronic or hard copy form.
  13. You may obtain a copy of the License at
  14. http://www.oculusvr.com/licenses/LICENSE-3.2
  15. Unless required by applicable law or agreed to in writing, the Oculus VR SDK
  16. distributed under the License is distributed on an "AS IS" BASIS,
  17. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. See the License for the specific language governing permissions and
  19. limitations under the License.
  20. ************************************************************************************/
  21. #ifndef OVR_System_h
  22. #define OVR_System_h
  23. #include "OVR_Allocator.h"
  24. #include "OVR_Log.h"
  25. #include "OVR_Atomic.h"
  26. namespace OVR {
  27. //-----------------------------------------------------------------------------
  28. // SystemSingleton
  29. // Subsystems are implemented using the Singleton pattern.
  30. // To avoid code duplication in all the places where Singletons are defined,
  31. // The pattern is defined once here and used everywhere.
  32. class SystemSingletonInternal
  33. {
  34. friend class System;
  35. // Allows for including this class in the shutdown list.
  36. SystemSingletonInternal* NextShutdownSingleton;
  37. // No copying allowed
  38. OVR_NON_COPYABLE(SystemSingletonInternal);
  39. public:
  40. // Call this to register for a call to OnThreadDestroy and OnSystemDestroy before the
  41. // Kernel is shut down. OnThreadDestroy is called before any remaining existing threads
  42. // are exited. Registered callbacks are called in the reverse order they were registered.
  43. // You would typically call this at the end of your SystemSingletonInternal subclass' constructor.
  44. // The registered objects are not deleted on shutdown; they would have to do that themselves within
  45. // OnSystemDestroy or via a compiler-generated static destruction.
  46. void RegisterDestroyCallback();
  47. void PushDestroyCallbacks() { RegisterDestroyCallback(); } // For backward compatibility.
  48. protected:
  49. SystemSingletonInternal() :
  50. NextShutdownSingleton(nullptr)
  51. {
  52. }
  53. virtual ~SystemSingletonInternal(){}
  54. // Initializes the SystemSingletonInternal.
  55. // You can register for an automatic call to this function by calling PushInitCallbacks.
  56. // The registration of an automatic call to this is not required, but may be useful if
  57. // you need to postpone your initialization until after Kernel is initialized.
  58. // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function.
  59. virtual void OnSystemInit() {}
  60. // Called just before waiting for threads to exit.
  61. // Listeners are called in the opposite order they were registered.
  62. // This function is useful for terminating threads at the right time before the rest of the system is shut down.
  63. // Note: The singleton must not delete itself here, as OnSystemDestroy will subsequently be called for it.
  64. virtual void OnThreadDestroy() {}
  65. // Shuts down the SystemSingletonInternal.
  66. // You can register for an automatic call to this function by calling PushDestroyCallbacks.
  67. // The registration of an automatic call to this is not required, but may be useful if
  68. // you need to delay your shutdown until application exit time.
  69. // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function.
  70. // This function may delete this.
  71. virtual void OnSystemDestroy() {}
  72. };
  73. // Singletons derive from this class
  74. template<class T>
  75. class SystemSingletonBase : public SystemSingletonInternal
  76. {
  77. static AtomicPtr<T> SingletonInstance;
  78. static T* SlowGetInstance();
  79. protected:
  80. ~SystemSingletonBase()
  81. {
  82. // Make sure the instance gets set to zero on dtor
  83. if (SingletonInstance == this)
  84. SingletonInstance = nullptr;
  85. }
  86. public:
  87. static OVR_FORCE_INLINE T* GetInstance()
  88. {
  89. // Fast version
  90. // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed
  91. // atomically from multiple threads without locks.
  92. T* instance = SingletonInstance;
  93. return instance ? instance : SlowGetInstance();
  94. }
  95. };
  96. // For reference, see N3337 14.5.1.3 (Static data members of class templates):
  97. template<class T> OVR::AtomicPtr<T> OVR::SystemSingletonBase<T>::SingletonInstance;
  98. // Place this in the singleton class in the header file
  99. #define OVR_DECLARE_SINGLETON(T) \
  100. friend class OVR::SystemSingletonBase<T>; \
  101. private: \
  102. T(); \
  103. virtual ~T(); \
  104. virtual void OnSystemDestroy();
  105. // Place this in the singleton class source file
  106. #define OVR_DEFINE_SINGLETON(T) \
  107. namespace OVR { \
  108. template<> T* SystemSingletonBase<T>::SlowGetInstance() \
  109. { \
  110. static OVR::Lock lock; \
  111. OVR::Lock::Locker locker(&lock); \
  112. if (!SingletonInstance) \
  113. SingletonInstance = new T; \
  114. return SingletonInstance; \
  115. } \
  116. }
  117. // ***** System Core Initialization class
  118. // System initialization must take place before any other OVR_Kernel objects are used;
  119. // this is done my calling System::Init(). Among other things, this is necessary to
  120. // initialize the memory allocator. Similarly, System::Destroy must be
  121. // called before program exist for proper cleanup. Both of these tasks can be achieved by
  122. // simply creating System object first, allowing its constructor/destructor do the work.
  123. class System
  124. {
  125. public:
  126. // Returns 'true' if system was properly initialized.
  127. static bool OVR_CDECL IsInitialized();
  128. // Initializes System core. Users can override memory implementation by passing
  129. // a different Allocator here.
  130. static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug));
  131. // De-initializes System more, finalizing the threading system and destroying
  132. // the global memory allocator.
  133. static void OVR_CDECL Destroy();
  134. };
  135. } // namespace OVR
  136. #endif