If a window is open, only update joystick connections on WM_DEVICECHANGE message
This commit is contained in:
parent
4cde8bb69c
commit
f053871a6c
@ -44,10 +44,13 @@ namespace
|
|||||||
bool connected;
|
bool connected;
|
||||||
sf::Clock timer;
|
sf::Clock timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sf::Time connectionRefreshDelay = sf::milliseconds(500);
|
const sf::Time connectionRefreshDelay = sf::milliseconds(500);
|
||||||
|
|
||||||
ConnectionCache connectionCache[sf::Joystick::Count];
|
ConnectionCache connectionCache[sf::Joystick::Count];
|
||||||
|
|
||||||
|
// If true, will only update when WM_DEVICECHANGE message is received
|
||||||
|
bool lazyUpdates = false;
|
||||||
|
|
||||||
// Get a system error string from an error code
|
// Get a system error string from an error code
|
||||||
std::string getErrorString(DWORD error)
|
std::string getErrorString(DWORD error)
|
||||||
{
|
{
|
||||||
@ -150,19 +153,7 @@ namespace priv
|
|||||||
void JoystickImpl::initialize()
|
void JoystickImpl::initialize()
|
||||||
{
|
{
|
||||||
// Perform the initial scan and populate the connection cache
|
// Perform the initial scan and populate the connection cache
|
||||||
for (unsigned int i = 0; i < Joystick::Count; ++i)
|
updateConnections();
|
||||||
{
|
|
||||||
ConnectionCache& cache = connectionCache[i];
|
|
||||||
|
|
||||||
// Check if the joystick is connected
|
|
||||||
JOYINFOEX joyInfo;
|
|
||||||
joyInfo.dwSize = sizeof(joyInfo);
|
|
||||||
joyInfo.dwFlags = 0;
|
|
||||||
cache.connected = joyGetPosEx(JOYSTICKID1 + i, &joyInfo) == JOYERR_NOERROR;
|
|
||||||
|
|
||||||
// start the timeout
|
|
||||||
cache.timer.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,27 +167,39 @@ void JoystickImpl::cleanup()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool JoystickImpl::isConnected(unsigned int index)
|
bool JoystickImpl::isConnected(unsigned int index)
|
||||||
{
|
{
|
||||||
// We check the connection state of joysticks only every N milliseconds,
|
|
||||||
// because of a strange (buggy?) behavior of joyGetPosEx when joysticks
|
|
||||||
// are just plugged/unplugged -- it takes really long and kills the app performances
|
|
||||||
ConnectionCache& cache = connectionCache[index];
|
ConnectionCache& cache = connectionCache[index];
|
||||||
if (cache.timer.getElapsedTime() > connectionRefreshDelay)
|
if (!lazyUpdates && cache.timer.getElapsedTime() > connectionRefreshDelay)
|
||||||
{
|
{
|
||||||
cache.timer.restart();
|
|
||||||
|
|
||||||
JOYINFOEX joyInfo;
|
JOYINFOEX joyInfo;
|
||||||
joyInfo.dwSize = sizeof(joyInfo);
|
joyInfo.dwSize = sizeof(joyInfo);
|
||||||
joyInfo.dwFlags = 0;
|
joyInfo.dwFlags = 0;
|
||||||
|
|
||||||
cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
|
cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
|
||||||
return cache.connected;
|
|
||||||
}
|
cache.timer.restart();
|
||||||
else
|
|
||||||
{
|
|
||||||
return cache.connected;
|
|
||||||
}
|
}
|
||||||
|
return cache.connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void JoystickImpl::setLazyUpdates(bool status)
|
||||||
|
{
|
||||||
|
lazyUpdates = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void JoystickImpl::updateConnections()
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < Joystick::Count; ++i)
|
||||||
|
{
|
||||||
|
JOYINFOEX joyInfo;
|
||||||
|
joyInfo.dwSize = sizeof(joyInfo);
|
||||||
|
joyInfo.dwFlags = 0;
|
||||||
|
ConnectionCache& cache = connectionCache[i];
|
||||||
|
cache.connected = joyGetPosEx(JOYSTICKID1 + i, &joyInfo) == JOYERR_NOERROR;
|
||||||
|
|
||||||
|
cache.timer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool JoystickImpl::open(unsigned int index)
|
bool JoystickImpl::open(unsigned int index)
|
||||||
|
@ -77,6 +77,20 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
static bool isConnected(unsigned int index);
|
static bool isConnected(unsigned int index);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Enable or disable lazy enumeration updates
|
||||||
|
///
|
||||||
|
/// \param status Whether to rely on windows triggering enumeration updates
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static void setLazyUpdates(bool status);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Update the connection status of all joysticks
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static void updateConnections();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Open the joystick
|
/// \brief Open the joystick
|
||||||
///
|
///
|
||||||
|
@ -55,10 +55,15 @@
|
|||||||
#define MAPVK_VK_TO_VSC (0)
|
#define MAPVK_VK_TO_VSC (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Avoid including <Dbt.h> just for one define
|
||||||
|
#ifndef DBT_DEVNODES_CHANGED
|
||||||
|
#define DBT_DEVNODES_CHANGED 0x0007
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
unsigned int windowCount = 0;
|
unsigned int windowCount = 0; // Windows owned by SFML
|
||||||
|
unsigned int handleCount = 0; // All window handles
|
||||||
const wchar_t* className = L"SFML_Window";
|
const wchar_t* className = L"SFML_Window";
|
||||||
sf::priv::WindowImplWin32* fullscreenWindow = NULL;
|
sf::priv::WindowImplWin32* fullscreenWindow = NULL;
|
||||||
|
|
||||||
@ -141,6 +146,12 @@ m_cursorGrabbed (false)
|
|||||||
|
|
||||||
if (m_handle)
|
if (m_handle)
|
||||||
{
|
{
|
||||||
|
// If we're the first window handle, we only need to poll for joysticks when WM_DEVICECHANGE message is received
|
||||||
|
if (handleCount == 0)
|
||||||
|
JoystickImpl::setLazyUpdates(true);
|
||||||
|
|
||||||
|
++handleCount;
|
||||||
|
|
||||||
// We change the event procedure of the control (it is important to save the old one)
|
// We change the event procedure of the control (it is important to save the old one)
|
||||||
SetWindowLongPtrW(m_handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
SetWindowLongPtrW(m_handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||||
m_callback = SetWindowLongPtrW(m_handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::globalOnEvent));
|
m_callback = SetWindowLongPtrW(m_handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::globalOnEvent));
|
||||||
@ -202,6 +213,15 @@ m_cursorGrabbed (m_fullscreen)
|
|||||||
// Create the window
|
// Create the window
|
||||||
m_handle = CreateWindowW(className, title.toWideString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
|
m_handle = CreateWindowW(className, title.toWideString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
|
||||||
|
|
||||||
|
// If we're the first window handle, we only need to poll for joysticks when WM_DEVICECHANGE message is received
|
||||||
|
if (m_handle)
|
||||||
|
{
|
||||||
|
if (handleCount == 0)
|
||||||
|
JoystickImpl::setLazyUpdates(true);
|
||||||
|
|
||||||
|
++handleCount;
|
||||||
|
}
|
||||||
|
|
||||||
// By default, the OS limits the size of the window the the desktop size,
|
// By default, the OS limits the size of the window the the desktop size,
|
||||||
// we have to resize it after creation to apply the real size
|
// we have to resize it after creation to apply the real size
|
||||||
setSize(Vector2u(mode.width, mode.height));
|
setSize(Vector2u(mode.width, mode.height));
|
||||||
@ -222,6 +242,15 @@ WindowImplWin32::~WindowImplWin32()
|
|||||||
if (m_icon)
|
if (m_icon)
|
||||||
DestroyIcon(m_icon);
|
DestroyIcon(m_icon);
|
||||||
|
|
||||||
|
// If it's the last window handle we have to poll for joysticks again
|
||||||
|
if (m_handle)
|
||||||
|
{
|
||||||
|
--handleCount;
|
||||||
|
|
||||||
|
if (handleCount == 0)
|
||||||
|
JoystickImpl::setLazyUpdates(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_callback)
|
if (!m_callback)
|
||||||
{
|
{
|
||||||
// Destroy the window
|
// Destroy the window
|
||||||
@ -936,6 +965,13 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_DEVICECHANGE:
|
||||||
|
{
|
||||||
|
// Some sort of device change has happened, update joystick connections
|
||||||
|
if (wParam == DBT_DEVNODES_CHANGED)
|
||||||
|
JoystickImpl::updateConnections();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user