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); | 
