diff options
Diffstat (limited to 'dinput')
-rw-r--r-- | dinput/dinput.cpp | 80 | ||||
-rw-r--r-- | dinput/dinput.hpp | 54 | ||||
-rw-r--r-- | dinput/keybinding-worker.cpp | 2 | ||||
-rw-r--r-- | dinput/keybinding-worker.hpp | 2 | ||||
-rw-r--r-- | dinput/win32-joystick.cpp | 2 | ||||
-rw-r--r-- | dinput/win32-joystick.hpp | 4 |
6 files changed, 59 insertions, 85 deletions
diff --git a/dinput/dinput.cpp b/dinput/dinput.cpp index 226d3277..c3509dd6 100644 --- a/dinput/dinput.cpp +++ b/dinput/dinput.cpp @@ -1,88 +1,64 @@ #include "dinput.hpp" #include <QDebug> -std::atomic<int> dinput_handle::refcnt; -std::atomic_flag dinput_handle::init_lock = ATOMIC_FLAG_INIT; +std::atomic<int> di_t::refcnt; +std::atomic_flag di_t::init_lock = ATOMIC_FLAG_INIT; +diptr di_t::handle; -LPDIRECTINPUT8& dinput_handle::init_di() +diptr di_t::init_di_() { CoInitialize(nullptr); - static LPDIRECTINPUT8 di_ = nullptr; - if (di_ == nullptr) + diptr di = nullptr; + if (HRESULT hr = DirectInput8Create(GetModuleHandle(nullptr), + DIRECTINPUT_VERSION, + IID_IDirectInput8, + (void**)&di, + nullptr); + !SUCCEEDED(hr)) { - if (!SUCCEEDED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di_, NULL))) - { - di_ = nullptr; - } + qDebug() << "can't make dinput:" << (void*)hr; + qDebug() << "crashing!"; + std::abort(); } - return di_; -} - -dinput_handle::di_t dinput_handle::make_di() -{ - while (init_lock.test_and_set()) { /* busy loop */ } - - LPDIRECTINPUT8& ret = init_di(); - init_lock.clear(); - - return di_t(ret); + return di; } -void dinput_handle::di_t::free_di() +di_t::di_t() { - if (handle && *handle) - { - (*handle)->Release(); - *handle = nullptr; - } - handle = nullptr; -} - -void dinput_handle::di_t::ref_di() -{ - //const int refcnt_ = refcnt.fetch_add(1) + 1; - (void) refcnt.fetch_add(1); + ref_di(); } -dinput_handle::di_t& dinput_handle::di_t::operator=(const di_t& new_di) +void di_t::ref_di() { - if (handle) - unref_di(); + while (init_lock.test_and_set()) { /* busy loop */ } - handle = new_di.handle; + if (!handle) + handle = init_di_(); - if (handle) - ref_di(); + ++refcnt; - return *this; + init_lock.clear(); } -void dinput_handle::di_t::unref_di() +void di_t::unref_di() { - const int refcnt_ = refcnt.fetch_sub(1) - 1; + const int refcnt_ = --refcnt; if (refcnt_ == 0) { while (init_lock.test_and_set()) { /* busy loop */ } qDebug() << "exit: di handle"; - free_di(); + handle->Release(); init_lock.clear(); } } -dinput_handle::di_t::di_t(LPDIRECTINPUT8& handle) : handle(&handle) +di_t::~di_t() { - ref_di(); + unref_di(); } -dinput_handle::di_t::di_t() : handle(nullptr) {} - -dinput_handle::di_t::~di_t() -{ - if (handle) - unref_di(); -} diff --git a/dinput/dinput.hpp b/dinput/dinput.hpp index fc73a90a..4806a992 100644 --- a/dinput/dinput.hpp +++ b/dinput/dinput.hpp @@ -10,42 +10,42 @@ #include "export.hpp" +#include <atomic> + #undef DIRECTINPUT_VERSION #define DIRECTINPUT_VERSION 0x800 + #include <dinput.h> -#include <atomic> -class OTR_DINPUT_EXPORT dinput_handle final +using diptr = IDirectInput8A*; + +class OTR_DINPUT_EXPORT di_t final { -public: - class di_t; + static void unref_di(); + static void ref_di(); -private: + static diptr handle; static std::atomic<int> refcnt; static std::atomic_flag init_lock; + static diptr init_di_(); - static LPDIRECTINPUT8& init_di(); public: - class di_t final + di_t(); + ~di_t(); + di_t(const di_t&) : di_t() {} + di_t& operator=(const di_t&) { return *this; } + + diptr operator->() const { return handle; } + operator bool() { return handle; } + + // for debugging bad usages + template<typename t = void> + operator void*() const { - friend class dinput_handle; - - LPDIRECTINPUT8* handle; - - di_t(LPDIRECTINPUT8& handle); - void free_di(); - void unref_di(); - void ref_di(); - - public: - LPDIRECTINPUT8 operator->() { return *handle; } - operator LPDIRECTINPUT8() { return *handle; } - LPDIRECTINPUT8 di() { return *handle; } - di_t& operator=(const di_t& new_di); - di_t(); - ~di_t(); - }; - - static di_t make_di(); - dinput_handle() = delete; + static_assert(sizeof(t) == -1); + static_assert(sizeof(t) == 0); + + return nullptr; + } }; + diff --git a/dinput/keybinding-worker.cpp b/dinput/keybinding-worker.cpp index 0bdc18cd..c7547107 100644 --- a/dinput/keybinding-worker.cpp +++ b/dinput/keybinding-worker.cpp @@ -93,7 +93,7 @@ bool KeybindingWorker::init() return true; } -KeybindingWorker::KeybindingWorker() : dinkeyboard(nullptr), din(dinput_handle::make_di()) +KeybindingWorker::KeybindingWorker() { if (init()) start(QThread::HighPriority); diff --git a/dinput/keybinding-worker.hpp b/dinput/keybinding-worker.hpp index 7481bcea..6b7d6882 100644 --- a/dinput/keybinding-worker.hpp +++ b/dinput/keybinding-worker.hpp @@ -47,7 +47,7 @@ private: std::vector<std::unique_ptr<fun>> receivers; QMutex mtx; QMainWindow fake_main_window; - dinput_handle::di_t din; + di_t din; bool keystate[256] {}; bool old_keystate[256] {}; diff --git a/dinput/win32-joystick.cpp b/dinput/win32-joystick.cpp index ed5bd214..a8a3f388 100644 --- a/dinput/win32-joystick.cpp +++ b/dinput/win32-joystick.cpp @@ -246,7 +246,7 @@ bool win32_joy_ctx::joy::poll(fn const& f) return true; } -win32_joy_ctx::enum_state::enum_state() : di(dinput_handle::make_di()) +win32_joy_ctx::enum_state::enum_state() { } diff --git a/dinput/win32-joystick.hpp b/dinput/win32-joystick.hpp index f42bd450..a6a4edc9 100644 --- a/dinput/win32-joystick.hpp +++ b/dinput/win32-joystick.hpp @@ -76,8 +76,6 @@ struct OTR_DINPUT_EXPORT win32_joy_ctx final win32_joy_ctx(); void refresh(); - using di_t = dinput_handle::di_t; - private: static QString guid_to_string(const GUID& guid); @@ -85,7 +83,7 @@ private: { std::vector<QString> all; joys_t joys; - dinput_handle::di_t di; + di_t di {}; static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext); static BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* ctx); |