aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/OVR_DeviceImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'LibOVR/Src/OVR_DeviceImpl.h')
-rw-r--r--LibOVR/Src/OVR_DeviceImpl.h857
1 files changed, 432 insertions, 425 deletions
diff --git a/LibOVR/Src/OVR_DeviceImpl.h b/LibOVR/Src/OVR_DeviceImpl.h
index 8b7bf0a..2273d3d 100644
--- a/LibOVR/Src/OVR_DeviceImpl.h
+++ b/LibOVR/Src/OVR_DeviceImpl.h
@@ -1,425 +1,432 @@
-/************************************************************************************
-
-Filename : OVR_DeviceImpl.h
-Content : Partial back-end independent implementation of Device interfaces
-Created : October 10, 2012
-Authors : Michael Antonov
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-*************************************************************************************/
-
-#ifndef OVR_DeviceImpl_h
-#define OVR_DeviceImpl_h
-
-#include "OVR_Device.h"
-#include "Kernel/OVR_Atomic.h"
-#include "Kernel/OVR_Log.h"
-#include "Kernel/OVR_System.h"
-
-#include "Kernel/OVR_Threads.h"
-#include "OVR_ThreadCommandQueue.h"
-#include "OVR_HIDDevice.h"
-
-namespace OVR {
-
-class DeviceManagerImpl;
-class DeviceFactory;
-
-enum
-{
- Oculus_VendorId = 0x2833
-};
-
-//-------------------------------------------------------------------------------------
-// Globally shared Lock implementation used for MessageHandlers.
-
-class SharedLock
-{
-public:
-
- Lock* GetLockAddRef();
- void ReleaseLock(Lock* plock);
-
-private:
- Lock* toLock() { return (Lock*)Buffer; }
-
- // UseCount and max alignment.
- volatile int UseCount;
- UInt64 Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)];
-};
-
-
-// Wrapper for MessageHandler that includes synchronization logic.
-// References to MessageHandlers are organized in a list to allow for them to
-// easily removed with MessageHandler::RemoveAllHandlers.
-class MessageHandlerRef : public ListNode<MessageHandlerRef>
-{
-public:
- MessageHandlerRef(DeviceBase* device);
- ~MessageHandlerRef();
-
- void SetHandler(MessageHandler* hander);
-
- // Not-thread-safe version
- void SetHandler_NTS(MessageHandler* hander);
-
- void Call(const Message& msg)
- {
- Lock::Locker lockScope(pLock);
- if (pHandler)
- pHandler->OnMessage(msg);
- }
-
- Lock* GetLock() const { return pLock; }
-
- // GetHandler() is not thread safe if used out of order across threads; nothing can be done
- // about that.
- MessageHandler* GetHandler() const { return pHandler; }
- DeviceBase* GetDevice() const { return pDevice; }
-
-private:
- Lock* pLock; // Cached global handler lock.
- DeviceBase* pDevice;
- MessageHandler* pHandler;
-};
-
-
-
-//-------------------------------------------------------------------------------------
-
-// DeviceManagerLock is a synchronization lock used by DeviceManager for Devices
-// and is allocated separately for potentially longer lifetime.
-//
-// DeviceManagerLock is used for all of the following:
-// - Adding/removing devices
-// - Reporting manager lifetime (pManager != 0) for DeviceHandles
-// - Protecting device creation/shutdown.
-
-class DeviceManagerLock : public RefCountBase<DeviceManagerLock>
-{
-public:
- Lock CreateLock;
- DeviceManagerImpl* pManager;
-
- DeviceManagerLock() : pManager(0) { }
-};
-
-
-// DeviceCreateDesc provides all of the information needed to create any device, a derived
-// instance of this class is created by DeviceFactory during enumeration.
-// - DeviceCreateDesc may or may not be a part of DeviceManager::Devices list (check pNext != 0).
-// - Referenced and kept alive by DeviceHandle.
-
-class DeviceCreateDesc : public ListNode<DeviceCreateDesc>, public NewOverrideBase
-{
- void operator = (const DeviceCreateDesc&) { } // Assign not supported; suppress MSVC warning.
-public:
- DeviceCreateDesc(DeviceFactory* factory, DeviceType type)
- : pFactory(factory), Type(type), pLock(0), HandleCount(0), pDevice(0), Enumerated(true)
- {
- pNext = pPrev = 0;
- }
-
- virtual ~DeviceCreateDesc()
- {
- OVR_ASSERT(!pDevice);
- if (pNext)
- RemoveNode();
- }
-
- DeviceManagerImpl* GetManagerImpl() { return pLock->pManager; }
- Lock* GetLock() const { return &pLock->CreateLock; }
-
- // DeviceCreateDesc reference counting is tied to Devices list management,
- // see comments for HandleCount.
- void AddRef();
- void Release();
-
-
- // *** Device creation/matching Interface
-
-
- // Cloning copies us to an allocated object when new device is enumerated.
- virtual DeviceCreateDesc* Clone() const = 0;
- // Creates a new device instance without Initializing it; the
- // later is done my Initialize()/Shutdown() methods of the device itself.
- virtual DeviceBase* NewDeviceInstance() = 0;
- // Override to return device-specific info.
- virtual bool GetDeviceInfo(DeviceInfo* info) const = 0;
-
-
- enum MatchResult
- {
- Match_None,
- Match_Found,
- Match_Candidate
- };
-
- // Override to return Match_Found if descriptor matches our device.
- // Match_Candidate can be returned, with pcandicate update, if this may be a match
- // but more searching is necessary. If this is the case UpdateMatchedCandidate will be called.
- virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
- DeviceCreateDesc** pcandidate) const = 0;
-
- // Called for matched candidate after all potential matches are iterated.
- // Used to update HMDevice creation arguments from Sensor.
- // Optional return param 'newDeviceFlag' will be set to true if the
- // 'desc' refers to a new device; false, otherwise.
- // Return 'false' to create new object, 'true' if done with this argument.
- virtual bool UpdateMatchedCandidate(
- const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL)
- { OVR_UNUSED2(desc, newDeviceFlag); return false; }
-
- // Matches HID device to the descriptor.
- virtual bool MatchHIDDevice(const HIDDeviceDesc&) const { return false; }
-
- // Matches device by path.
- virtual bool MatchDevice(const String& /*path*/) { return false; }
-//protected:
- DeviceFactory* const pFactory;
- const DeviceType Type;
-
- // List in which this descriptor lives. pList->CreateLock required if added/removed.
- Ptr<DeviceManagerLock> pLock;
-
- // Strong references to us: Incremented by Device, DeviceHandles & Enumerators.
- // May be 0 if device not created and there are no handles.
- // Following transitions require pList->CreateLock:
- // {1 -> 0}: May delete & remove handle if no longer available.
- // {0 -> 1}: Device creation is only possible if manager is still alive.
- AtomicInt<UInt32> HandleCount;
- // If not null, points to our created device instance. Modified during lock only.
- DeviceBase* pDevice;
- // True if device is marked as available during enumeration.
- bool Enumerated;
-};
-
-
-
-// Common data present in the implementation of every DeviceBase.
-// Injected by DeviceImpl.
-class DeviceCommon
-{
-public:
- AtomicInt<UInt32> RefCount;
- Ptr<DeviceCreateDesc> pCreateDesc;
- Ptr<DeviceBase> pParent;
- MessageHandlerRef HandlerRef;
-
- DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent)
- : RefCount(1), pCreateDesc(createDesc), pParent(parent), HandlerRef(device)
- {
- }
-
- // Device reference counting delegates to Manager thread to actually kill devices.
- void DeviceAddRef();
- void DeviceRelease();
-
- Lock* GetLock() const { return pCreateDesc->GetLock(); }
-
- virtual bool Initialize(DeviceBase* parent) = 0;
- virtual void Shutdown() = 0;
-};
-
-
-//-------------------------------------------------------------------------------------
-// DeviceImpl address DeviceRecord implementation to a device base class B.
-// B must be derived form DeviceBase.
-
-template<class B>
-class DeviceImpl : public B, public DeviceCommon
-{
-public:
- DeviceImpl(DeviceCreateDesc* createDesc, DeviceBase* parent)
- : DeviceCommon(createDesc, getThis(), parent)
- {
- }
-
- // Convenience method to avoid manager access typecasts.
- DeviceManagerImpl* GetManagerImpl() const { return pCreateDesc->pLock->pManager; }
-
- // Inline to avoid warnings.
- DeviceImpl* getThis() { return this; }
-
- // Common implementation delegate to avoid virtual inheritance and dynamic casts.
- virtual DeviceCommon* getDeviceCommon() const { return (DeviceCommon*)this; }
-
- /*
- virtual void AddRef() { pCreateDesc->DeviceAddRef(); }
- virtual void Release() { pCreateDesc->DeviceRelease(); }
- virtual DeviceBase* GetParent() const { return pParent.GetPtr(); }
- virtual DeviceManager* GetManager() const { return pCreateDesc->pLock->pManager;}
- virtual void SetMessageHandler(MessageHandler* handler) { HanderRef.SetHandler(handler); }
- virtual MessageHandler* GetMessageHandler() const { return HanderRef.GetHandler(); }
- virtual DeviceType GetType() const { return pCreateDesc->Type; }
- virtual DeviceType GetType() const { return pCreateDesc->Type; }
- */
-};
-
-
-//-------------------------------------------------------------------------------------
-// ***** DeviceFactory
-
-// DeviceFactory is maintained in DeviceManager for each separately-enumerable
-// device type; factories allow separation of unrelated enumeration code.
-
-class DeviceFactory : public ListNode<DeviceFactory>, public NewOverrideBase
-{
-public:
-
- DeviceFactory() : pManager(0)
- {
- pNext = pPrev = 0;
- }
- virtual ~DeviceFactory() { }
-
- DeviceManagerImpl* GetManagerImpl() { return pManager; }
-
- // Notifiers called when we are added to/removed from a device.
- virtual bool AddedToManager(DeviceManagerImpl* manager)
- {
- OVR_ASSERT(pManager == 0);
- pManager = manager;
- return true;
- }
-
- virtual void RemovedFromManager()
- {
- pManager = 0;
- }
-
-
- // *** Device Enumeration/Creation Support
-
- // Passed to EnumerateDevices to be informed of every device detected.
- class EnumerateVisitor
- {
- public:
- virtual void Visit(const DeviceCreateDesc& createDesc) = 0;
- };
-
- // Enumerates factory devices by notifying EnumerateVisitor about every
- // device that is present.
- virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0;
-
- // Matches vendorId/productId pair with the factory; returns 'true'
- // if the factory can handle the device.
- virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
- {
- OVR_UNUSED2(vendorId, productId);
- return false;
- }
-
- // Detects the HID device and adds the DeviceCreateDesc into Devices list, if
- // the device belongs to this factory. Returns 'false', if not.
- virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
- {
- OVR_UNUSED2(pdevMgr, desc);
- return false;
- }
-
-protected:
- DeviceManagerImpl* pManager;
-};
-
-
-//-------------------------------------------------------------------------------------
-// ***** DeviceManagerImpl
-
-// DeviceManagerImpl is a partial default DeviceManager implementation that
-// maintains a list of devices and supports their enumeration.
-
-class DeviceManagerImpl : public DeviceImpl<OVR::DeviceManager>, public ThreadCommandQueue
-{
-public:
- DeviceManagerImpl();
- ~DeviceManagerImpl();
-
- // Constructor helper function to create Descriptor and manager lock during initialization.
- static DeviceCreateDesc* CreateManagerDesc();
-
- // DeviceManagerImpl provides partial implementation of Initialize/Shutdown that must
- // be called by the platform-specific derived class.
- virtual bool Initialize(DeviceBase* parent);
- virtual void Shutdown();
-
- // Override to return ThreadCommandQueue implementation used to post commands
- // to the background device manager thread (that must be created by Initialize).
- virtual ThreadCommandQueue* GetThreadQueue() = 0;
-
- // Returns the thread id of the DeviceManager.
- virtual ThreadId GetThreadId() const = 0;
-
- virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
-
-
- //
- void AddFactory(DeviceFactory* factory)
- {
- // This lock is only needed if we call AddFactory after manager thread creation.
- Lock::Locker scopeLock(GetLock());
- Factories.PushBack(factory);
- factory->AddedToManager(this);
- }
-
- void CallOnDeviceAdded(DeviceCreateDesc* desc)
- {
- HandlerRef.Call(MessageDeviceStatus(Message_DeviceAdded, this, DeviceHandle(desc)));
- }
- void CallOnDeviceRemoved(DeviceCreateDesc* desc)
- {
- HandlerRef.Call(MessageDeviceStatus(Message_DeviceRemoved, this, DeviceHandle(desc)));
- }
-
- // Helper to access Common data for a device.
- static DeviceCommon* GetDeviceCommon(DeviceBase* device)
- {
- return device->getDeviceCommon();
- }
-
-
- // Background-thread callbacks for DeviceCreation/Release. These
- DeviceBase* CreateDevice_MgrThread(DeviceCreateDesc* createDesc, DeviceBase* parent = 0);
- Void ReleaseDevice_MgrThread(DeviceBase* device);
-
-
- // Calls EnumerateDevices() on all factories
- virtual Void EnumerateAllFactoryDevices();
- // Enumerates devices for a particular factory.
- virtual Void EnumerateFactoryDevices(DeviceFactory* factory);
-
- virtual HIDDeviceManager* GetHIDDeviceManager() const
- {
- return HidDeviceManager;
- }
-
- // Adds device (DeviceCreateDesc*) into Devices. Returns NULL,
- // if unsuccessful or device is already in the list.
- virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc);
-
- // Finds a device descriptor by path and optional type.
- Ptr<DeviceCreateDesc> FindDevice(const String& path, DeviceType = Device_None);
-
- // Finds HID device by HIDDeviceDesc.
- Ptr<DeviceCreateDesc> FindHIDDevice(const HIDDeviceDesc&);
- void DetectHIDDevice(const HIDDeviceDesc&);
-
- // Manager Lock-protected list of devices.
- List<DeviceCreateDesc> Devices;
-
- // Factories used to detect and manage devices.
- List<DeviceFactory> Factories;
-
-protected:
- Ptr<HIDDeviceManager> HidDeviceManager;
-};
-
-
-} // namespace OVR
-
-#endif
+/************************************************************************************
+
+Filename : OVR_DeviceImpl.h
+Content : Partial back-end independent implementation of Device interfaces
+Created : October 10, 2012
+Authors : Michael Antonov
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Use of this software is subject to the terms of the Oculus license
+agreement provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+*************************************************************************************/
+
+#ifndef OVR_DeviceImpl_h
+#define OVR_DeviceImpl_h
+
+#include "OVR_Device.h"
+#include "Kernel/OVR_Atomic.h"
+#include "Kernel/OVR_Log.h"
+#include "Kernel/OVR_System.h"
+
+#include "Kernel/OVR_Threads.h"
+#include "OVR_ThreadCommandQueue.h"
+#include "OVR_HIDDevice.h"
+
+namespace OVR {
+
+class DeviceManagerImpl;
+class DeviceFactory;
+
+enum
+{
+ Oculus_VendorId = 0x2833
+};
+
+//-------------------------------------------------------------------------------------
+// Globally shared Lock implementation used for MessageHandlers.
+
+class SharedLock
+{
+public:
+ SharedLock() : UseCount(0) {}
+
+ Lock* GetLockAddRef();
+ void ReleaseLock(Lock* plock);
+
+private:
+ Lock* toLock() { return (Lock*)Buffer; }
+
+ // UseCount and max alignment.
+ volatile int UseCount;
+ UInt64 Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)];
+};
+
+
+// Wrapper for MessageHandler that includes synchronization logic.
+// References to MessageHandlers are organized in a list to allow for them to
+// easily removed with MessageHandler::RemoveAllHandlers.
+class MessageHandlerRef : public ListNode<MessageHandlerRef>
+{
+public:
+ MessageHandlerRef(DeviceBase* device);
+ ~MessageHandlerRef();
+
+ void SetHandler(MessageHandler* hander);
+
+ // Not-thread-safe version
+ void SetHandler_NTS(MessageHandler* hander);
+
+ void Call(const Message& msg)
+ {
+ Lock::Locker lockScope(pLock);
+ if (pHandler)
+ pHandler->OnMessage(msg);
+ }
+
+ Lock* GetLock() const { return pLock; }
+
+ // GetHandler() is not thread safe if used out of order across threads; nothing can be done
+ // about that.
+ MessageHandler* GetHandler() const { return pHandler; }
+ DeviceBase* GetDevice() const { return pDevice; }
+
+private:
+ Lock* pLock; // Cached global handler lock.
+ DeviceBase* pDevice;
+ MessageHandler* pHandler;
+};
+
+
+
+//-------------------------------------------------------------------------------------
+
+// DeviceManagerLock is a synchronization lock used by DeviceManager for Devices
+// and is allocated separately for potentially longer lifetime.
+//
+// DeviceManagerLock is used for all of the following:
+// - Adding/removing devices
+// - Reporting manager lifetime (pManager != 0) for DeviceHandles
+// - Protecting device creation/shutdown.
+
+class DeviceManagerLock : public RefCountBase<DeviceManagerLock>
+{
+public:
+ Lock CreateLock;
+ DeviceManagerImpl* pManager;
+
+ DeviceManagerLock() : pManager(0) { }
+};
+
+
+// DeviceCreateDesc provides all of the information needed to create any device, a derived
+// instance of this class is created by DeviceFactory during enumeration.
+// - DeviceCreateDesc may or may not be a part of DeviceManager::Devices list (check pNext != 0).
+// - Referenced and kept alive by DeviceHandle.
+
+class DeviceCreateDesc : public ListNode<DeviceCreateDesc>, public NewOverrideBase
+{
+ void operator = (const DeviceCreateDesc&) { } // Assign not supported; suppress MSVC warning.
+public:
+ DeviceCreateDesc(DeviceFactory* factory, DeviceType type)
+ : pFactory(factory), Type(type), pLock(0), HandleCount(0), pDevice(0), Enumerated(true)
+ {
+ pNext = pPrev = 0;
+ }
+
+ virtual ~DeviceCreateDesc()
+ {
+ OVR_ASSERT(!pDevice);
+ if (pNext)
+ RemoveNode();
+ }
+
+ DeviceManagerImpl* GetManagerImpl() const { return pLock->pManager; }
+ Lock* GetLock() const { return &pLock->CreateLock; }
+
+ // DeviceCreateDesc reference counting is tied to Devices list management,
+ // see comments for HandleCount.
+ void AddRef();
+ void Release();
+
+
+ // *** Device creation/matching Interface
+
+
+ // Cloning copies us to an allocated object when new device is enumerated.
+ virtual DeviceCreateDesc* Clone() const = 0;
+ // Creates a new device instance without Initializing it; the
+ // later is done my Initialize()/Shutdown() methods of the device itself.
+ virtual DeviceBase* NewDeviceInstance() = 0;
+ // Override to return device-specific info.
+ virtual bool GetDeviceInfo(DeviceInfo* info) const = 0;
+
+
+ enum MatchResult
+ {
+ Match_None,
+ Match_Found,
+ Match_Candidate
+ };
+
+ // Override to return Match_Found if descriptor matches our device.
+ // Match_Candidate can be returned, with pcandicate update, if this may be a match
+ // but more searching is necessary. If this is the case UpdateMatchedCandidate will be called.
+ virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
+ DeviceCreateDesc** pcandidate) const = 0;
+
+ // Called for matched candidate after all potential matches are iterated.
+ // Used to update HMDevice creation arguments from Sensor.
+ // Optional return param 'newDeviceFlag' will be set to true if the
+ // 'desc' refers to a new device; false, otherwise.
+ // Return 'false' to create new object, 'true' if done with this argument.
+ virtual bool UpdateMatchedCandidate(
+ const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL)
+ { OVR_UNUSED2(desc, newDeviceFlag); return false; }
+
+ // Matches HID device to the descriptor.
+ virtual bool MatchHIDDevice(const HIDDeviceDesc&) const { return false; }
+
+ // Matches device by path.
+ virtual bool MatchDevice(const String& /*path*/) { return false; }
+//protected:
+ DeviceFactory* const pFactory;
+ const DeviceType Type;
+
+ // List in which this descriptor lives. pList->CreateLock required if added/removed.
+ Ptr<DeviceManagerLock> pLock;
+
+ // Strong references to us: Incremented by Device, DeviceHandles & Enumerators.
+ // May be 0 if device not created and there are no handles.
+ // Following transitions require pList->CreateLock:
+ // {1 -> 0}: May delete & remove handle if no longer available.
+ // {0 -> 1}: Device creation is only possible if manager is still alive.
+ AtomicInt<UInt32> HandleCount;
+ // If not null, points to our created device instance. Modified during lock only.
+ DeviceBase* pDevice;
+ // True if device is marked as available during enumeration.
+ bool Enumerated;
+};
+
+
+
+// Common data present in the implementation of every DeviceBase.
+// Injected by DeviceImpl.
+class DeviceCommon
+{
+public:
+ AtomicInt<UInt32> RefCount;
+ Ptr<DeviceCreateDesc> pCreateDesc;
+ Ptr<DeviceBase> pParent;
+ MessageHandlerRef HandlerRef;
+
+ DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent)
+ : RefCount(1), pCreateDesc(createDesc), pParent(parent), HandlerRef(device)
+ {
+ }
+
+ // Device reference counting delegates to Manager thread to actually kill devices.
+ void DeviceAddRef();
+ void DeviceRelease();
+
+ Lock* GetLock() const { return pCreateDesc->GetLock(); }
+
+ virtual bool Initialize(DeviceBase* parent) = 0;
+ virtual void Shutdown() = 0;
+};
+
+
+//-------------------------------------------------------------------------------------
+// DeviceImpl address DeviceRecord implementation to a device base class B.
+// B must be derived form DeviceBase.
+
+template<class B>
+class DeviceImpl : public B, public DeviceCommon
+{
+public:
+ DeviceImpl(DeviceCreateDesc* createDesc, DeviceBase* parent)
+ : DeviceCommon(createDesc, getThis(), parent)
+ {
+ }
+
+ // Convenience method to avoid manager access typecasts.
+ DeviceManagerImpl* GetManagerImpl() const { return pCreateDesc->pLock->pManager; }
+
+ // Inline to avoid warnings.
+ DeviceImpl* getThis() { return this; }
+
+ // Common implementation delegate to avoid virtual inheritance and dynamic casts.
+ virtual DeviceCommon* getDeviceCommon() const { return (DeviceCommon*)this; }
+
+ /*
+ virtual void AddRef() { pCreateDesc->DeviceAddRef(); }
+ virtual void Release() { pCreateDesc->DeviceRelease(); }
+ virtual DeviceBase* GetParent() const { return pParent.GetPtr(); }
+ virtual DeviceManager* GetManager() const { return pCreateDesc->pLock->pManager;}
+ virtual void SetMessageHandler(MessageHandler* handler) { HanderRef.SetHandler(handler); }
+ virtual MessageHandler* GetMessageHandler() const { return HanderRef.GetHandler(); }
+ virtual DeviceType GetType() const { return pCreateDesc->Type; }
+ virtual DeviceType GetType() const { return pCreateDesc->Type; }
+ */
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** DeviceFactory
+
+// DeviceFactory is maintained in DeviceManager for each separately-enumerable
+// device type; factories allow separation of unrelated enumeration code.
+
+class DeviceFactory : public ListNode<DeviceFactory>, public NewOverrideBase
+{
+public:
+
+ DeviceFactory() : pManager(0)
+ {
+ pNext = pPrev = 0;
+ }
+ virtual ~DeviceFactory() { }
+
+ DeviceManagerImpl* GetManagerImpl() { return pManager; }
+
+ // Notifiers called when we are added to/removed from a device.
+ virtual bool AddedToManager(DeviceManagerImpl* manager)
+ {
+ OVR_ASSERT(pManager == 0);
+ pManager = manager;
+ return true;
+ }
+
+ virtual void RemovedFromManager()
+ {
+ pManager = 0;
+ }
+
+
+ // *** Device Enumeration/Creation Support
+
+ // Passed to EnumerateDevices to be informed of every device detected.
+ class EnumerateVisitor
+ {
+ public:
+ virtual void Visit(const DeviceCreateDesc& createDesc) = 0;
+ };
+
+ // Enumerates factory devices by notifying EnumerateVisitor about every
+ // device that is present.
+ virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0;
+
+ // Matches vendorId/productId pair with the factory; returns 'true'
+ // if the factory can handle the device.
+ virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
+ {
+ OVR_UNUSED2(vendorId, productId);
+ return false;
+ }
+
+ // Detects the HID device and adds the DeviceCreateDesc into Devices list, if
+ // the device belongs to this factory. Returns 'false', if not.
+ virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
+ {
+ OVR_UNUSED2(pdevMgr, desc);
+ return false;
+ }
+
+protected:
+ DeviceManagerImpl* pManager;
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** DeviceManagerImpl
+
+// DeviceManagerImpl is a partial default DeviceManager implementation that
+// maintains a list of devices and supports their enumeration.
+
+class DeviceManagerImpl : public DeviceImpl<OVR::DeviceManager>, public ThreadCommandQueue
+{
+public:
+ DeviceManagerImpl();
+ ~DeviceManagerImpl();
+
+ // Constructor helper function to create Descriptor and manager lock during initialization.
+ static DeviceCreateDesc* CreateManagerDesc();
+
+ // DeviceManagerImpl provides partial implementation of Initialize/Shutdown that must
+ // be called by the platform-specific derived class.
+ virtual bool Initialize(DeviceBase* parent);
+ virtual void Shutdown();
+
+
+ // Every DeviceManager has an associated profile manager, which us used to store
+ // user settings that may affect device behavior.
+ virtual ProfileManager* GetProfileManager() const { return pProfileManager.GetPtr(); }
+
+ // Override to return ThreadCommandQueue implementation used to post commands
+ // to the background device manager thread (that must be created by Initialize).
+ virtual ThreadCommandQueue* GetThreadQueue() = 0;
+
+ // Returns the thread id of the DeviceManager.
+ virtual ThreadId GetThreadId() const = 0;
+
+ virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
+
+
+ //
+ void AddFactory(DeviceFactory* factory)
+ {
+ // This lock is only needed if we call AddFactory after manager thread creation.
+ Lock::Locker scopeLock(GetLock());
+ Factories.PushBack(factory);
+ factory->AddedToManager(this);
+ }
+
+ void CallOnDeviceAdded(DeviceCreateDesc* desc)
+ {
+ HandlerRef.Call(MessageDeviceStatus(Message_DeviceAdded, this, DeviceHandle(desc)));
+ }
+ void CallOnDeviceRemoved(DeviceCreateDesc* desc)
+ {
+ HandlerRef.Call(MessageDeviceStatus(Message_DeviceRemoved, this, DeviceHandle(desc)));
+ }
+
+ // Helper to access Common data for a device.
+ static DeviceCommon* GetDeviceCommon(DeviceBase* device)
+ {
+ return device->getDeviceCommon();
+ }
+
+
+ // Background-thread callbacks for DeviceCreation/Release. These
+ DeviceBase* CreateDevice_MgrThread(DeviceCreateDesc* createDesc, DeviceBase* parent = 0);
+ Void ReleaseDevice_MgrThread(DeviceBase* device);
+
+
+ // Calls EnumerateDevices() on all factories
+ virtual Void EnumerateAllFactoryDevices();
+ // Enumerates devices for a particular factory.
+ virtual Void EnumerateFactoryDevices(DeviceFactory* factory);
+
+ virtual HIDDeviceManager* GetHIDDeviceManager() const
+ {
+ return HidDeviceManager;
+ }
+
+ // Adds device (DeviceCreateDesc*) into Devices. Returns NULL,
+ // if unsuccessful or device is already in the list.
+ virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc);
+
+ // Finds a device descriptor by path and optional type.
+ Ptr<DeviceCreateDesc> FindDevice(const String& path, DeviceType = Device_None);
+
+ // Finds HID device by HIDDeviceDesc.
+ Ptr<DeviceCreateDesc> FindHIDDevice(const HIDDeviceDesc&);
+ void DetectHIDDevice(const HIDDeviceDesc&);
+
+ // Manager Lock-protected list of devices.
+ List<DeviceCreateDesc> Devices;
+
+ // Factories used to detect and manage devices.
+ List<DeviceFactory> Factories;
+
+protected:
+ Ptr<HIDDeviceManager> HidDeviceManager;
+ Ptr<ProfileManager> pProfileManager;
+};
+
+
+} // namespace OVR
+
+#endif