Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OVR_DeviceImpl.h
Go to the documentation of this file.
1 /************************************************************************************
2 
3 Filename : OVR_DeviceImpl.h
4 Content : Partial back-end independent implementation of Device interfaces
5 Created : October 10, 2012
6 Authors : Michael Antonov
7 
8 Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
9 
10 Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
12 which is provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
14 
15 You may obtain a copy of the License at
16 
17 http://www.oculusvr.com/licenses/LICENSE-3.1
18 
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24 
25 *************************************************************************************/
26 
27 #ifndef OVR_DeviceImpl_h
28 #define OVR_DeviceImpl_h
29 
30 #include "OVR_Device.h"
31 #include "Kernel/OVR_Atomic.h"
32 #include "Kernel/OVR_Log.h"
33 #include "Kernel/OVR_System.h"
34 
35 #include "Kernel/OVR_Threads.h"
36 #include "OVR_ThreadCommandQueue.h"
37 #include "OVR_HIDDevice.h"
38 
39 namespace OVR {
40 
41 class DeviceManagerImpl;
42 class DeviceFactory;
43 
44 enum
45 {
46  Oculus_VendorId = 0x2833,
50 };
51 
52 
53 // Wrapper for MessageHandler that includes synchronization logic.
55 {
56  enum
57  {
59  };
60 public:
63 
64  bool HasHandlers() const { return HandlersCount > 0; };
65  void AddHandler(MessageHandler* handler);
66  // returns false if the handler is not found
67  bool RemoveHandler(MessageHandler* handler);
68  // Not-thread-safe version
69  void AddHandler_NTS(MessageHandler* handler);
70 
71  void Call(const Message& msg);
72 
73  Lock* GetLock() const { return pLock; }
74  DeviceBase* GetDevice() const { return pDevice; }
75 
76 private:
77  Lock* pLock; // Cached global handler lock.
79 
82 
83  bool removeHandler(int idx);
84 };
85 
86 
87 //-------------------------------------------------------------------------------------
88 
89 // DeviceManagerLock is a synchronization lock used by DeviceManager for Devices
90 // and is allocated separately for potentially longer lifetime.
91 //
92 // DeviceManagerLock is used for all of the following:
93 // - Adding/removing devices
94 // - Reporting manager lifetime (pManager != 0) for DeviceHandles
95 // - Protecting device creation/shutdown.
96 
97 class DeviceManagerLock : public RefCountBase<DeviceManagerLock>
98 {
99 public:
102 
104 };
105 
106 
107 // DeviceCreateDesc provides all of the information needed to create any device, a derived
108 // instance of this class is created by DeviceFactory during enumeration.
109 // - DeviceCreateDesc may or may not be a part of DeviceManager::Devices list (check pNext != 0).
110 // - Referenced and kept alive by DeviceHandle.
111 
112 class DeviceCreateDesc : public ListNode<DeviceCreateDesc>, public NewOverrideBase
113 {
114  void operator = (const DeviceCreateDesc&) { } // Assign not supported; suppress MSVC warning.
115 public:
117  : pFactory(factory), Type(type), pLock(0), HandleCount(0), pDevice(0), Enumerated(true)
118  {
119  pNext = pPrev = 0;
120  }
121 
123  {
125  if (pNext)
126  RemoveNode();
127  }
128 
129  DeviceManagerImpl* GetManagerImpl() const { return pLock->pManager; }
130  Lock* GetLock() const { return &pLock->CreateLock; }
131 
132  // DeviceCreateDesc reference counting is tied to Devices list management,
133  // see comments for HandleCount.
134  void AddRef();
135  void Release();
136 
137 
138  // *** Device creation/matching Interface
139 
140 
141  // Cloning copies us to an allocated object when new device is enumerated.
142  virtual DeviceCreateDesc* Clone() const = 0;
143  // Creates a new device instance without Initializing it; the
144  // later is done my Initialize()/Shutdown() methods of the device itself.
145  virtual DeviceBase* NewDeviceInstance() = 0;
146  // Override to return device-specific info.
147  virtual bool GetDeviceInfo(DeviceInfo* info) const = 0;
148 
149 
151  {
155  };
156 
157  // Override to return Match_Found if descriptor matches our device.
158  // Match_Candidate can be returned, with pcandicate update, if this may be a match
159  // but more searching is necessary. If this is the case UpdateMatchedCandidate will be called.
160  virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
161  DeviceCreateDesc** pcandidate) const = 0;
162 
163  // Called for matched candidate after all potential matches are iterated.
164  // Used to update HMDevice creation arguments from Sensor.
165  // Optional return param 'newDeviceFlag' will be set to true if the
166  // 'desc' refers to a new device; false, otherwise.
167  // Return 'false' to create new object, 'true' if done with this argument.
169  const DeviceCreateDesc& desc, bool* newDeviceFlag = NULL)
170  { OVR_UNUSED2(desc, newDeviceFlag); return false; }
171 
172  // Matches HID device to the descriptor.
173  virtual bool MatchHIDDevice(const HIDDeviceDesc&) const { return false; }
174 
175  // Matches device by path.
176  virtual bool MatchDevice(const String& /*path*/) { return false; }
177 //protected:
180 
181  // List in which this descriptor lives. pList->CreateLock required if added/removed.
183 
184  // Strong references to us: Incremented by Device, DeviceHandles & Enumerators.
185  // May be 0 if device not created and there are no handles.
186  // Following transitions require pList->CreateLock:
187  // {1 -> 0}: May delete & remove handle if no longer available.
188  // {0 -> 1}: Device creation is only possible if manager is still alive.
190  // If not null, points to our created device instance. Modified during lock only.
192  // True if device is marked as available during enumeration.
194 };
195 
196 
197 
198 // Common data present in the implementation of every DeviceBase.
199 // Injected by DeviceImpl.
201 {
202 public:
206  volatile bool ConnectedFlag;
208 
209  DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent)
210  : RefCount(1), pCreateDesc(createDesc), pParent(parent),
211  ConnectedFlag(true), HandlerRef(device)
212  {
213  }
214  virtual ~DeviceCommon() {}
215 
216  // Device reference counting delegates to Manager thread to actually kill devices.
217  void DeviceAddRef();
218  void DeviceRelease();
219 
220  Lock* GetLock() const { return pCreateDesc->GetLock(); }
221 
222  virtual bool Initialize(DeviceBase* parent) = 0;
223  virtual void Shutdown() = 0;
224 };
225 
226 
227 //-------------------------------------------------------------------------------------
228 // DeviceImpl address DeviceRecord implementation to a device base class B.
229 // B must be derived form DeviceBase.
230 
231 template<class B>
232 class DeviceImpl : public B, public DeviceCommon
233 {
234 public:
235  DeviceImpl(DeviceCreateDesc* createDesc, DeviceBase* parent)
236  : DeviceCommon(createDesc, getThis(), parent)
237  {
238  }
239 
240  // Convenience method to avoid manager access typecasts.
241  DeviceManagerImpl* GetManagerImpl() const { return pCreateDesc->pLock->pManager; }
242 
243  // Inline to avoid warnings.
244  DeviceImpl* getThis() { return this; }
245 
246  // Common implementation delegate to avoid virtual inheritance and dynamic casts.
247  virtual DeviceCommon* getDeviceCommon() const { return (DeviceCommon*)this; }
248 
249  /*
250  virtual void AddRef() { pCreateDesc->DeviceAddRef(); }
251  virtual void Release() { pCreateDesc->DeviceRelease(); }
252  virtual DeviceBase* GetParent() const { return pParent.GetPtr(); }
253  virtual DeviceManager* GetManager() const { return pCreateDesc->pLock->pManager;}
254  virtual void SetMessageHandler(MessageHandler* handler) { HanderRef.SetHandler(handler); }
255  virtual MessageHandler* GetMessageHandler() const { return HanderRef.GetHandler(); }
256  virtual DeviceType GetType() const { return pCreateDesc->Type; }
257  virtual DeviceType GetType() const { return pCreateDesc->Type; }
258  */
259 };
260 
261 
262 //-------------------------------------------------------------------------------------
263 // ***** DeviceFactory
264 
265 // DeviceFactory is maintained in DeviceManager for each separately-enumerable
266 // device type; factories allow separation of unrelated enumeration code.
267 
268 class DeviceFactory : public ListNode<DeviceFactory>, public NewOverrideBase
269 {
270 public:
271 
273  {
274  pNext = pPrev = 0;
275  }
276  virtual ~DeviceFactory() { }
277 
279 
280  // Notifiers called when we are added to/removed from a device.
281  virtual bool AddedToManager(DeviceManagerImpl* manager)
282  {
283  OVR_ASSERT(pManager == 0);
284  pManager = manager;
285  return true;
286  }
287 
288  virtual void RemovedFromManager()
289  {
290  pManager = 0;
291  }
292 
293 
294  // *** Device Enumeration/Creation Support
295 
296  // Passed to EnumerateDevices to be informed of every device detected.
298  {
299  public:
300  virtual void Visit(const DeviceCreateDesc& createDesc) = 0;
301  };
302 
303  // Enumerates factory devices by notifying EnumerateVisitor about every
304  // device that is present.
305  virtual void EnumerateDevices(EnumerateVisitor& visitor) = 0;
306 
307  // Matches vendorId/productId pair with the factory; returns 'true'
308  // if the factory can handle the device.
309  virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
310  {
311  OVR_UNUSED2(vendorId, productId);
312  return false;
313  }
314 
315  // Detects the HID device and adds the DeviceCreateDesc into Devices list, if
316  // the device belongs to this factory. Returns 'false', if not.
317  virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
318  {
319  OVR_UNUSED2(pdevMgr, desc);
320  return false;
321  }
322 
323 protected:
325 };
326 
327 
328 //-------------------------------------------------------------------------------------
329 // ***** DeviceManagerImpl
330 
331 // DeviceManagerImpl is a partial default DeviceManager implementation that
332 // maintains a list of devices and supports their enumeration.
333 
334 class DeviceManagerImpl : public DeviceImpl<OVR::DeviceManager>, public ThreadCommandQueue
335 {
336 public:
339 
340  // Constructor helper function to create Descriptor and manager lock during initialization.
342 
343  // DeviceManagerImpl provides partial implementation of Initialize/Shutdown that must
344  // be called by the platform-specific derived class.
345  virtual bool Initialize(DeviceBase* parent);
346  virtual void Shutdown();
347 
348 
349  // Every DeviceManager has an associated profile manager, which is used to store
350  // user settings that may affect device behavior.
351  virtual ProfileManager* GetProfileManager() const { return pProfileManager.GetPtr(); }
352 
353  // Override to return ThreadCommandQueue implementation used to post commands
354  // to the background device manager thread (that must be created by Initialize).
355  virtual ThreadCommandQueue* GetThreadQueue() = 0;
356 
357  // Returns the thread id of the DeviceManager.
358  virtual ThreadId GetThreadId() const = 0;
359 
361 
362 
363  //
364  void AddFactory(DeviceFactory* factory)
365  {
366  // This lock is only needed if we call AddFactory after manager thread creation.
367  Lock::Locker scopeLock(GetLock());
368  Factories.PushBack(factory);
369  factory->AddedToManager(this);
370  }
371 
373  {
375  }
377  {
379  }
380 
381  // Helper to access Common data for a device.
383  {
384  return device->getDeviceCommon();
385  }
386 
387 
388  // Background-thread callbacks for DeviceCreation/Release. These
391 
392 
393  // Calls EnumerateDevices() on all factories
395  // Enumerates devices for a particular factory.
396  virtual Void EnumerateFactoryDevices(DeviceFactory* factory);
397 
399  {
400  return HidDeviceManager;
401  }
402 
403  // Adds device (DeviceCreateDesc*) into Devices. Returns NULL,
404  // if unsuccessful or device is already in the list.
406 
407  // Finds a device descriptor by path and optional type.
409 
410  // Finds HID device by HIDDeviceDesc.
411  Ptr<DeviceCreateDesc> FindHIDDevice(const HIDDeviceDesc&, bool created);
412  void DetectHIDDevice(const HIDDeviceDesc&);
413 
414  // Manager Lock-protected list of devices.
416 
417  // Factories used to detect and manage devices.
419 
420 protected:
423 };
424 
425 
426 } // namespace OVR
427 
428 #endif
Lock * GetLock() const
virtual bool MatchHIDDevice(const HIDDeviceDesc &) const
void CallOnDeviceRemoved(DeviceCreateDesc *desc)
DeviceImpl(DeviceCreateDesc *createDesc, DeviceBase *parent)
DeviceFactory *const pFactory
bool RemoveHandler(MessageHandler *handler)
virtual ThreadId GetThreadId() const =0
Void ReleaseDevice_MgrThread(DeviceBase *device)
DeviceCommon(DeviceCreateDesc *createDesc, DeviceBase *device, DeviceBase *parent)
DeviceManagerImpl * GetManagerImpl()
virtual bool Initialize(DeviceBase *parent)=0
void AddFactory(DeviceFactory *factory)
static DeviceCommon * GetDeviceCommon(DeviceBase *device)
virtual Ptr< DeviceCreateDesc > AddDevice_NeedsLock(const DeviceCreateDesc &createDesc)
#define NULL
virtual ThreadCommandQueue * GetThreadQueue()=0
virtual ~DeviceFactory()
MessageHandler * pHandlers[MaxHandlersCount]
Ptr< DeviceCreateDesc > pCreateDesc
virtual ~DeviceCommon()
DeviceImpl * getThis()
Ptr< DeviceCreateDesc > FindDevice(const String &path, DeviceType=Device_None)
uint16_t UInt16
Definition: OVR_Types.h:251
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
Ptr< DeviceBase > pParent
Ptr< DeviceManagerLock > pLock
Lock * GetLock() const
void operator=(const DeviceCreateDesc &)
void CallOnDeviceAdded(DeviceCreateDesc *desc)
virtual MatchResult MatchDevice(const DeviceCreateDesc &other, DeviceCreateDesc **pcandidate) const =0
void AddHandler_NTS(MessageHandler *handler)
virtual bool UpdateMatchedCandidate(const DeviceCreateDesc &desc, bool *newDeviceFlag=NULL)
bool HasHandlers() const
virtual DeviceEnumerator EnumerateDevicesEx(const DeviceEnumerationArgs &args)
Ptr< ProfileManager > pProfileManager
DeviceManagerImpl * GetManagerImpl() const
void AddHandler(MessageHandler *handler)
const DeviceType Type
virtual bool DetectHIDDevice(DeviceManager *pdevMgr, const HIDDeviceDesc &desc)
DeviceManagerImpl * pManager
virtual DeviceBase * NewDeviceInstance()=0
Ptr< DeviceCreateDesc > FindHIDDevice(const HIDDeviceDesc &, bool created)
virtual bool GetDeviceInfo(DeviceInfo *info) const =0
Lock * GetLock() const
#define OVR_ASSERT(p)
MessageHandlerRef(DeviceBase *device)
virtual void Visit(const DeviceCreateDesc &createDesc)=0
virtual Void EnumerateFactoryDevices(DeviceFactory *factory)
List< DeviceFactory > Factories
MessageHandlerRef HandlerRef
List< DeviceCreateDesc > Devices
virtual void Shutdown()=0
virtual HIDDeviceManager * GetHIDDeviceManager() const
DeviceCreateDesc(DeviceFactory *factory, DeviceType type)
AtomicInt< UInt32 > HandleCount
DeviceManagerImpl * GetManagerImpl() const
Ptr< HIDDeviceManager > HidDeviceManager
void * ThreadId
Definition: OVR_Threads.h:180
virtual bool MatchDevice(const String &)
virtual DeviceCommon * getDeviceCommon() const
DeviceManagerImpl * pManager
friend class DeviceHandle
Definition: OVR_Device.h:102
virtual ProfileManager * GetProfileManager() const
virtual DeviceCreateDesc * Clone() const =0
virtual DeviceCommon * getDeviceCommon() const =0
void DetectHIDDevice(const HIDDeviceDesc &)
virtual Void EnumerateAllFactoryDevices()
virtual void RemovedFromManager()
void Call(const Message &msg)
DeviceBase * GetDevice() const
virtual void EnumerateDevices(EnumerateVisitor &visitor)=0
DeviceBase * CreateDevice_MgrThread(DeviceCreateDesc *createDesc, DeviceBase *parent=0)
static DeviceCreateDesc * CreateManagerDesc()
volatile bool ConnectedFlag
AtomicInt< UInt32 > RefCount
#define OVR_UNUSED2(a1, a2)
virtual bool AddedToManager(DeviceManagerImpl *manager)
virtual bool Initialize(DeviceBase *parent)