Title: [170957] trunk/Source/WebCore
Revision
170957
Author
[email protected]
Date
2014-07-09 23:08:58 -0700 (Wed, 09 Jul 2014)

Log Message

Fire connected/disconnected events for Gamepads.
https://bugs.webkit.org/show_bug.cgi?id=134386

Reviewed by Dean Jackson.

No new tests (No effect in a currently tested config)

* Modules/gamepad/GamepadManager.cpp:
(WebCore::navigatorGamepadFromDOMWindow): Handling converting a possibly-null Navigator into
    a possibly null NavigatorGamepad.
(WebCore::GamepadManager::platformGamepadConnected): Notify blind Navigator/DOMWindows of all
    previously attached Gamepads, then notify everybody of this new gamepad.
(WebCore::GamepadManager::platformGamepadDisconnected): Handle dispatching the disconnected
    event to all registered DOMWindows.
(WebCore::GamepadManager::platformGamepadInputActivity): Notify blind Navigator/DOMWindows of all
    attached Gamepads.
(WebCore::GamepadManager::makeGamepadVisible): Handles notifying setting up a new gamepads
    with all NavigatorGamepads as well as dispatching the connected even to DOMWindows.
(WebCore::GamepadManager::registerDOMWindow):
(WebCore::GamepadManager::unregisterDOMWindow):
(WebCore::GamepadManager::makeGamepadsVisibileToBlindNavigators): Deleted.
* Modules/gamepad/GamepadManager.h:

* Modules/gamepad/NavigatorGamepad.cpp:
(WebCore::NavigatorGamepad::gamepadAtIndex):
* Modules/gamepad/NavigatorGamepad.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (170956 => 170957)


--- trunk/Source/WebCore/ChangeLog	2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/ChangeLog	2014-07-10 06:08:58 UTC (rev 170957)
@@ -1,3 +1,32 @@
+2014-07-09  Brady Eidson  <[email protected]>
+
+        Fire connected/disconnected events for Gamepads.
+        https://bugs.webkit.org/show_bug.cgi?id=134386
+
+        Reviewed by Dean Jackson.
+
+        No new tests (No effect in a currently tested config)
+
+        * Modules/gamepad/GamepadManager.cpp:
+        (WebCore::navigatorGamepadFromDOMWindow): Handling converting a possibly-null Navigator into
+            a possibly null NavigatorGamepad.
+        (WebCore::GamepadManager::platformGamepadConnected): Notify blind Navigator/DOMWindows of all
+            previously attached Gamepads, then notify everybody of this new gamepad.
+        (WebCore::GamepadManager::platformGamepadDisconnected): Handle dispatching the disconnected
+            event to all registered DOMWindows.
+        (WebCore::GamepadManager::platformGamepadInputActivity): Notify blind Navigator/DOMWindows of all
+            attached Gamepads.
+        (WebCore::GamepadManager::makeGamepadVisible): Handles notifying setting up a new gamepads
+            with all NavigatorGamepads as well as dispatching the connected even to DOMWindows.
+        (WebCore::GamepadManager::registerDOMWindow):
+        (WebCore::GamepadManager::unregisterDOMWindow):
+        (WebCore::GamepadManager::makeGamepadsVisibileToBlindNavigators): Deleted.
+        * Modules/gamepad/GamepadManager.h:
+
+        * Modules/gamepad/NavigatorGamepad.cpp:
+        (WebCore::NavigatorGamepad::gamepadAtIndex):
+        * Modules/gamepad/NavigatorGamepad.h:
+
 2014-07-09  Benjamin Poulain  <[email protected]>
 
         [iOS][WK2] Disable text quantization while actively changing the page's scale factor

Modified: trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp (170956 => 170957)


--- trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp	2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadManager.cpp	2014-07-10 06:08:58 UTC (rev 170957)
@@ -27,7 +27,10 @@
 
 #if ENABLE(GAMEPAD)
 
+#include "DOMWindow.h"
+#include "Document.h"
 #include "Gamepad.h"
+#include "GamepadEvent.h"
 #include "GamepadProvider.h"
 #include "Logging.h"
 #include "NavigatorGamepad.h"
@@ -35,6 +38,15 @@
 
 namespace WebCore {
 
+static NavigatorGamepad* navigatorGamepadFromDOMWindow(DOMWindow* window)
+{
+    Navigator* navigator = window->navigator();
+    if (!navigator)
+        return nullptr;
+
+    return NavigatorGamepad::from(navigator);
+}
+
 GamepadManager& GamepadManager::shared()
 {
     static NeverDestroyed<GamepadManager> sharedManager;
@@ -48,43 +60,95 @@
 
 void GamepadManager::platformGamepadConnected(PlatformGamepad& platformGamepad)
 {
-    for (auto& navigator : m_navigators) {
-        if (!m_gamepadBlindNavigators.contains(navigator))
-            navigator->gamepadConnected(platformGamepad);
+    // Notify blind Navigators and Windows about all gamepads except for this one.
+    for (auto* gamepad : GamepadProvider::shared().platformGamepads()) {
+        if (!gamepad || gamepad == &platformGamepad)
+            continue;
 
-        // FIXME: Fire connected event to all pages with listeners.
+        makeGamepadVisible(*gamepad, m_gamepadBlindNavigators, m_gamepadBlindDOMWindows);
     }
 
-    makeGamepadsVisibileToBlindNavigators();
+    m_gamepadBlindNavigators.clear();
+    m_gamepadBlindDOMWindows.clear();
+
+    // Notify everyone of this new gamepad.
+    makeGamepadVisible(platformGamepad, m_navigators, m_domWindows);
 }
 
 void GamepadManager::platformGamepadDisconnected(PlatformGamepad& platformGamepad)
 {
-    for (auto& navigator : m_navigators) {
-        if (!m_gamepadBlindNavigators.contains(navigator))
-            navigator->gamepadDisconnected(platformGamepad);
+    Vector<DOMWindow*> domWindowVector;
+    copyToVector(m_domWindows, domWindowVector);
 
-        // FIXME: Fire disconnected event to all pages with listeners.
+    HashSet<NavigatorGamepad*> notifiedNavigators;
+
+    // Handle the disconnect for all DOMWindows with event listeners and their Navigators.
+    for (auto* window : domWindowVector) {
+        // Event dispatch might have made this window go away.
+        if (!m_domWindows.contains(window))
+            continue;
+
+        NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
+        if (!navigator)
+            continue;
+
+        // If this Navigator hasn't seen gamepads yet then its Window should not get the disconnect event.
+        if (m_gamepadBlindNavigators.contains(navigator))
+            continue;
+
+        RefPtr<Gamepad> gamepad = navigator->gamepadAtIndex(platformGamepad.index());
+        ASSERT(gamepad);
+
+        navigator->gamepadDisconnected(platformGamepad);
+        notifiedNavigators.add(navigator);
+
+        window->dispatchEvent(GamepadEvent::create(eventNames().gamepaddisconnectedEvent, gamepad.get()), window->document());
     }
+
+    // Notify all the Navigators that haven't already been notified.
+    for (auto* navigator : m_navigators) {
+        if (!notifiedNavigators.contains(navigator))
+            navigator->gamepadDisconnected(platformGamepad);
+    }
 }
 
 void GamepadManager::platformGamepadInputActivity()
 {
-    makeGamepadsVisibileToBlindNavigators();
+    if (m_gamepadBlindNavigators.isEmpty() && m_gamepadBlindDOMWindows.isEmpty())
+        return;
+
+    for (auto* gamepad : GamepadProvider::shared().platformGamepads())
+        makeGamepadVisible(*gamepad, m_gamepadBlindNavigators, m_gamepadBlindDOMWindows);
+
+    m_gamepadBlindNavigators.clear();
+    m_gamepadBlindDOMWindows.clear();
 }
 
-void GamepadManager::makeGamepadsVisibileToBlindNavigators()
+void GamepadManager::makeGamepadVisible(PlatformGamepad& platformGamepad, HashSet<NavigatorGamepad*>& navigatorSet, HashSet<DOMWindow*>& domWindowSet)
 {
-    for (auto& navigator : m_gamepadBlindNavigators) {
-        // FIXME: Here we notify a blind Navigator of each existing gamepad.
-        // But we also need to fire the connected event to its corresponding DOMWindow objects.
-        for (auto& platformGamepad : GamepadProvider::shared().platformGamepads()) {
-            if (platformGamepad)
-                navigator->gamepadConnected(*platformGamepad);
-        }
+    if (navigatorSet.isEmpty() && domWindowSet.isEmpty())
+        return;
+
+    for (auto* navigator : navigatorSet)
+        navigator->gamepadConnected(platformGamepad);
+
+    Vector<DOMWindow*> domWindowVector;
+    copyToVector(domWindowSet, domWindowVector);
+
+    for (auto* window : domWindowVector) {
+        // Event dispatch might have made this window go away.
+        if (!m_domWindows.contains(window))
+            continue;
+
+        NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
+        if (!navigator)
+            continue;
+
+        RefPtr<Gamepad> gamepad = navigator->gamepadAtIndex(platformGamepad.index());
+        ASSERT(gamepad);
+
+        window->dispatchEvent(GamepadEvent::create(eventNames().gamepadconnectedEvent, gamepad.get()), window->document());
     }
-
-    m_gamepadBlindNavigators.clear();
 }
 
 void GamepadManager::registerNavigator(NavigatorGamepad* navigator)
@@ -116,6 +180,18 @@
     ASSERT(!m_domWindows.contains(window));
     m_domWindows.add(window);
 
+    // Anytime we register a DOMWindow, we should also double check that its NavigatorGamepad is registered.
+    NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
+    ASSERT(navigator);
+
+    if (m_navigators.add(navigator).isNewEntry)
+        m_gamepadBlindNavigators.add(navigator);
+
+    // If this DOMWindow's NavigatorGamepad was already registered but was still blind,
+    // then this DOMWindow should be blind.
+    if (m_gamepadBlindNavigators.contains(navigator))
+        m_gamepadBlindDOMWindows.add(window);
+
     maybeStartMonitoringGamepads();
 }
 
@@ -125,6 +201,7 @@
 
     ASSERT(m_domWindows.contains(window));
     m_domWindows.remove(window);
+    m_gamepadBlindDOMWindows.remove(window);
 
     maybeStopMonitoringGamepads();
 }

Modified: trunk/Source/WebCore/Modules/gamepad/GamepadManager.h (170956 => 170957)


--- trunk/Source/WebCore/Modules/gamepad/GamepadManager.h	2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/GamepadManager.h	2014-07-10 06:08:58 UTC (rev 170957)
@@ -32,6 +32,7 @@
 #include <wtf/HashSet.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/RefPtr.h>
+#include <wtf/text/AtomicString.h>
 
 namespace WebCore {
 
@@ -57,7 +58,8 @@
 private:
     GamepadManager();
 
-    void makeGamepadsVisibileToBlindNavigators();
+    void makeGamepadVisible(PlatformGamepad&, HashSet<NavigatorGamepad*>&, HashSet<DOMWindow*>&);
+    void dispatchGamepadEvent(const WTF::AtomicString& eventName, PlatformGamepad&);
 
     void maybeStartMonitoringGamepads();
     void maybeStopMonitoringGamepads();
@@ -67,6 +69,7 @@
     HashSet<NavigatorGamepad*> m_navigators;
     HashSet<NavigatorGamepad*> m_gamepadBlindNavigators;
     HashSet<DOMWindow*> m_domWindows;
+    HashSet<DOMWindow*> m_gamepadBlindDOMWindows;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp (170956 => 170957)


--- trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp	2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp	2014-07-10 06:08:58 UTC (rev 170957)
@@ -72,6 +72,13 @@
     return supplement;
 }
 
+Gamepad* NavigatorGamepad::gamepadAtIndex(unsigned index)
+{
+    if (index >= m_gamepads.size())
+        return nullptr;
+    return m_gamepads[index].get();
+}
+
 const Vector<RefPtr<Gamepad>>& NavigatorGamepad::getGamepads(Navigator* navigator)
 {
     return NavigatorGamepad::from(navigator)->gamepads();

Modified: trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h (170956 => 170957)


--- trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h	2014-07-10 05:59:04 UTC (rev 170956)
+++ trunk/Source/WebCore/Modules/gamepad/NavigatorGamepad.h	2014-07-10 06:08:58 UTC (rev 170957)
@@ -53,6 +53,8 @@
     void gamepadConnected(PlatformGamepad&);
     void gamepadDisconnected(PlatformGamepad&);
 
+    Gamepad* gamepadAtIndex(unsigned index);
+
 private:
     static const char* supplementName();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to