| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /************************************************************************************
- PublicHeader: OVR
- Filename : OVR_System.h
- Content : General kernel initialization/cleanup, including that
- of the memory allocator.
- Created : September 19, 2012
- Notes :
- Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
- Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
- you may not use the Oculus VR Rift SDK except in compliance with the License,
- which is provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
- You may obtain a copy of the License at
- http://www.oculusvr.com/licenses/LICENSE-3.2
- Unless required by applicable law or agreed to in writing, the Oculus VR SDK
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ************************************************************************************/
- #ifndef OVR_System_h
- #define OVR_System_h
- #include "OVR_Allocator.h"
- #include "OVR_Log.h"
- #include "OVR_Atomic.h"
- namespace OVR {
- //-----------------------------------------------------------------------------
- // SystemSingleton
- // Subsystems are implemented using the Singleton pattern.
- // To avoid code duplication in all the places where Singletons are defined,
- // The pattern is defined once here and used everywhere.
- class SystemSingletonInternal
- {
- friend class System;
- // Allows for including this class in the shutdown list.
- SystemSingletonInternal* NextShutdownSingleton;
- // No copying allowed
- OVR_NON_COPYABLE(SystemSingletonInternal);
- public:
- // Call this to register for a call to OnThreadDestroy and OnSystemDestroy before the
- // Kernel is shut down. OnThreadDestroy is called before any remaining existing threads
- // are exited. Registered callbacks are called in the reverse order they were registered.
- // You would typically call this at the end of your SystemSingletonInternal subclass' constructor.
- // The registered objects are not deleted on shutdown; they would have to do that themselves within
- // OnSystemDestroy or via a compiler-generated static destruction.
- void RegisterDestroyCallback();
- void PushDestroyCallbacks() { RegisterDestroyCallback(); } // For backward compatibility.
- protected:
- SystemSingletonInternal() :
- NextShutdownSingleton(nullptr)
- {
- }
- virtual ~SystemSingletonInternal(){}
- // Initializes the SystemSingletonInternal.
- // You can register for an automatic call to this function by calling PushInitCallbacks.
- // The registration of an automatic call to this is not required, but may be useful if
- // you need to postpone your initialization until after Kernel is initialized.
- // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function.
- virtual void OnSystemInit() {}
- // Called just before waiting for threads to exit.
- // Listeners are called in the opposite order they were registered.
- // This function is useful for terminating threads at the right time before the rest of the system is shut down.
- // Note: The singleton must not delete itself here, as OnSystemDestroy will subsequently be called for it.
- virtual void OnThreadDestroy() {}
- // Shuts down the SystemSingletonInternal.
- // You can register for an automatic call to this function by calling PushDestroyCallbacks.
- // The registration of an automatic call to this is not required, but may be useful if
- // you need to delay your shutdown until application exit time.
- // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function.
- // This function may delete this.
- virtual void OnSystemDestroy() {}
- };
- // Singletons derive from this class
- template<class T>
- class SystemSingletonBase : public SystemSingletonInternal
- {
- static AtomicPtr<T> SingletonInstance;
- static T* SlowGetInstance();
- protected:
- ~SystemSingletonBase()
- {
- // Make sure the instance gets set to zero on dtor
- if (SingletonInstance == this)
- SingletonInstance = nullptr;
- }
- public:
- static OVR_FORCE_INLINE T* GetInstance()
- {
- // Fast version
- // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed
- // atomically from multiple threads without locks.
- T* instance = SingletonInstance;
- return instance ? instance : SlowGetInstance();
- }
- };
- // For reference, see N3337 14.5.1.3 (Static data members of class templates):
- template<class T> OVR::AtomicPtr<T> OVR::SystemSingletonBase<T>::SingletonInstance;
- // Place this in the singleton class in the header file
- #define OVR_DECLARE_SINGLETON(T) \
- friend class OVR::SystemSingletonBase<T>; \
- private: \
- T(); \
- virtual ~T(); \
- virtual void OnSystemDestroy();
- // Place this in the singleton class source file
- #define OVR_DEFINE_SINGLETON(T) \
- namespace OVR { \
- template<> T* SystemSingletonBase<T>::SlowGetInstance() \
- { \
- static OVR::Lock lock; \
- OVR::Lock::Locker locker(&lock); \
- if (!SingletonInstance) \
- SingletonInstance = new T; \
- return SingletonInstance; \
- } \
- }
- // ***** System Core Initialization class
- // System initialization must take place before any other OVR_Kernel objects are used;
- // this is done my calling System::Init(). Among other things, this is necessary to
- // initialize the memory allocator. Similarly, System::Destroy must be
- // called before program exist for proper cleanup. Both of these tasks can be achieved by
- // simply creating System object first, allowing its constructor/destructor do the work.
- class System
- {
- public:
- // Returns 'true' if system was properly initialized.
- static bool OVR_CDECL IsInitialized();
- // Initializes System core. Users can override memory implementation by passing
- // a different Allocator here.
- static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug));
- // De-initializes System more, finalizing the threading system and destroying
- // the global memory allocator.
- static void OVR_CDECL Destroy();
- };
- } // namespace OVR
- #endif
|