diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2019-03-21 10:31:45 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-03-21 10:31:45 +0100 |
commit | 8553a64aa9eddfa9c7ed166ecb220f1a8c115b78 (patch) | |
tree | 970843c27d6079d71be15715adb984e375870e58 | |
parent | 89d5870138a4ad26c00cddb209ebe5312fe85dc3 (diff) |
dinput: get rid of refcounting
-rw-r--r-- | dinput/dinput.cpp | 69 | ||||
-rw-r--r-- | dinput/dinput.hpp | 12 | ||||
-rw-r--r-- | dinput/keybinding-worker.cpp | 45 | ||||
-rw-r--r-- | dinput/keybinding-worker.hpp | 2 | ||||
-rw-r--r-- | dinput/win32-joystick.hpp | 2 |
5 files changed, 70 insertions, 60 deletions
diff --git a/dinput/dinput.cpp b/dinput/dinput.cpp index 22781a32..02b56683 100644 --- a/dinput/dinput.cpp +++ b/dinput/dinput.cpp @@ -1,68 +1,69 @@ +#undef NDEBUG + #include "dinput.hpp" #include "compat/macros.hpp" +#include <cassert> +#include <cstdlib> + #include <QDebug> -int di_t::refcnt{0}; diptr di_t::handle; QMutex di_t::lock; -diptr di_t::init_di_() +diptr di_t::init_di() { CoInitialize(nullptr); - diptr di = nullptr; - HRESULT hr = DirectInput8Create(GetModuleHandle(nullptr), - DIRECTINPUT_VERSION, - IID_IDirectInput8, - (void**)&di, - nullptr); - if (!SUCCEEDED(hr)) - { - qDebug() << "can't make dinput:" << (void*)(LONG_PTR)hr; - qDebug() << "crashing!"; - std::abort(); - } + if (!handle) + handle = init_di_(); - return di; + return handle; } -di_t::di_t() +diptr di_t::operator->() const { - ref_di(); + QMutexLocker l(&lock); + return init_di(); } -void di_t::ref_di() +di_t::operator bool() const { QMutexLocker l(&lock); - - if (!handle) - handle = init_di_(); - - ++refcnt; + return !!init_di(); } -void di_t::unref_di() +di_t::operator diptr() const { - QMutexLocker l(&lock); - - const int refcnt_ = --refcnt; + return init_di(); +} - if (refcnt_ == 0) +diptr di_t::init_di_() +{ + diptr di = nullptr; + HRESULT hr = DirectInput8Create(GetModuleHandle(nullptr), + DIRECTINPUT_VERSION, + IID_IDirectInput8, + (void**)&di, + nullptr); + if (!SUCCEEDED(hr)) { - qDebug() << "exit: di handle"; - handle->Release(); + qDebug() << "can't make dinput:" << (void*)(LONG_PTR)hr; + qDebug() << "crashing!"; + std::abort(); } -} -di_t::~di_t() -{ - unref_di(); + qDebug() << "dinput: initialized"; + + return di; } +di_t::di_t() = default; + bool di_t::poll_device(LPDIRECTINPUTDEVICE8 dev) { HRESULT hr; + assert(handle); switch (dev->Poll()) { diff --git a/dinput/dinput.hpp b/dinput/dinput.hpp index 394084e2..e9908a94 100644 --- a/dinput/dinput.hpp +++ b/dinput/dinput.hpp @@ -25,23 +25,19 @@ using diptr = IDirectInput8A*; class OTR_DINPUT_EXPORT di_t final { - static void unref_di(); - static void ref_di(); - static diptr handle; - static int refcnt; static QMutex lock; static diptr init_di_(); + static diptr init_di(); public: di_t(); - ~di_t(); di_t(const di_t&) : di_t() {} di_t& operator=(const di_t&) = default; - diptr operator->() const { return handle; } - operator bool() const { return handle != nullptr; } - operator diptr() const { return handle; } + diptr operator->() const; + operator bool() const; + operator diptr() const; static bool poll_device(LPDIRECTINPUTDEVICE8 dev); }; diff --git a/dinput/keybinding-worker.cpp b/dinput/keybinding-worker.cpp index 3d792778..14676c05 100644 --- a/dinput/keybinding-worker.cpp +++ b/dinput/keybinding-worker.cpp @@ -33,7 +33,9 @@ KeybindingWorker::~KeybindingWorker() requestInterruption(); wait(); - if (dinkeyboard) { + + if (dinkeyboard) + { dinkeyboard->Unacquire(); dinkeyboard->Release(); } @@ -41,29 +43,31 @@ KeybindingWorker::~KeybindingWorker() bool KeybindingWorker::init() { + if (dinkeyboard) + return true; + if (!din) { qDebug() << "can't create dinput handle"; - return false; + goto fail; } - if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, nullptr) != DI_OK) { + if (din->CreateDevice(GUID_SysKeyboard, &dinkeyboard, nullptr) != DI_OK) + { qDebug() << "dinput: create keyboard failed" << GetLastError(); - return false; + goto fail; } - if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) { + if (dinkeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK) + { qDebug() << "dinput: keyboard SetDataFormat" << GetLastError(); - dinkeyboard->Release(); - dinkeyboard = nullptr; - return false; + goto fail; } - if (dinkeyboard->SetCooperativeLevel((HWND) fake_main_window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) { - dinkeyboard->Release(); - dinkeyboard = nullptr; + if (dinkeyboard->SetCooperativeLevel((HWND) fake_main_window.winId(), DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK) + { qDebug() << "dinput: keyboard SetCooperativeLevel" << GetLastError(); - return false; + goto fail; } { @@ -73,20 +77,29 @@ bool KeybindingWorker::init() dipdw.diph.dwHow = DIPH_DEVICE; dipdw.diph.dwObj = 0; dipdw.diph.dwSize = sizeof(dipdw); - if ( dinkeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK) + + if (dinkeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK) { qDebug() << "dinput: DIPROP_BUFFERSIZE"; - dinkeyboard->Release(); - dinkeyboard = nullptr; - return false; + goto fail; } } return true; + +fail: + if (dinkeyboard) + { + dinkeyboard->Release(); + dinkeyboard = nullptr; + } + return false; } KeybindingWorker::KeybindingWorker() { + fake_main_window.setAttribute(Qt::WA_NativeWindow); + if (init()) start(QThread::HighPriority); } diff --git a/dinput/keybinding-worker.hpp b/dinput/keybinding-worker.hpp index 7b9dd259..335a5c11 100644 --- a/dinput/keybinding-worker.hpp +++ b/dinput/keybinding-worker.hpp @@ -45,7 +45,7 @@ struct OTR_DINPUT_EXPORT KeybindingWorker : private QThread KeybindingWorker& operator=(KeybindingWorker&) = delete; private: - LPDIRECTINPUTDEVICE8 dinkeyboard { nullptr }; + IDirectInputDevice8A* dinkeyboard = nullptr; win32_joy_ctx joy_ctx; std::vector<std::unique_ptr<fun>> receivers; QMutex mtx; diff --git a/dinput/win32-joystick.hpp b/dinput/win32-joystick.hpp index 331e4968..3aa6f315 100644 --- a/dinput/win32-joystick.hpp +++ b/dinput/win32-joystick.hpp @@ -87,7 +87,7 @@ private: { std::vector<QString> all; joys_t joys; - di_t di {}; + di_t di; static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext); static BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* ctx); |