ovr_sdk
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/LibOVR/Src/Kernel/OVR_System.h Wed Jan 14 06:51:16 2015 +0200 1.3 @@ -0,0 +1,174 @@ 1.4 +/************************************************************************************ 1.5 + 1.6 +PublicHeader: OVR 1.7 +Filename : OVR_System.h 1.8 +Content : General kernel initialization/cleanup, including that 1.9 + of the memory allocator. 1.10 +Created : September 19, 2012 1.11 +Notes : 1.12 + 1.13 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. 1.14 + 1.15 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 1.16 +you may not use the Oculus VR Rift SDK except in compliance with the License, 1.17 +which is provided at the time of installation or download, or which 1.18 +otherwise accompanies this software in either electronic or hard copy form. 1.19 + 1.20 +You may obtain a copy of the License at 1.21 + 1.22 +http://www.oculusvr.com/licenses/LICENSE-3.2 1.23 + 1.24 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK 1.25 +distributed under the License is distributed on an "AS IS" BASIS, 1.26 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.27 +See the License for the specific language governing permissions and 1.28 +limitations under the License. 1.29 + 1.30 +************************************************************************************/ 1.31 + 1.32 +#ifndef OVR_System_h 1.33 +#define OVR_System_h 1.34 + 1.35 +#include "OVR_Allocator.h" 1.36 +#include "OVR_Log.h" 1.37 +#include "OVR_Atomic.h" 1.38 + 1.39 +namespace OVR { 1.40 + 1.41 + 1.42 +//----------------------------------------------------------------------------- 1.43 +// SystemSingleton 1.44 + 1.45 +// Subsystems are implemented using the Singleton pattern. 1.46 +// To avoid code duplication in all the places where Singletons are defined, 1.47 +// The pattern is defined once here and used everywhere. 1.48 + 1.49 +class SystemSingletonInternal 1.50 +{ 1.51 + friend class System; 1.52 + 1.53 + SystemSingletonInternal* NextSingleton; 1.54 + 1.55 + // No copying allowed 1.56 + OVR_NON_COPYABLE(SystemSingletonInternal); 1.57 + 1.58 +protected: 1.59 + SystemSingletonInternal() : 1.60 + NextSingleton(0) 1.61 + { 1.62 + } 1.63 + 1.64 + virtual ~SystemSingletonInternal(){} 1.65 + 1.66 + // Call this to register the destroy events 1.67 + // Destroy callbacks will be called in the reverse order they were registered 1.68 + // Note: As a rule of thumb, call this at the end of the singleton class constructor. 1.69 + void PushDestroyCallbacks(); 1.70 + 1.71 + // Required: Invoked when the System object is shutting down 1.72 + // Called after threads are stopped 1.73 + // Called before Log, Allocator, and Timer subsystems are stopped 1.74 + // Listeners are called in the opposite order they were registered 1.75 + virtual void OnSystemDestroy() = 0; 1.76 + 1.77 + // Called just before waiting for threads to die 1.78 + // Listeners are called in the opposite order they were registered 1.79 + // Useful to start terminating threads at the right time 1.80 + // Note: The singleton must not delete itself here. 1.81 + virtual void OnThreadDestroy() {} 1.82 +}; 1.83 + 1.84 +// Singletons derive from this class 1.85 +template<class T> 1.86 +class SystemSingletonBase : public SystemSingletonInternal 1.87 +{ 1.88 + static AtomicPtr<T> SingletonInstance; 1.89 + static T* SlowGetInstance(); 1.90 + 1.91 +protected: 1.92 + ~SystemSingletonBase() 1.93 + { 1.94 + // Make sure the instance gets set to zero on dtor 1.95 + if (SingletonInstance == this) 1.96 + SingletonInstance = 0; 1.97 + } 1.98 + 1.99 +public: 1.100 + static OVR_FORCE_INLINE T* GetInstance() 1.101 + { 1.102 + // Fast version 1.103 + // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed 1.104 + // atomically from multiple threads without locks. 1.105 + T* instance = SingletonInstance; 1.106 + return instance ? instance : SlowGetInstance(); 1.107 + } 1.108 +}; 1.109 + 1.110 +// For reference, see N3337 14.5.1.3 (Static data members of class templates): 1.111 +template<class T> OVR::AtomicPtr<T> OVR::SystemSingletonBase<T>::SingletonInstance; 1.112 + 1.113 +// Place this in the singleton class in the header file 1.114 +#define OVR_DECLARE_SINGLETON(T) \ 1.115 + friend class OVR::SystemSingletonBase<T>; \ 1.116 +private: \ 1.117 + T(); \ 1.118 + virtual ~T(); \ 1.119 + virtual void OnSystemDestroy(); 1.120 + 1.121 +// Place this in the singleton class source file 1.122 +#define OVR_DEFINE_SINGLETON(T) \ 1.123 + namespace OVR { \ 1.124 + template<> T* SystemSingletonBase<T>::SlowGetInstance() \ 1.125 + { \ 1.126 + static OVR::Lock lock; \ 1.127 + OVR::Lock::Locker locker(&lock); \ 1.128 + if (!SingletonInstance) SingletonInstance = new T; \ 1.129 + return SingletonInstance; \ 1.130 + } \ 1.131 + } 1.132 + 1.133 + 1.134 +// ***** System Core Initialization class 1.135 + 1.136 +// System initialization must take place before any other OVR_Kernel objects are used; 1.137 +// this is done my calling System::Init(). Among other things, this is necessary to 1.138 +// initialize the memory allocator. Similarly, System::Destroy must be 1.139 +// called before program exist for proper cleanup. Both of these tasks can be achieved by 1.140 +// simply creating System object first, allowing its constructor/destructor do the work. 1.141 + 1.142 +// TBD: Require additional System class for Oculus Rift API? 1.143 + 1.144 +class System 1.145 +{ 1.146 +public: 1.147 + // System constructor expects allocator to be specified, if it is being substituted. 1.148 + System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), 1.149 + Allocator* palloc = DefaultAllocator::InitSystemSingleton()) 1.150 + { 1.151 + Init(log, palloc); 1.152 + } 1.153 + ~System() 1.154 + { 1.155 + Destroy(); 1.156 + } 1.157 + 1.158 + static void OVR_CDECL DirectDisplayInitialize(); 1.159 + static bool OVR_CDECL DirectDisplayEnabled(); 1.160 + 1.161 + // Returns 'true' if system was properly initialized. 1.162 + static bool OVR_CDECL IsInitialized(); 1.163 + 1.164 + // Initializes System core. Users can override memory implementation by passing 1.165 + // a different Allocator here. 1.166 + static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), 1.167 + Allocator *palloc = DefaultAllocator::InitSystemSingleton()); 1.168 + 1.169 + // De-initializes System more, finalizing the threading system and destroying 1.170 + // the global memory allocator. 1.171 + static void OVR_CDECL Destroy(); 1.172 +}; 1.173 + 1.174 + 1.175 +} // namespace OVR 1.176 + 1.177 +#endif