Chromium Code Reviews| Index: Source/modules/gamepad/NavigatorGamepad.cpp |
| diff --git a/Source/modules/gamepad/NavigatorGamepad.cpp b/Source/modules/gamepad/NavigatorGamepad.cpp |
| index 6333946be8a506ee5138fe2e9e63869afac7b3f6..58d628ae15354b3a1819b55745de5d600e6bfa37 100644 |
| --- a/Source/modules/gamepad/NavigatorGamepad.cpp |
| +++ b/Source/modules/gamepad/NavigatorGamepad.cpp |
| @@ -152,14 +152,28 @@ void NavigatorGamepad::didUpdateData() |
| sampleGamepad(change.index, *gamepad, change.pad); |
| m_gamepads->set(change.index, gamepad); |
| - const AtomicString& eventName = change.pad.connected ? EventTypeNames::gamepadconnected : EventTypeNames::gamepaddisconnected; |
| + m_pendingEvents.append(gamepad); |
| + m_dispatchOneEventRunner.runAsync(); |
| +} |
| + |
| +void NavigatorGamepad::dispatchOneEvent() |
| +{ |
| + ASSERT(window()); |
| + ASSERT(!m_pendingEvents.isEmpty()); |
| + |
| + Gamepad* gamepad = m_pendingEvents.takeFirst(); |
| + const AtomicString& eventName = gamepad->connected() ? EventTypeNames::gamepadconnected : EventTypeNames::gamepaddisconnected; |
| window()->dispatchEvent(GamepadEvent::create(eventName, false, true, gamepad)); |
| + |
| + if (!m_pendingEvents.isEmpty()) |
| + m_dispatchOneEventRunner.runAsync(); |
| } |
| NavigatorGamepad::NavigatorGamepad(LocalFrame* frame) |
| : DOMWindowProperty(frame) |
| , DeviceEventControllerBase(frame ? frame->page() : 0) |
| , DOMWindowLifecycleObserver(frame ? frame->domWindow() : 0) |
| + , m_dispatchOneEventRunner(this, &NavigatorGamepad::dispatchOneEvent) |
| { |
| } |
| @@ -186,11 +200,13 @@ void NavigatorGamepad::willDetachGlobalObjectFromFrame() |
| void NavigatorGamepad::registerWithDispatcher() |
| { |
| + m_dispatchOneEventRunner.resume(); |
| GamepadDispatcher::instance().addController(this); |
| } |
| void NavigatorGamepad::unregisterWithDispatcher() |
| { |
| + m_dispatchOneEventRunner.suspend(); |
| GamepadDispatcher::instance().removeController(this); |
| } |
|
abarth-chromium
2014/07/07 22:11:04
I'd probably move one of these to be after the cal
|
| @@ -219,22 +235,57 @@ void NavigatorGamepad::didRemoveEventListener(LocalDOMWindow* window, const Atom |
| if (isGamepadEvent(eventType) |
| && !window->hasEventListeners(EventTypeNames::gamepadconnected) |
| && !window->hasEventListeners(EventTypeNames::gamepaddisconnected)) { |
| - m_hasEventListener = false; |
| + didRemoveGamepadEventListeners(); |
| } |
| } |
| void NavigatorGamepad::didRemoveAllEventListeners(LocalDOMWindow*) |
| { |
| + didRemoveGamepadEventListeners(); |
| +} |
| + |
| +void NavigatorGamepad::didRemoveGamepadEventListeners() |
| +{ |
| m_hasEventListener = false; |
| + m_dispatchOneEventRunner.stop(); |
| + m_pendingEvents.clear(); |
| } |
| void NavigatorGamepad::pageVisibilityChanged() |
| { |
| // Inform the embedder whether it needs to provide gamepad data for us. |
| - if (page()->visibilityState() == PageVisibilityStateVisible && (m_hasEventListener || m_gamepads || m_webkitGamepads)) |
| + bool visible = page()->visibilityState() == PageVisibilityStateVisible; |
| + if (visible && (m_hasEventListener || m_gamepads || m_webkitGamepads)) |
| startUpdating(); |
| else |
| stopUpdating(); |
| + |
| + if (!visible || !m_hasEventListener) |
| + return; |
| + |
| + // Tell the page what has changed. m_gamepads contains the state before we became hidden. |
| + // We create a new snapshot and compare them. |
| + GamepadList* oldGamepads = m_gamepads.release(); |
| + gamepads(); |
| + GamepadList* newGamepads = m_gamepads.get(); |
| + ASSERT(newGamepads); |
| + |
| + for (unsigned i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) { |
| + Gamepad* oldGamepad = oldGamepads ? oldGamepads->item(i) : 0; |
| + Gamepad* newGamepad = newGamepads->item(i); |
| + bool oldWasConnected = oldGamepad && oldGamepad->connected(); |
| + bool newIsConnected = newGamepad && newGamepad->connected(); |
| + bool connectedGamepadChanged = oldWasConnected && newIsConnected && oldGamepad->id() != newGamepad->id(); |
| + if (connectedGamepadChanged || (oldWasConnected && !newIsConnected)) { |
| + oldGamepad->setConnected(false); |
| + m_pendingEvents.append(oldGamepad); |
| + } |
| + if (connectedGamepadChanged || (!oldWasConnected && newIsConnected)) { |
| + m_pendingEvents.append(newGamepad); |
| + } |
| + |
| + m_dispatchOneEventRunner.runAsync(); |
| + } |
| } |
| } // namespace WebCore |