OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011, Google Inc. All rights reserved. | 2 * Copyright (C) 2011, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are met: | 5 * modification, are permitted provided that the following conditions are met: |
6 * | 6 * |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 | 145 |
146 if (!m_gamepads) | 146 if (!m_gamepads) |
147 m_gamepads = GamepadList::create(); | 147 m_gamepads = GamepadList::create(); |
148 | 148 |
149 Gamepad* gamepad = m_gamepads->item(change.index); | 149 Gamepad* gamepad = m_gamepads->item(change.index); |
150 if (!gamepad) | 150 if (!gamepad) |
151 gamepad = Gamepad::create(); | 151 gamepad = Gamepad::create(); |
152 sampleGamepad(change.index, *gamepad, change.pad); | 152 sampleGamepad(change.index, *gamepad, change.pad); |
153 m_gamepads->set(change.index, gamepad); | 153 m_gamepads->set(change.index, gamepad); |
154 | 154 |
155 const AtomicString& eventName = change.pad.connected ? EventTypeNames::gamep adconnected : EventTypeNames::gamepaddisconnected; | 155 m_pendingEvents.append(gamepad); |
156 m_dispatchOneEventRunner.runAsync(); | |
157 } | |
158 | |
159 void NavigatorGamepad::dispatchOneEvent() | |
160 { | |
161 ASSERT(window()); | |
162 ASSERT(!m_pendingEvents.isEmpty()); | |
163 | |
164 Gamepad* gamepad = m_pendingEvents.takeFirst(); | |
165 const AtomicString& eventName = gamepad->connected() ? EventTypeNames::gamep adconnected : EventTypeNames::gamepaddisconnected; | |
156 window()->dispatchEvent(GamepadEvent::create(eventName, false, true, gamepad )); | 166 window()->dispatchEvent(GamepadEvent::create(eventName, false, true, gamepad )); |
167 | |
168 if (!m_pendingEvents.isEmpty()) | |
169 m_dispatchOneEventRunner.runAsync(); | |
157 } | 170 } |
158 | 171 |
159 NavigatorGamepad::NavigatorGamepad(LocalFrame* frame) | 172 NavigatorGamepad::NavigatorGamepad(LocalFrame* frame) |
160 : DOMWindowProperty(frame) | 173 : DOMWindowProperty(frame) |
161 , DeviceEventControllerBase(frame ? frame->page() : 0) | 174 , DeviceEventControllerBase(frame ? frame->page() : 0) |
162 , DOMWindowLifecycleObserver(frame ? frame->domWindow() : 0) | 175 , DOMWindowLifecycleObserver(frame ? frame->domWindow() : 0) |
176 , m_dispatchOneEventRunner(this, &NavigatorGamepad::dispatchOneEvent) | |
163 { | 177 { |
164 } | 178 } |
165 | 179 |
166 NavigatorGamepad::~NavigatorGamepad() | 180 NavigatorGamepad::~NavigatorGamepad() |
167 { | 181 { |
168 } | 182 } |
169 | 183 |
170 const char* NavigatorGamepad::supplementName() | 184 const char* NavigatorGamepad::supplementName() |
171 { | 185 { |
172 return "NavigatorGamepad"; | 186 return "NavigatorGamepad"; |
173 } | 187 } |
174 | 188 |
175 void NavigatorGamepad::willDestroyGlobalObjectInFrame() | 189 void NavigatorGamepad::willDestroyGlobalObjectInFrame() |
176 { | 190 { |
177 stopUpdating(); | 191 stopUpdating(); |
178 DOMWindowProperty::willDestroyGlobalObjectInFrame(); | 192 DOMWindowProperty::willDestroyGlobalObjectInFrame(); |
179 } | 193 } |
180 | 194 |
181 void NavigatorGamepad::willDetachGlobalObjectFromFrame() | 195 void NavigatorGamepad::willDetachGlobalObjectFromFrame() |
182 { | 196 { |
183 stopUpdating(); | 197 stopUpdating(); |
184 DOMWindowProperty::willDetachGlobalObjectFromFrame(); | 198 DOMWindowProperty::willDetachGlobalObjectFromFrame(); |
185 } | 199 } |
186 | 200 |
187 void NavigatorGamepad::registerWithDispatcher() | 201 void NavigatorGamepad::registerWithDispatcher() |
188 { | 202 { |
203 m_dispatchOneEventRunner.resume(); | |
189 GamepadDispatcher::instance().addController(this); | 204 GamepadDispatcher::instance().addController(this); |
190 } | 205 } |
191 | 206 |
192 void NavigatorGamepad::unregisterWithDispatcher() | 207 void NavigatorGamepad::unregisterWithDispatcher() |
193 { | 208 { |
209 m_dispatchOneEventRunner.suspend(); | |
194 GamepadDispatcher::instance().removeController(this); | 210 GamepadDispatcher::instance().removeController(this); |
195 } | 211 } |
abarth-chromium
2014/07/07 22:11:04
I'd probably move one of these to be after the cal
| |
196 | 212 |
197 bool NavigatorGamepad::hasLastData() | 213 bool NavigatorGamepad::hasLastData() |
198 { | 214 { |
199 // Gamepad data is polled instead of pushed. | 215 // Gamepad data is polled instead of pushed. |
200 return false; | 216 return false; |
201 } | 217 } |
202 | 218 |
203 static bool isGamepadEvent(const AtomicString& eventType) | 219 static bool isGamepadEvent(const AtomicString& eventType) |
204 { | 220 { |
205 return eventType == EventTypeNames::gamepadconnected || eventType == EventTy peNames::gamepaddisconnected; | 221 return eventType == EventTypeNames::gamepadconnected || eventType == EventTy peNames::gamepaddisconnected; |
206 } | 222 } |
207 | 223 |
208 void NavigatorGamepad::didAddEventListener(LocalDOMWindow*, const AtomicString& eventType) | 224 void NavigatorGamepad::didAddEventListener(LocalDOMWindow*, const AtomicString& eventType) |
209 { | 225 { |
210 if (RuntimeEnabledFeatures::gamepadEnabled() && isGamepadEvent(eventType)) { | 226 if (RuntimeEnabledFeatures::gamepadEnabled() && isGamepadEvent(eventType)) { |
211 if (page() && page()->visibilityState() == PageVisibilityStateVisible) | 227 if (page() && page()->visibilityState() == PageVisibilityStateVisible) |
212 startUpdating(); | 228 startUpdating(); |
213 m_hasEventListener = true; | 229 m_hasEventListener = true; |
214 } | 230 } |
215 } | 231 } |
216 | 232 |
217 void NavigatorGamepad::didRemoveEventListener(LocalDOMWindow* window, const Atom icString& eventType) | 233 void NavigatorGamepad::didRemoveEventListener(LocalDOMWindow* window, const Atom icString& eventType) |
218 { | 234 { |
219 if (isGamepadEvent(eventType) | 235 if (isGamepadEvent(eventType) |
220 && !window->hasEventListeners(EventTypeNames::gamepadconnected) | 236 && !window->hasEventListeners(EventTypeNames::gamepadconnected) |
221 && !window->hasEventListeners(EventTypeNames::gamepaddisconnected)) { | 237 && !window->hasEventListeners(EventTypeNames::gamepaddisconnected)) { |
222 m_hasEventListener = false; | 238 didRemoveGamepadEventListeners(); |
223 } | 239 } |
224 } | 240 } |
225 | 241 |
226 void NavigatorGamepad::didRemoveAllEventListeners(LocalDOMWindow*) | 242 void NavigatorGamepad::didRemoveAllEventListeners(LocalDOMWindow*) |
227 { | 243 { |
244 didRemoveGamepadEventListeners(); | |
245 } | |
246 | |
247 void NavigatorGamepad::didRemoveGamepadEventListeners() | |
248 { | |
228 m_hasEventListener = false; | 249 m_hasEventListener = false; |
250 m_dispatchOneEventRunner.stop(); | |
251 m_pendingEvents.clear(); | |
229 } | 252 } |
230 | 253 |
231 void NavigatorGamepad::pageVisibilityChanged() | 254 void NavigatorGamepad::pageVisibilityChanged() |
232 { | 255 { |
233 // Inform the embedder whether it needs to provide gamepad data for us. | 256 // Inform the embedder whether it needs to provide gamepad data for us. |
234 if (page()->visibilityState() == PageVisibilityStateVisible && (m_hasEventLi stener || m_gamepads || m_webkitGamepads)) | 257 bool visible = page()->visibilityState() == PageVisibilityStateVisible; |
258 if (visible && (m_hasEventListener || m_gamepads || m_webkitGamepads)) | |
235 startUpdating(); | 259 startUpdating(); |
236 else | 260 else |
237 stopUpdating(); | 261 stopUpdating(); |
262 | |
263 if (!visible || !m_hasEventListener) | |
264 return; | |
265 | |
266 // Tell the page what has changed. m_gamepads contains the state before we b ecame hidden. | |
267 // We create a new snapshot and compare them. | |
268 GamepadList* oldGamepads = m_gamepads.release(); | |
269 gamepads(); | |
270 GamepadList* newGamepads = m_gamepads.get(); | |
271 ASSERT(newGamepads); | |
272 | |
273 for (unsigned i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) { | |
274 Gamepad* oldGamepad = oldGamepads ? oldGamepads->item(i) : 0; | |
275 Gamepad* newGamepad = newGamepads->item(i); | |
276 bool oldWasConnected = oldGamepad && oldGamepad->connected(); | |
277 bool newIsConnected = newGamepad && newGamepad->connected(); | |
278 bool connectedGamepadChanged = oldWasConnected && newIsConnected && oldG amepad->id() != newGamepad->id(); | |
279 if (connectedGamepadChanged || (oldWasConnected && !newIsConnected)) { | |
280 oldGamepad->setConnected(false); | |
281 m_pendingEvents.append(oldGamepad); | |
282 } | |
283 if (connectedGamepadChanged || (!oldWasConnected && newIsConnected)) { | |
284 m_pendingEvents.append(newGamepad); | |
285 } | |
286 | |
287 m_dispatchOneEventRunner.runAsync(); | |
288 } | |
238 } | 289 } |
239 | 290 |
240 } // namespace WebCore | 291 } // namespace WebCore |
OLD | NEW |