ovr_sdk

annotate LibOVR/Src/Kernel/OVR_System.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
rev   line source
nuclear@0 1 /************************************************************************************
nuclear@0 2
nuclear@0 3 PublicHeader: OVR
nuclear@0 4 Filename : OVR_System.h
nuclear@0 5 Content : General kernel initialization/cleanup, including that
nuclear@0 6 of the memory allocator.
nuclear@0 7 Created : September 19, 2012
nuclear@0 8 Notes :
nuclear@0 9
nuclear@0 10 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
nuclear@0 11
nuclear@0 12 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
nuclear@0 13 you may not use the Oculus VR Rift SDK except in compliance with the License,
nuclear@0 14 which is provided at the time of installation or download, or which
nuclear@0 15 otherwise accompanies this software in either electronic or hard copy form.
nuclear@0 16
nuclear@0 17 You may obtain a copy of the License at
nuclear@0 18
nuclear@0 19 http://www.oculusvr.com/licenses/LICENSE-3.2
nuclear@0 20
nuclear@0 21 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
nuclear@0 22 distributed under the License is distributed on an "AS IS" BASIS,
nuclear@0 23 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nuclear@0 24 See the License for the specific language governing permissions and
nuclear@0 25 limitations under the License.
nuclear@0 26
nuclear@0 27 ************************************************************************************/
nuclear@0 28
nuclear@0 29 #ifndef OVR_System_h
nuclear@0 30 #define OVR_System_h
nuclear@0 31
nuclear@0 32 #include "OVR_Allocator.h"
nuclear@0 33 #include "OVR_Log.h"
nuclear@0 34 #include "OVR_Atomic.h"
nuclear@0 35
nuclear@0 36 namespace OVR {
nuclear@0 37
nuclear@0 38
nuclear@0 39 //-----------------------------------------------------------------------------
nuclear@0 40 // SystemSingleton
nuclear@0 41
nuclear@0 42 // Subsystems are implemented using the Singleton pattern.
nuclear@0 43 // To avoid code duplication in all the places where Singletons are defined,
nuclear@0 44 // The pattern is defined once here and used everywhere.
nuclear@0 45
nuclear@0 46 class SystemSingletonInternal
nuclear@0 47 {
nuclear@0 48 friend class System;
nuclear@0 49
nuclear@0 50 SystemSingletonInternal* NextSingleton;
nuclear@0 51
nuclear@0 52 // No copying allowed
nuclear@0 53 OVR_NON_COPYABLE(SystemSingletonInternal);
nuclear@0 54
nuclear@0 55 protected:
nuclear@0 56 SystemSingletonInternal() :
nuclear@0 57 NextSingleton(0)
nuclear@0 58 {
nuclear@0 59 }
nuclear@0 60
nuclear@0 61 virtual ~SystemSingletonInternal(){}
nuclear@0 62
nuclear@0 63 // Call this to register the destroy events
nuclear@0 64 // Destroy callbacks will be called in the reverse order they were registered
nuclear@0 65 // Note: As a rule of thumb, call this at the end of the singleton class constructor.
nuclear@0 66 void PushDestroyCallbacks();
nuclear@0 67
nuclear@0 68 // Required: Invoked when the System object is shutting down
nuclear@0 69 // Called after threads are stopped
nuclear@0 70 // Called before Log, Allocator, and Timer subsystems are stopped
nuclear@0 71 // Listeners are called in the opposite order they were registered
nuclear@0 72 virtual void OnSystemDestroy() = 0;
nuclear@0 73
nuclear@0 74 // Called just before waiting for threads to die
nuclear@0 75 // Listeners are called in the opposite order they were registered
nuclear@0 76 // Useful to start terminating threads at the right time
nuclear@0 77 // Note: The singleton must not delete itself here.
nuclear@0 78 virtual void OnThreadDestroy() {}
nuclear@0 79 };
nuclear@0 80
nuclear@0 81 // Singletons derive from this class
nuclear@0 82 template<class T>
nuclear@0 83 class SystemSingletonBase : public SystemSingletonInternal
nuclear@0 84 {
nuclear@0 85 static AtomicPtr<T> SingletonInstance;
nuclear@0 86 static T* SlowGetInstance();
nuclear@0 87
nuclear@0 88 protected:
nuclear@0 89 ~SystemSingletonBase()
nuclear@0 90 {
nuclear@0 91 // Make sure the instance gets set to zero on dtor
nuclear@0 92 if (SingletonInstance == this)
nuclear@0 93 SingletonInstance = 0;
nuclear@0 94 }
nuclear@0 95
nuclear@0 96 public:
nuclear@0 97 static OVR_FORCE_INLINE T* GetInstance()
nuclear@0 98 {
nuclear@0 99 // Fast version
nuclear@0 100 // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed
nuclear@0 101 // atomically from multiple threads without locks.
nuclear@0 102 T* instance = SingletonInstance;
nuclear@0 103 return instance ? instance : SlowGetInstance();
nuclear@0 104 }
nuclear@0 105 };
nuclear@0 106
nuclear@0 107 // For reference, see N3337 14.5.1.3 (Static data members of class templates):
nuclear@0 108 template<class T> OVR::AtomicPtr<T> OVR::SystemSingletonBase<T>::SingletonInstance;
nuclear@0 109
nuclear@0 110 // Place this in the singleton class in the header file
nuclear@0 111 #define OVR_DECLARE_SINGLETON(T) \
nuclear@0 112 friend class OVR::SystemSingletonBase<T>; \
nuclear@0 113 private: \
nuclear@0 114 T(); \
nuclear@0 115 virtual ~T(); \
nuclear@0 116 virtual void OnSystemDestroy();
nuclear@0 117
nuclear@0 118 // Place this in the singleton class source file
nuclear@0 119 #define OVR_DEFINE_SINGLETON(T) \
nuclear@0 120 namespace OVR { \
nuclear@0 121 template<> T* SystemSingletonBase<T>::SlowGetInstance() \
nuclear@0 122 { \
nuclear@0 123 static OVR::Lock lock; \
nuclear@0 124 OVR::Lock::Locker locker(&lock); \
nuclear@0 125 if (!SingletonInstance) SingletonInstance = new T; \
nuclear@0 126 return SingletonInstance; \
nuclear@0 127 } \
nuclear@0 128 }
nuclear@0 129
nuclear@0 130
nuclear@0 131 // ***** System Core Initialization class
nuclear@0 132
nuclear@0 133 // System initialization must take place before any other OVR_Kernel objects are used;
nuclear@0 134 // this is done my calling System::Init(). Among other things, this is necessary to
nuclear@0 135 // initialize the memory allocator. Similarly, System::Destroy must be
nuclear@0 136 // called before program exist for proper cleanup. Both of these tasks can be achieved by
nuclear@0 137 // simply creating System object first, allowing its constructor/destructor do the work.
nuclear@0 138
nuclear@0 139 // TBD: Require additional System class for Oculus Rift API?
nuclear@0 140
nuclear@0 141 class System
nuclear@0 142 {
nuclear@0 143 public:
nuclear@0 144 // System constructor expects allocator to be specified, if it is being substituted.
nuclear@0 145 System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
nuclear@0 146 Allocator* palloc = DefaultAllocator::InitSystemSingleton())
nuclear@0 147 {
nuclear@0 148 Init(log, palloc);
nuclear@0 149 }
nuclear@0 150 ~System()
nuclear@0 151 {
nuclear@0 152 Destroy();
nuclear@0 153 }
nuclear@0 154
nuclear@0 155 static void OVR_CDECL DirectDisplayInitialize();
nuclear@0 156 static bool OVR_CDECL DirectDisplayEnabled();
nuclear@0 157
nuclear@0 158 // Returns 'true' if system was properly initialized.
nuclear@0 159 static bool OVR_CDECL IsInitialized();
nuclear@0 160
nuclear@0 161 // Initializes System core. Users can override memory implementation by passing
nuclear@0 162 // a different Allocator here.
nuclear@0 163 static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug),
nuclear@0 164 Allocator *palloc = DefaultAllocator::InitSystemSingleton());
nuclear@0 165
nuclear@0 166 // De-initializes System more, finalizing the threading system and destroying
nuclear@0 167 // the global memory allocator.
nuclear@0 168 static void OVR_CDECL Destroy();
nuclear@0 169 };
nuclear@0 170
nuclear@0 171
nuclear@0 172 } // namespace OVR
nuclear@0 173
nuclear@0 174 #endif