mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
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;
|
||||
sf::Clock timer;
|
||||
};
|
||||
|
||||
const sf::Time connectionRefreshDelay = sf::milliseconds(500);
|
||||
|
||||
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
|
||||
std::string getErrorString(DWORD error)
|
||||
{
|
||||
@ -150,19 +153,7 @@ namespace priv
|
||||
void JoystickImpl::initialize()
|
||||
{
|
||||
// Perform the initial scan and populate the connection cache
|
||||
for (unsigned int i = 0; i < Joystick::Count; ++i)
|
||||
{
|
||||
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();
|
||||
}
|
||||
updateConnections();
|
||||
}
|
||||
|
||||
|
||||
@ -176,27 +167,39 @@ void JoystickImpl::cleanup()
|
||||
////////////////////////////////////////////////////////////
|
||||
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];
|
||||
if (cache.timer.getElapsedTime() > connectionRefreshDelay)
|
||||
if (!lazyUpdates && cache.timer.getElapsedTime() > connectionRefreshDelay)
|
||||
{
|
||||
cache.timer.restart();
|
||||
|
||||
JOYINFOEX joyInfo;
|
||||
joyInfo.dwSize = sizeof(joyInfo);
|
||||
joyInfo.dwFlags = 0;
|
||||
|
||||
cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
|
||||
return cache.connected;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cache.connected;
|
||||
|
||||
cache.timer.restart();
|
||||
}
|
||||
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)
|
||||
|
@ -77,6 +77,20 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
|
@ -55,10 +55,15 @@
|
||||
#define MAPVK_VK_TO_VSC (0)
|
||||
#endif
|
||||
|
||||
// Avoid including <Dbt.h> just for one define
|
||||
#ifndef DBT_DEVNODES_CHANGED
|
||||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#endif
|
||||
|
||||
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";
|
||||
sf::priv::WindowImplWin32* fullscreenWindow = NULL;
|
||||
|
||||
@ -141,6 +146,12 @@ m_cursorGrabbed (false)
|
||||
|
||||
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)
|
||||
SetWindowLongPtrW(m_handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
|
||||
m_callback = SetWindowLongPtrW(m_handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::globalOnEvent));
|
||||
@ -202,6 +213,15 @@ m_cursorGrabbed (m_fullscreen)
|
||||
// Create the window
|
||||
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,
|
||||
// we have to resize it after creation to apply the real size
|
||||
setSize(Vector2u(mode.width, mode.height));
|
||||
@ -222,6 +242,15 @@ WindowImplWin32::~WindowImplWin32()
|
||||
if (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)
|
||||
{
|
||||
// Destroy the window
|
||||
@ -936,6 +965,13 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
pushEvent(event);
|
||||
break;
|
||||
}
|
||||
case WM_DEVICECHANGE:
|
||||
{
|
||||
// Some sort of device change has happened, update joystick connections
|
||||
if (wParam == DBT_DEVNODES_CHANGED)
|
||||
JoystickImpl::updateConnections();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user