From 76e04a8d00cae47d2fa0dc8b355284e032da54b1 Mon Sep 17 00:00:00 2001
From: Laurent Gomila <laurent.gom@gmail.com>
Date: Sun, 13 May 2012 21:53:27 +0200
Subject: [PATCH] Added a workaround in JoystickImpl::isConnected on Windows,
 to limit the number of calls to joyGetPosEx which takes too long in certain
 situations

---
 src/SFML/Window/Win32/JoystickImpl.cpp | 36 +++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/SFML/Window/Win32/JoystickImpl.cpp b/src/SFML/Window/Win32/JoystickImpl.cpp
index 5098b763..f14cecfc 100644
--- a/src/SFML/Window/Win32/JoystickImpl.cpp
+++ b/src/SFML/Window/Win32/JoystickImpl.cpp
@@ -26,10 +26,24 @@
 // Headers
 ////////////////////////////////////////////////////////////
 #include <SFML/Window/JoystickImpl.hpp>
+#include <SFML/System/Clock.hpp>
 #include <windows.h>
 #include <cmath>
 
 
+namespace
+{
+    struct ConnectionCache
+    {
+        ConnectionCache() : connected(false) {}
+        bool connected;
+        sf::Clock timer;
+    };
+
+    const sf::Time connectionRefreshDelay = sf::milliseconds(500);
+    ConnectionCache connectionCache[sf::Joystick::Count];
+}
+
 namespace sf
 {
 namespace priv
@@ -37,11 +51,25 @@ namespace priv
 ////////////////////////////////////////////////////////////
 bool JoystickImpl::isConnected(unsigned int index)
 {
-    JOYINFOEX joyInfo;
-    joyInfo.dwSize = sizeof(joyInfo);
-    joyInfo.dwFlags = 0;
+    // We check the connection state of joysticks only every N milliseconds,
+    // because of a strange (buggy?) behaviour 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)
+    {
+        cache.timer.restart();
 
-    return joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
+        JOYINFOEX joyInfo;
+        joyInfo.dwSize = sizeof(joyInfo);
+        joyInfo.dwFlags = 0;
+
+        cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
+        return cache.connected;
+    }
+    else
+    {
+        return cache.connected;
+    }
 }