OVR_DeviceImpl.h
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 Filename    :   OVR_DeviceImpl.h
00004 Content     :   Partial back-end independent implementation of Device interfaces
00005 Created     :   October 10, 2012
00006 Authors     :   Michael Antonov
00007 
00008 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00009 
00010 Use of this software is subject to the terms of the Oculus license
00011 agreement provided at the time of installation or download, or which
00012 otherwise accompanies this software in either electronic or hard copy form.
00013 
00014 *************************************************************************************/
00015 
00016 #ifndef OVR_DeviceImpl_h
00017 #define OVR_DeviceImpl_h
00018 
00019 #include "OVR_Device.h"
00020 #include "Kernel/OVR_Atomic.h"
00021 #include "Kernel/OVR_Log.h"
00022 #include "Kernel/OVR_System.h"
00023 
00024 #include "Kernel/OVR_Threads.h"
00025 #include "OVR_ThreadCommandQueue.h"
00026 #include "OVR_HIDDevice.h"
00027 
00028 namespace OVR {
00029     
00030 class DeviceManagerImpl;
00031 class DeviceFactory;
00032 
00033 enum
00034 {
00035     Oculus_VendorId = 0x2833
00036 };
00037 
00038 //-------------------------------------------------------------------------------------
00039 // Globally shared Lock implementation used for MessageHandlers.
00040 
00041 class SharedLock
00042 {    
00043 public:
00044     SharedLock() : UseCount(0) {}
00045 
00046     Lock* GetLockAddRef();
00047     void  ReleaseLock(Lock* plock);
00048    
00049 private:
00050     Lock* toLock() { return (Lock*)Buffer; }
00051 
00052     // UseCount and max alignment.
00053     volatile int    UseCount;
00054     UInt64          Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)];
00055 };
00056 
00057 
00058 // Wrapper for MessageHandler that includes synchronization logic.
00059 // References to MessageHandlers are organized in a list to allow for them to
00060 // easily removed with MessageHandler::RemoveAllHandlers.
00061 class MessageHandlerRef : public ListNode<MessageHandlerRef>
00062 {    
00063 public:
00064     MessageHandlerRef(DeviceBase* device);
00065     ~MessageHandlerRef();
00066 
00067     void SetHandler(MessageHandler* hander);
00068 
00069     // Not-thread-safe version
00070     void SetHandler_NTS(MessageHandler* hander);
00071     
00072     void Call(const Message& msg)
00073     {
00074         Lock::Locker lockScope(pLock);
00075         if (pHandler)
00076             pHandler->OnMessage(msg);
00077     }
00078 
00079     Lock*           GetLock() const { return pLock; }
00080 
00081     // GetHandler() is not thread safe if used out of order across threads; nothing can be done
00082     // about that.
00083     MessageHandler* GetHandler() const { return pHandler; }
00084     DeviceBase*     GetDevice() const  { return pDevice; }
00085 
00086 private:
00087     Lock*           pLock;   // Cached global handler lock.
00088     DeviceBase*     pDevice;
00089     MessageHandler* pHandler;
00090 };
00091 
00092 
00093 
00094 //-------------------------------------------------------------------------------------
00095 
00096 // DeviceManagerLock is a synchronization lock used by DeviceManager for Devices
00097 // and is allocated separately for potentially longer lifetime.
00098 // 
00099 // DeviceManagerLock is used for all of the following:
00100 //  - Adding/removing devices
00101 //  - Reporting manager lifetime (pManager != 0) for DeviceHandles
00102 //  - Protecting device creation/shutdown.
00103 
00104 class DeviceManagerLock : public RefCountBase<DeviceManagerLock>
00105 {
00106 public:
00107     Lock                CreateLock;
00108     DeviceManagerImpl*  pManager;
00109 
00110     DeviceManagerLock() : pManager(0) { }
00111 };
00112 
00113 
00114 // DeviceCreateDesc provides all of the information needed to create any device, a derived
00115 // instance of this class is created by DeviceFactory during enumeration.
00116 //   - DeviceCreateDesc may or may not be a part of DeviceManager::Devices list (check pNext != 0).
00117 //   - Referenced and kept alive by DeviceHandle.
00118 
00119 class DeviceCreateDesc : public ListNode<DeviceCreateDesc>, public NewOverrideBase
00120 {    
00121     void operator = (const DeviceCreateDesc&) { } // Assign not supported; suppress MSVC warning.
00122 public:
00123     DeviceCreateDesc(DeviceFactory* factory, DeviceType type)
00124         : pFactory(factory), Type(type), pLock(0), HandleCount(0), pDevice(0), Enumerated(true)
00125     {
00126         pNext = pPrev = 0;
00127     }
00128 
00129     virtual ~DeviceCreateDesc()
00130     {
00131         OVR_ASSERT(!pDevice);
00132         if (pNext)        
00133             RemoveNode();
00134     }
00135 
00136     DeviceManagerImpl* GetManagerImpl() const { return pLock->pManager; }
00137     Lock*              GetLock() const        { return &pLock->CreateLock; }
00138 
00139     // DeviceCreateDesc reference counting is tied to Devices list management,
00140     // see comments for HandleCount.
00141     void AddRef();
00142     void Release();
00143 
00144 
00145     // *** Device creation/matching Interface
00146 
00147 
00148     // Cloning copies us to an allocated object when new device is enumerated.
00149     virtual DeviceCreateDesc* Clone() const = 0;
00150     // Creates a new device instance without Initializing it; the
00151     // later is done my Initialize()/Shutdown() methods of the device itself.
00152     virtual DeviceBase*       NewDeviceInstance() = 0;
00153     // Override to return device-specific info.
00154     virtual bool              GetDeviceInfo(DeviceInfo* info) const = 0;
00155 
00156 
00157     enum MatchResult
00158     {
00159         Match_None,
00160         Match_Found,
00161         Match_Candidate
00162     };
00163 
00164     // Override to return Match_Found if descriptor matches our device.
00165     // Match_Candidate can be returned, with pcandicate update, if this may be a match
00166     // but more searching is necessary. If this is the case UpdateMatchedCandidate will be called.
00167     virtual MatchResult       MatchDevice(const DeviceCreateDesc& other,
00168                                           DeviceCreateDesc** pcandidate) const = 0;
00169     
00170     // Called for matched candidate after all potential matches are iterated.
00171     // Used to update HMDevice creation arguments from Sensor.
00172     // Optional return param 'newDeviceFlag' will be set to true if the 
00173     // 'desc' refers to a new device; false, otherwise.
00174     // Return 'false' to create new object, 'true' if done with this argument.
00175     virtual bool              UpdateMatchedCandidate(
00176         const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL) 
00177     { OVR_UNUSED2(desc, newDeviceFlag); return false; }
00178 
00179     // Matches HID device to the descriptor.
00180     virtual bool              MatchHIDDevice(const HIDDeviceDesc&) const { return false; }
00181 
00182     // Matches device by path.
00183     virtual bool              MatchDevice(const String& /*path*/) { return false; }
00184 //protected:
00185     DeviceFactory* const        pFactory;
00186     const DeviceType            Type;
00187 
00188     // List in which this descriptor lives. pList->CreateLock required if added/removed.
00189     Ptr<DeviceManagerLock>      pLock;    
00190 
00191     // Strong references to us: Incremented by Device, DeviceHandles & Enumerators.
00192     // May be 0 if device not created and there are no handles.
00193     // Following transitions require pList->CreateLock:
00194     //  {1 -> 0}: May delete & remove handle if no longer available.
00195     //  {0 -> 1}: Device creation is only possible if manager is still alive.
00196     AtomicInt<UInt32>           HandleCount;
00197     // If not null, points to our created device instance. Modified during lock only.
00198     DeviceBase*                 pDevice;
00199     // True if device is marked as available during enumeration.
00200     bool                        Enumerated;
00201 };
00202 
00203 
00204 
00205 // Common data present in the implementation of every DeviceBase.
00206 // Injected by DeviceImpl.
00207 class DeviceCommon
00208 {
00209 public:
00210     AtomicInt<UInt32>      RefCount;
00211     Ptr<DeviceCreateDesc>  pCreateDesc;
00212     Ptr<DeviceBase>        pParent;
00213     MessageHandlerRef      HandlerRef;
00214 
00215     DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent)
00216         : RefCount(1), pCreateDesc(createDesc), pParent(parent), HandlerRef(device)
00217     {
00218     }
00219 
00220     // Device reference counting delegates to Manager thread to actually kill devices.
00221     void DeviceAddRef();
00222     void DeviceRelease();
00223 
00224     Lock* GetLock() const { return pCreateDesc->GetLock(); }
00225 
00226     virtual bool Initialize(DeviceBase* parent) = 0;
00227     virtual void Shutdown() = 0;
00228 };
00229 
00230 
00231 //-------------------------------------------------------------------------------------
00232 // DeviceImpl address DeviceRecord implementation to a device base class B.
00233 // B must be derived form DeviceBase.
00234 
00235 template<class B>
00236 class DeviceImpl : public B, public DeviceCommon
00237 {
00238 public:
00239     DeviceImpl(DeviceCreateDesc* createDesc, DeviceBase* parent)
00240         : DeviceCommon(createDesc, getThis(), parent)        
00241     {
00242     }
00243 
00244         // Convenience method to avoid manager access typecasts.
00245     DeviceManagerImpl*  GetManagerImpl() const      { return pCreateDesc->pLock->pManager; }
00246 
00247     // Inline to avoid warnings.
00248     DeviceImpl*         getThis()                   { return this; }
00249 
00250     // Common implementation delegate to avoid virtual inheritance and dynamic casts.
00251     virtual DeviceCommon* getDeviceCommon() const   { return (DeviceCommon*)this; }
00252 
00253     /*
00254     virtual void            AddRef()                                   { pCreateDesc->DeviceAddRef(); }
00255     virtual void            Release()                                  { pCreateDesc->DeviceRelease(); }
00256     virtual DeviceBase*     GetParent() const                          { return pParent.GetPtr(); } 
00257     virtual DeviceManager*  GetManager() const                         { return pCreateDesc->pLock->pManager;}
00258     virtual void            SetMessageHandler(MessageHandler* handler) { HanderRef.SetHandler(handler); }
00259     virtual MessageHandler* GetMessageHandler() const                  { return HanderRef.GetHandler(); }
00260     virtual DeviceType      GetType() const                            { return pCreateDesc->Type; }
00261     virtual DeviceType      GetType() const                            { return pCreateDesc->Type; }
00262     */
00263 };
00264 
00265 
00266 //-------------------------------------------------------------------------------------
00267 // ***** DeviceFactory
00268 
00269 // DeviceFactory is maintained in DeviceManager for each separately-enumerable
00270 // device type; factories allow separation of unrelated enumeration code.
00271 
00272 class DeviceFactory : public ListNode<DeviceFactory>, public NewOverrideBase
00273 {    
00274 public:
00275 
00276     DeviceFactory() : pManager(0)
00277     {
00278         pNext = pPrev = 0;
00279     }
00280     virtual ~DeviceFactory() { }
00281 
00282     DeviceManagerImpl* GetManagerImpl() { return pManager; }
00283 
00284     // Notifiers called when we are added to/removed from a device.
00285     virtual bool AddedToManager(DeviceManagerImpl* manager)
00286     {
00287         OVR_ASSERT(pManager == 0);
00288         pManager = manager;
00289         return true;
00290     }
00291 
00292     virtual void RemovedFromManager()
00293     {
00294         pManager = 0;
00295     }
00296 
00297 
00298     // *** Device Enumeration/Creation Support
00299     
00300     // Passed to EnumerateDevices to be informed of every device detected.
00301     class EnumerateVisitor
00302     {
00303     public:        
00304         virtual void Visit(const DeviceCreateDesc& createDesc) = 0;
00305     };
00306 
00307     // Enumerates factory devices by notifying EnumerateVisitor about every
00308     // device that is present.
00309     virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0;
00310 
00311     // Matches vendorId/productId pair with the factory; returns 'true'
00312     // if the factory can handle the device.
00313     virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
00314     {
00315         OVR_UNUSED2(vendorId, productId);
00316         return false;
00317     }
00318 
00319     // Detects the HID device and adds the DeviceCreateDesc into Devices list, if
00320     // the device belongs to this factory. Returns 'false', if not.
00321     virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
00322     {
00323         OVR_UNUSED2(pdevMgr, desc);
00324         return false;
00325     }
00326     
00327 protected:
00328     DeviceManagerImpl* pManager;
00329 };
00330 
00331 
00332 //-------------------------------------------------------------------------------------
00333 // ***** DeviceManagerImpl
00334 
00335 // DeviceManagerImpl is a partial default DeviceManager implementation that
00336 // maintains a list of devices and supports their enumeration.
00337 
00338 class DeviceManagerImpl : public DeviceImpl<OVR::DeviceManager>, public ThreadCommandQueue
00339 {
00340 public:
00341     DeviceManagerImpl();
00342     ~DeviceManagerImpl();
00343 
00344     // Constructor helper function to create Descriptor and manager lock during initialization.
00345     static DeviceCreateDesc* CreateManagerDesc();
00346 
00347     // DeviceManagerImpl provides partial implementation of Initialize/Shutdown that must
00348     // be called by the platform-specific derived class.
00349     virtual bool Initialize(DeviceBase* parent);
00350     virtual void Shutdown();
00351 
00352 
00353     // Every DeviceManager has an associated profile manager, which us used to store
00354     // user settings that may affect device behavior. 
00355     virtual ProfileManager* GetProfileManager() const { return pProfileManager.GetPtr(); }
00356 
00357     // Override to return ThreadCommandQueue implementation used to post commands
00358     // to the background device manager thread (that must be created by Initialize).
00359     virtual ThreadCommandQueue* GetThreadQueue() = 0;
00360 
00361     // Returns the thread id of the DeviceManager.
00362     virtual ThreadId GetThreadId() const = 0;
00363 
00364     virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
00365 
00366 
00367     // 
00368     void AddFactory(DeviceFactory* factory)
00369     {
00370         // This lock is only needed if we call AddFactory after manager thread creation.
00371         Lock::Locker scopeLock(GetLock());
00372         Factories.PushBack(factory);
00373         factory->AddedToManager(this);        
00374     }
00375 
00376     void CallOnDeviceAdded(DeviceCreateDesc* desc)
00377     {
00378         HandlerRef.Call(MessageDeviceStatus(Message_DeviceAdded, this, DeviceHandle(desc)));
00379     }
00380     void CallOnDeviceRemoved(DeviceCreateDesc* desc)
00381     {
00382         HandlerRef.Call(MessageDeviceStatus(Message_DeviceRemoved, this, DeviceHandle(desc)));
00383     }
00384 
00385     // Helper to access Common data for a device.
00386     static DeviceCommon* GetDeviceCommon(DeviceBase* device)
00387     {
00388         return device->getDeviceCommon();
00389     }
00390 
00391 
00392     // Background-thread callbacks for DeviceCreation/Release. These
00393     DeviceBase* CreateDevice_MgrThread(DeviceCreateDesc* createDesc, DeviceBase* parent = 0);
00394     Void        ReleaseDevice_MgrThread(DeviceBase* device);
00395 
00396    
00397     // Calls EnumerateDevices() on all factories
00398     virtual Void EnumerateAllFactoryDevices();
00399     // Enumerates devices for a particular factory.
00400     virtual Void EnumerateFactoryDevices(DeviceFactory* factory);
00401 
00402     virtual HIDDeviceManager* GetHIDDeviceManager() const
00403     {
00404         return HidDeviceManager;
00405     }
00406 
00407     // Adds device (DeviceCreateDesc*) into Devices. Returns NULL, 
00408     // if unsuccessful or device is already in the list.
00409     virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc);
00410     
00411     // Finds a device descriptor by path and optional type.
00412     Ptr<DeviceCreateDesc> FindDevice(const String& path, DeviceType = Device_None);
00413 
00414     // Finds HID device by HIDDeviceDesc.
00415     Ptr<DeviceCreateDesc> FindHIDDevice(const HIDDeviceDesc&);
00416     void DetectHIDDevice(const HIDDeviceDesc&);
00417 
00418     // Manager Lock-protected list of devices.
00419     List<DeviceCreateDesc>  Devices;    
00420 
00421     // Factories used to detect and manage devices.
00422     List<DeviceFactory>     Factories;
00423 
00424 protected:
00425     Ptr<HIDDeviceManager>   HidDeviceManager;
00426     Ptr<ProfileManager>     pProfileManager;
00427 };
00428 
00429 
00430 } // namespace OVR
00431 
00432 #endif


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:18