Source/WebCore/ChangeLog

 12014-07-06 Brady Eidson <beidson@apple.com>
 2
 3 Fire connected/disconnected events for Gamepads.
 4 https://bugs.webkit.org/show_bug.cgi?id=134386
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 No new tests (No effect in a currently tested config)
 9
 10 * Modules/gamepad/GamepadManager.cpp:
 11 (WebCore::navigatorGamepadFromDOMWindow): Handling converting a possibly-null Navigator into
 12 a possibly null NavigatorGamepad.
 13 (WebCore::GamepadManager::platformGamepadConnected): Notify blind Navigator/DOMWindows of all
 14 previously attached Gamepads, then notify everybody of this new gamepad.
 15 (WebCore::GamepadManager::platformGamepadDisconnected): Handle dispatching the disconnected
 16 event to all registered DOMWindows.
 17 (WebCore::GamepadManager::platformGamepadInputActivity): Notify blind Navigator/DOMWindows of all
 18 attached Gamepads.
 19 (WebCore::GamepadManager::makeGamepadVisible): Handles notifying setting up a new gamepads
 20 with all NavigatorGamepads as well as dispatching the connected even to DOMWindows.
 21 (WebCore::GamepadManager::registerDOMWindow):
 22 (WebCore::GamepadManager::unregisterDOMWindow):
 23 (WebCore::GamepadManager::makeGamepadsVisibileToBlindNavigators): Deleted.
 24 * Modules/gamepad/GamepadManager.h:
 25
 26 * Modules/gamepad/NavigatorGamepad.cpp:
 27 (WebCore::NavigatorGamepad::gamepadAtIndex):
 28 * Modules/gamepad/NavigatorGamepad.h:
 29
1302014-07-08 Brady Eidson <beidson@apple.com>
231
332 DOMWindows should register themselves with the GamepadManager when they have event listeners

Source/WebCore/Modules/gamepad/GamepadManager.cpp

2727
2828#if ENABLE(GAMEPAD)
2929
 30#include "DOMWindow.h"
 31#include "Document.h"
3032#include "Gamepad.h"
 33#include "GamepadEvent.h"
3134#include "GamepadProvider.h"
3235#include "Logging.h"
3336#include "NavigatorGamepad.h"

3538
3639namespace WebCore {
3740
 41static NavigatorGamepad* navigatorGamepadFromDOMWindow(DOMWindow* window)
 42{
 43 Navigator* navigator = window->navigator();
 44 if (!navigator)
 45 return nullptr;
 46
 47 return NavigatorGamepad::from(navigator);
 48}
 49
3850GamepadManager& GamepadManager::shared()
3951{
4052 static NeverDestroyed<GamepadManager> sharedManager;

@@GamepadManager::GamepadManager()
4860
4961void GamepadManager::platformGamepadConnected(PlatformGamepad& platformGamepad)
5062{
51  for (auto& navigator : m_navigators) {
52  if (!m_gamepadBlindNavigators.contains(navigator))
53  navigator->gamepadConnected(platformGamepad);
 63 // Notify blind Navigators and Windows about all gamepads except for this one.
 64 for (auto* gamepad : GamepadProvider::shared().platformGamepads()) {
 65 if (!gamepad || gamepad == &platformGamepad)
 66 continue;
5467
55  // FIXME: Fire connected event to all pages with listeners.
 68 makeGamepadVisible(*gamepad, m_gamepadBlindNavigators, m_gamepadBlindDOMWindows);
5669 }
5770
58  makeGamepadsVisibileToBlindNavigators();
 71 m_gamepadBlindNavigators.clear();
 72 m_gamepadBlindDOMWindows.clear();
 73
 74 // Notify everyone of this new gamepad
 75 makeGamepadVisible(platformGamepad, m_navigators, m_domWindows);
5976}
6077
6178void GamepadManager::platformGamepadDisconnected(PlatformGamepad& platformGamepad)
6279{
63  for (auto& navigator : m_navigators) {
64  if (!m_gamepadBlindNavigators.contains(navigator))
65  navigator->gamepadDisconnected(platformGamepad);
 80 Vector<DOMWindow*> domWindowVector;
 81 copyToVector(m_domWindows, domWindowVector);
 82
 83 HashSet<NavigatorGamepad*> notifiedNavigators;
6684
67  // FIXME: Fire disconnected event to all pages with listeners.
 85 // Handle the disconnect for all DOMWindows with event listeners and their Navigators.
 86 for (auto* window : domWindowVector) {
 87 // Event dispatch might have made this window go away.
 88 if (!m_domWindows.contains(window))
 89 continue;
 90
 91 NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
 92 if (!navigator)
 93 continue;
 94
 95 // If this Navigator hasn't seen gamepads yet then its Window should not get the disconnect event.
 96 if (m_gamepadBlindNavigators.contains(navigator))
 97 continue;
 98
 99 RefPtr<Gamepad> gamepad = navigator->gamepadAtIndex(platformGamepad.index());
 100 ASSERT(gamepad);
 101
 102 navigator->gamepadDisconnected(platformGamepad);
 103 notifiedNavigators.add(navigator);
 104
 105 window->dispatchEvent(GamepadEvent::create(eventNames().gamepaddisconnectedEvent, gamepad.get()), window->document());
 106 }
 107
 108 // Notify all the Navigators that haven't already been notified.
 109 for (auto* navigator : m_navigators) {
 110 if (!notifiedNavigators.contains(navigator))
 111 navigator->gamepadDisconnected(platformGamepad);
68112 }
69113}
70114
71115void GamepadManager::platformGamepadInputActivity()
72116{
73  makeGamepadsVisibileToBlindNavigators();
 117 if (m_gamepadBlindNavigators.isEmpty() && m_gamepadBlindDOMWindows.isEmpty())
 118 return;
 119
 120 for (auto* gamepad : GamepadProvider::shared().platformGamepads())
 121 makeGamepadVisible(*gamepad, m_gamepadBlindNavigators, m_gamepadBlindDOMWindows);
 122
 123 m_gamepadBlindNavigators.clear();
 124 m_gamepadBlindDOMWindows.clear();
74125}
75126
76 void GamepadManager::makeGamepadsVisibileToBlindNavigators()
 127void GamepadManager::makeGamepadVisible(PlatformGamepad& platformGamepad, HashSet<NavigatorGamepad*>& navigatorSet, HashSet<DOMWindow*>& domWindowSet)
77128{
78  for (auto& navigator : m_gamepadBlindNavigators) {
79  // FIXME: Here we notify a blind Navigator of each existing gamepad.
80  // But we also need to fire the connected event to its corresponding DOMWindow objects.
81  for (auto& platformGamepad : GamepadProvider::shared().platformGamepads()) {
82  if (platformGamepad)
83  navigator->gamepadConnected(*platformGamepad);
84  }
85  }
 129 if (navigatorSet.isEmpty() && domWindowSet.isEmpty())
 130 return;
86131
87  m_gamepadBlindNavigators.clear();
 132 for (auto* navigator : navigatorSet)
 133 navigator->gamepadConnected(platformGamepad);
 134
 135 Vector<DOMWindow*> domWindowVector;
 136 copyToVector(domWindowSet, domWindowVector);
 137
 138 for (auto* window : domWindowVector) {
 139 // Event dispatch might have made this window go away.
 140 if (!m_domWindows.contains(window))
 141 continue;
 142
 143 NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
 144 if (!navigator)
 145 continue;
 146
 147 RefPtr<Gamepad> gamepad = navigator->gamepadAtIndex(platformGamepad.index());
 148 ASSERT(gamepad);
 149
 150 window->dispatchEvent(GamepadEvent::create(eventNames().gamepadconnectedEvent, gamepad.get()), window->document());
 151 }
88152}
89153
90154void GamepadManager::registerNavigator(NavigatorGamepad* navigator)

@@void GamepadManager::registerDOMWindow(DOMWindow* window)
116180 ASSERT(!m_domWindows.contains(window));
117181 m_domWindows.add(window);
118182
 183 // Anytime we register a DOMWindow, we should also double check that its NavigatorGamepad is registered.
 184 NavigatorGamepad* navigator = navigatorGamepadFromDOMWindow(window);
 185 ASSERT(navigator);
 186
 187 if (m_navigators.add(navigator).isNewEntry)
 188 m_gamepadBlindNavigators.add(navigator);
 189
 190 // If this DOMWindow's NavigatorGamepad was already registered but was still blind,
 191 // then this DOMWindow should be blind.
 192 if (m_gamepadBlindNavigators.contains(navigator))
 193 m_gamepadBlindDOMWindows.add(window);
 194
119195 maybeStartMonitoringGamepads();
120196}
121197

@@void GamepadManager::unregisterDOMWindow(DOMWindow* window)
125201
126202 ASSERT(m_domWindows.contains(window));
127203 m_domWindows.remove(window);
 204 m_gamepadBlindDOMWindows.remove(window);
128205
129206 maybeStopMonitoringGamepads();
130207}

Source/WebCore/Modules/gamepad/GamepadManager.h

3232#include <wtf/HashSet.h>
3333#include <wtf/NeverDestroyed.h>
3434#include <wtf/RefPtr.h>
 35#include <wtf/text/AtomicString.h>
3536
3637namespace WebCore {
3738

@@public:
5758private:
5859 GamepadManager();
5960
60  void makeGamepadsVisibileToBlindNavigators();
 61 void makeGamepadVisible(PlatformGamepad&, HashSet<NavigatorGamepad*>&, HashSet<DOMWindow*>&);
 62 void dispatchGamepadEvent(const WTF::AtomicString& eventName, PlatformGamepad&);
6163
6264 void maybeStartMonitoringGamepads();
6365 void maybeStopMonitoringGamepads();

@@private:
6769 HashSet<NavigatorGamepad*> m_navigators;
6870 HashSet<NavigatorGamepad*> m_gamepadBlindNavigators;
6971 HashSet<DOMWindow*> m_domWindows;
 72 HashSet<DOMWindow*> m_gamepadBlindDOMWindows;
7073};
7174
7275} // namespace WebCore

Source/WebCore/Modules/gamepad/NavigatorGamepad.cpp

@@NavigatorGamepad* NavigatorGamepad::from(Navigator* navigator)
7272 return supplement;
7373}
7474
 75Gamepad* NavigatorGamepad::gamepadAtIndex(unsigned index)
 76{
 77 if (index >= m_gamepads.size())
 78 return nullptr;
 79 return m_gamepads[index].get();
 80}
 81
7582const Vector<RefPtr<Gamepad>>& NavigatorGamepad::getGamepads(Navigator* navigator)
7683{
7784 return NavigatorGamepad::from(navigator)->gamepads();

Source/WebCore/Modules/gamepad/NavigatorGamepad.h

@@public:
5353 void gamepadConnected(PlatformGamepad&);
5454 void gamepadDisconnected(PlatformGamepad&);
5555
 56 Gamepad* gamepadAtIndex(unsigned index);
 57
5658private:
5759 static const char* supplementName();
5860