diff options
Diffstat (limited to 'LibOVR/Src/OVR_Win32_DeviceManager.cpp')
-rw-r--r-- | LibOVR/Src/OVR_Win32_DeviceManager.cpp | 434 |
1 files changed, 0 insertions, 434 deletions
diff --git a/LibOVR/Src/OVR_Win32_DeviceManager.cpp b/LibOVR/Src/OVR_Win32_DeviceManager.cpp deleted file mode 100644 index 3fd25b2..0000000 --- a/LibOVR/Src/OVR_Win32_DeviceManager.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Win32_DeviceManager.cpp -Content : Win32 implementation of DeviceManager. -Created : September 21, 2012 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (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.1 - -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. - -*************************************************************************************/ - -#include "OVR_Win32_DeviceManager.h" - -// Sensor & HMD Factories -#include "OVR_SensorImpl.h" -#include "OVR_LatencyTestImpl.h" -#include "OVR_Win32_HMDDevice.h" -#include "OVR_Win32_DeviceStatus.h" -#include "OVR_Win32_HIDDevice.h" - -#include "Kernel/OVR_Timer.h" -#include "Kernel/OVR_Std.h" -#include "Kernel/OVR_Log.h" - -DWORD Debug_WaitedObjectCount = 0; - -namespace OVR { namespace Win32 { - - -//------------------------------------------------------------------------------------- -// **** Win32::DeviceManager - -DeviceManager::DeviceManager() -{ - HidDeviceManager = *HIDDeviceManager::CreateInternal(this); -} - -DeviceManager::~DeviceManager() -{ - // make sure Shutdown was called. - OVR_ASSERT(!pThread); -} - -bool DeviceManager::Initialize(DeviceBase*) -{ - if (!DeviceManagerImpl::Initialize(0)) - return false; - - pThread = *new DeviceManagerThread(this); - if (!pThread || !pThread->Start()) - return false; - - pCreateDesc->pDevice = this; - LogText("OVR::DeviceManager - initialized.\n"); - return true; -} - -void DeviceManager::Shutdown() -{ - LogText("OVR::DeviceManager - shutting down.\n"); - - // Set Manager shutdown marker variable; this prevents - // any existing DeviceHandle objects from accessing device. - pCreateDesc->pLock->pManager = 0; - - // Push for thread shutdown *WITH NO WAIT*. - // This will have the following effect: - // - Exit command will get enqueued, which will be executed later on the thread itself. - // - Beyond this point, this DeviceManager object may be deleted by our caller. - // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will - // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued - // after pManager is null. - // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last - // reference to the thread object. - pThread->PushExitCommand(false); - pThread->DetachDeviceManager(); - pThread.Clear(); - - DeviceManagerImpl::Shutdown(); -} - -ThreadCommandQueue* DeviceManager::GetThreadQueue() -{ - return pThread; -} - -bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const -{ - if ((info->InfoClassType != Device_Manager) && - (info->InfoClassType != Device_None)) - return false; - - info->Type = Device_Manager; - info->Version = 0; - info->ProductName = "DeviceManager"; - info->Manufacturer = "Oculus VR, Inc."; - return true; -} - -DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args) -{ - // TBD: Can this be avoided in the future, once proper device notification is in place? - if (GetThreadId() != OVR::GetCurrentThreadId()) - { - pThread->PushCall((DeviceManagerImpl*)this, - &DeviceManager::EnumerateAllFactoryDevices, true); - } - else - DeviceManager::EnumerateAllFactoryDevices(); - - return DeviceManagerImpl::EnumerateDevicesEx(args); -} - -ThreadId DeviceManager::GetThreadId() const -{ - return pThread->GetThreadId(); -} - -bool DeviceManager::GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const -{ - if (GetHIDDeviceManager()) - return static_cast<HIDDeviceManager*>(GetHIDDeviceManager())->GetHIDDeviceDesc(path, pdevDesc); - return false; -} - - -//------------------------------------------------------------------------------------- -// ***** DeviceManager Thread - -DeviceManagerThread::DeviceManagerThread(DeviceManager* pdevMgr) - : Thread(ThreadStackSize), hCommandEvent(0), pDeviceMgr(pdevMgr) -{ - // Create a non-signaled manual-reset event. - hCommandEvent = ::CreateEvent(0, TRUE, FALSE, 0); - if (!hCommandEvent) - return; - - // Must add event before starting. - AddOverlappedEvent(0, hCommandEvent); - - // Create device messages object. - pStatusObject = *new DeviceStatus(this); -} - -DeviceManagerThread::~DeviceManagerThread() -{ - // Remove overlapped event [0], after thread service exit. - if (hCommandEvent) - { - RemoveOverlappedEvent(0, hCommandEvent); - ::CloseHandle(hCommandEvent); - hCommandEvent = 0; - } -} - -int DeviceManagerThread::Run() -{ - ThreadCommand::PopBuffer command; - - SetThreadName("OVR::DeviceManagerThread"); - LogText("OVR::DeviceManagerThread - running (ThreadId=0x%X).\n", GetThreadId()); - - if (!pStatusObject->Initialize()) - { - LogText("OVR::DeviceManagerThread - failed to initialize MessageObject.\n"); - } - - while(!IsExiting()) - { - // PopCommand will reset event on empty queue. - if (PopCommand(&command)) - { - command.Execute(); - } - else - { - DWORD eventIndex = 0; - do { - UPInt numberOfWaitHandles = WaitHandles.GetSize(); - Debug_WaitedObjectCount = (DWORD)numberOfWaitHandles; - - DWORD waitMs = INFINITE; - - // If devices have time-dependent logic registered, get the longest wait - // allowed based on current ticks. - if (!TicksNotifiers.IsEmpty()) - { - double timeSeconds = Timer::GetSeconds(); - DWORD waitAllowed; - - for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++) - { - waitAllowed = (DWORD)(TicksNotifiers[j]->OnTicks(timeSeconds) * Timer::MsPerSecond); - if (waitAllowed < waitMs) - waitMs = waitAllowed; - } - } - - // Wait for event signals or window messages. - eventIndex = MsgWaitForMultipleObjects((DWORD)numberOfWaitHandles, &WaitHandles[0], FALSE, waitMs, QS_ALLINPUT); - - if (eventIndex != WAIT_FAILED) - { - if (eventIndex == WAIT_TIMEOUT) - continue; - - // TBD: Does this ever apply? - OVR_ASSERT(eventIndex < WAIT_ABANDONED_0); - - if (eventIndex == WAIT_OBJECT_0) - { - // Handle [0] services commands. - break; - } - else if (eventIndex == WAIT_OBJECT_0 + numberOfWaitHandles) - { - // Handle Windows messages. - pStatusObject->ProcessMessages(); - } - else - { - // Notify waiting device that its event is signaled. - unsigned i = eventIndex - WAIT_OBJECT_0; - OVR_ASSERT(i < numberOfWaitHandles); - if (WaitNotifiers[i]) - WaitNotifiers[i]->OnOverlappedEvent(WaitHandles[i]); - } - } - - } while(eventIndex != WAIT_FAILED); - - } - } - - pStatusObject->ShutDown(); - - LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%X).\n", GetThreadId()); - return 0; -} - -bool DeviceManagerThread::AddOverlappedEvent(Notifier* notify, HANDLE hevent) -{ - WaitNotifiers.PushBack(notify); - WaitHandles.PushBack(hevent); - - OVR_ASSERT(WaitNotifiers.GetSize() <= MAXIMUM_WAIT_OBJECTS); - return true; -} - -bool DeviceManagerThread::RemoveOverlappedEvent(Notifier* notify, HANDLE hevent) -{ - // [0] is reserved for thread commands with notify of null, but we still - // can use this function to remove it. - for (UPInt i = 0; i < WaitNotifiers.GetSize(); i++) - { - if ((WaitNotifiers[i] == notify) && (WaitHandles[i] == hevent)) - { - WaitNotifiers.RemoveAt(i); - WaitHandles.RemoveAt(i); - return true; - } - } - return false; -} - -bool DeviceManagerThread::AddTicksNotifier(Notifier* notify) -{ - TicksNotifiers.PushBack(notify); - return true; -} - -bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify) -{ - for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++) - { - if (TicksNotifiers[i] == notify) - { - TicksNotifiers.RemoveAt(i); - return true; - } - } - return false; -} - -bool DeviceManagerThread::AddMessageNotifier(Notifier* notify) -{ - MessageNotifiers.PushBack(notify); - return true; -} - -bool DeviceManagerThread::RemoveMessageNotifier(Notifier* notify) -{ - for (UPInt i = 0; i < MessageNotifiers.GetSize(); i++) - { - if (MessageNotifiers[i] == notify) - { - MessageNotifiers.RemoveAt(i); - return true; - } - } - return false; -} - -bool DeviceManagerThread::OnMessage(MessageType type, const String& devicePath) -{ - Notifier::DeviceMessageType notifierMessageType = Notifier::DeviceMessage_DeviceAdded; - if (type == DeviceAdded) - { - } - else if (type == DeviceRemoved) - { - notifierMessageType = Notifier::DeviceMessage_DeviceRemoved; - } - else - { - OVR_ASSERT(false); - } - - bool error = false; - bool deviceFound = false; - for (UPInt i = 0; i < MessageNotifiers.GetSize(); i++) - { - if (MessageNotifiers[i] && - MessageNotifiers[i]->OnDeviceMessage(notifierMessageType, devicePath, &error)) - { - // The notifier belonged to a device with the specified device name so we're done. - deviceFound = true; - break; - } - } - if (type == DeviceAdded && !deviceFound) - { - Lock::Locker devMgrLock(&DevMgrLock); - // a new device was connected. Go through all device factories and - // try to detect the device using HIDDeviceDesc. - HIDDeviceDesc devDesc; - if (pDeviceMgr->GetHIDDeviceDesc(devicePath, &devDesc)) - { - Lock::Locker deviceLock(pDeviceMgr->GetLock()); - DeviceFactory* factory = pDeviceMgr->Factories.GetFirst(); - while(!pDeviceMgr->Factories.IsNull(factory)) - { - if (factory->DetectHIDDevice(pDeviceMgr, devDesc)) - { - deviceFound = true; - break; - } - factory = factory->pNext; - } - } - } - - if (!deviceFound && strstr(devicePath.ToCStr(), "#OVR00")) - { - Ptr<DeviceManager> pmgr; - { - Lock::Locker devMgrLock(&DevMgrLock); - pmgr = pDeviceMgr; - } - // HMD plugged/unplugged - // This is not a final solution to enumerate HMD devices and get - // a first available handle. This won't work with multiple rifts. - // @TODO (!AB) - pmgr->EnumerateDevices<HMDDevice>(); - } - - return !error; -} - -void DeviceManagerThread::DetachDeviceManager() -{ - Lock::Locker devMgrLock(&DevMgrLock); - pDeviceMgr = NULL; -} - -} // namespace Win32 - - -//------------------------------------------------------------------------------------- -// ***** Creation - - -// Creates a new DeviceManager and initializes OVR. -DeviceManager* DeviceManager::Create() -{ - - if (!System::IsInitialized()) - { - // Use custom message, since Log is not yet installed. - OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> - LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); ); - return 0; - } - - Ptr<Win32::DeviceManager> manager = *new Win32::DeviceManager; - - if (manager) - { - if (manager->Initialize(0)) - { - manager->AddFactory(&SensorDeviceFactory::GetInstance()); - manager->AddFactory(&LatencyTestDeviceFactory::GetInstance()); - manager->AddFactory(&Win32::HMDDeviceFactory::GetInstance()); - - manager->AddRef(); - } - else - { - manager.Clear(); - } - - } - - return manager.GetPtr(); -} - - -} // namespace OVR - |