Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(624)

Side by Side Diff: ui/base/gestures/gesture_recognizer_impl.cc

Issue 11188012: gesture recognizer: Remove the touch-event queue. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tot-merge Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/base/gestures/gesture_recognizer_impl.h ('k') | ui/base/gestures/gesture_sequence.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/base/gestures/gesture_recognizer_impl.h" 5 #include "ui/base/gestures/gesture_recognizer_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "ui/base/events/event.h" 10 #include "ui/base/events/event.h"
11 #include "ui/base/events/event_constants.h" 11 #include "ui/base/events/event_constants.h"
12 #include "ui/base/gestures/gesture_configuration.h" 12 #include "ui/base/gestures/gesture_configuration.h"
13 #include "ui/base/gestures/gesture_sequence.h" 13 #include "ui/base/gestures/gesture_sequence.h"
14 #include "ui/base/gestures/gesture_types.h" 14 #include "ui/base/gestures/gesture_types.h"
15 15
16 namespace ui { 16 namespace ui {
17 17
18 namespace { 18 namespace {
19 19
20 // This is used to pop a std::queue when returning from a function.
21 class ScopedPop {
22 public:
23 explicit ScopedPop(std::queue<TouchEvent*>* queue) : queue_(queue) {
24 }
25
26 ~ScopedPop() {
27 delete queue_->front();
28 queue_->pop();
29 }
30
31 private:
32 std::queue<TouchEvent*>* queue_;
33 DISALLOW_COPY_AND_ASSIGN(ScopedPop);
34 };
35
36 // CancelledTouchEvent mirrors a TouchEvent object. 20 // CancelledTouchEvent mirrors a TouchEvent object.
37 class MirroredTouchEvent : public TouchEvent { 21 class MirroredTouchEvent : public TouchEvent {
38 public: 22 public:
39 explicit MirroredTouchEvent(const TouchEvent* real) 23 explicit MirroredTouchEvent(const TouchEvent* real)
40 : TouchEvent(real->type(), 24 : TouchEvent(real->type(),
41 real->location(), 25 real->location(),
42 real->touch_id(), 26 real->touch_id(),
43 real->time_stamp()) { 27 real->time_stamp()) {
44 set_flags(real->flags()); 28 set_flags(real->flags());
45 set_radius(real->radius_x(), real->radius_y()); 29 set_radius(real->radius_x(), real->radius_y());
46 set_rotation_angle(real->rotation_angle()); 30 set_rotation_angle(real->rotation_angle());
47 set_force(real->force()); 31 set_force(real->force());
48 } 32 }
49 33
50 virtual ~MirroredTouchEvent() { 34 virtual ~MirroredTouchEvent() {
51 } 35 }
52 36
53 private: 37 private:
54 DISALLOW_COPY_AND_ASSIGN(MirroredTouchEvent); 38 DISALLOW_COPY_AND_ASSIGN(MirroredTouchEvent);
55 }; 39 };
56 40
57 class QueuedTouchEvent : public MirroredTouchEvent {
58 public:
59 QueuedTouchEvent(const TouchEvent* real, EventResult result)
60 : MirroredTouchEvent(real),
61 result_(result) {
62 }
63
64 virtual ~QueuedTouchEvent() {
65 }
66
67 EventResult result() const { return result_; }
68
69 private:
70 EventResult result_;
71
72 DISALLOW_COPY_AND_ASSIGN(QueuedTouchEvent);
73 };
74
75 // A mirrored event, except for the type, which is always ET_TOUCH_CANCELLED. 41 // A mirrored event, except for the type, which is always ET_TOUCH_CANCELLED.
76 class CancelledTouchEvent : public MirroredTouchEvent { 42 class CancelledTouchEvent : public MirroredTouchEvent {
77 public: 43 public:
78 explicit CancelledTouchEvent(const TouchEvent* src) 44 explicit CancelledTouchEvent(const TouchEvent* src)
79 : MirroredTouchEvent(src) { 45 : MirroredTouchEvent(src) {
80 set_type(ET_TOUCH_CANCELLED); 46 set_type(ET_TOUCH_CANCELLED);
81 } 47 }
82 48
83 virtual ~CancelledTouchEvent() {} 49 virtual ~CancelledTouchEvent() {}
84 50
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 //////////////////////////////////////////////////////////////////////////////// 98 ////////////////////////////////////////////////////////////////////////////////
133 // GestureRecognizerImpl, public: 99 // GestureRecognizerImpl, public:
134 100
135 GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper) 101 GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper)
136 : helper_(helper) { 102 : helper_(helper) {
137 gesture_consumer_ignorer_.reset(new GestureConsumerIgnorer()); 103 gesture_consumer_ignorer_.reset(new GestureConsumerIgnorer());
138 } 104 }
139 105
140 GestureRecognizerImpl::~GestureRecognizerImpl() { 106 GestureRecognizerImpl::~GestureRecognizerImpl() {
141 STLDeleteValues(&consumer_sequence_); 107 STLDeleteValues(&consumer_sequence_);
142 STLDeleteValues(&event_queue_);
143 } 108 }
144 109
145 // Checks if this finger is already down, if so, returns the current target. 110 // Checks if this finger is already down, if so, returns the current target.
146 // Otherwise, returns NULL. 111 // Otherwise, returns NULL.
147 GestureConsumer* GestureRecognizerImpl::GetTouchLockedTarget( 112 GestureConsumer* GestureRecognizerImpl::GetTouchLockedTarget(
148 TouchEvent* event) { 113 TouchEvent* event) {
149 return touch_id_target_[event->touch_id()]; 114 return touch_id_target_[event->touch_id()];
150 } 115 }
151 116
152 GestureConsumer* GestureRecognizerImpl::GetTargetForGestureEvent( 117 GestureConsumer* GestureRecognizerImpl::GetTargetForGestureEvent(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 i->second = gesture_consumer_ignorer_.get(); 166 i->second = gesture_consumer_ignorer_.get();
202 } 167 }
203 } 168 }
204 169
205 // Transer events from |current_consumer| to |new_consumer|. 170 // Transer events from |current_consumer| to |new_consumer|.
206 if (current_consumer && new_consumer) { 171 if (current_consumer && new_consumer) {
207 TransferTouchIdToConsumerMap(current_consumer, new_consumer, 172 TransferTouchIdToConsumerMap(current_consumer, new_consumer,
208 &touch_id_target_); 173 &touch_id_target_);
209 TransferTouchIdToConsumerMap(current_consumer, new_consumer, 174 TransferTouchIdToConsumerMap(current_consumer, new_consumer,
210 &touch_id_target_for_gestures_); 175 &touch_id_target_for_gestures_);
211 TransferConsumer(current_consumer, new_consumer, &event_queue_);
212 TransferConsumer(current_consumer, new_consumer, &consumer_sequence_); 176 TransferConsumer(current_consumer, new_consumer, &consumer_sequence_);
213 } 177 }
214 } 178 }
215 179
216 bool GestureRecognizerImpl::GetLastTouchPointForTarget( 180 bool GestureRecognizerImpl::GetLastTouchPointForTarget(
217 GestureConsumer* consumer, 181 GestureConsumer* consumer,
218 gfx::Point* point) { 182 gfx::Point* point) {
219 if (consumer_sequence_.count(consumer) == 0) 183 if (consumer_sequence_.count(consumer) == 0)
220 return false; 184 return false;
221 185
(...skipping 27 matching lines...) Expand all
249 if (event.type() == ui::ET_TOUCH_RELEASED || 213 if (event.type() == ui::ET_TOUCH_RELEASED ||
250 event.type() == ui::ET_TOUCH_CANCELLED) { 214 event.type() == ui::ET_TOUCH_CANCELLED) {
251 touch_id_target_[event.touch_id()] = NULL; 215 touch_id_target_[event.touch_id()] = NULL;
252 } else { 216 } else {
253 touch_id_target_[event.touch_id()] = target; 217 touch_id_target_[event.touch_id()] = target;
254 if (target) 218 if (target)
255 touch_id_target_for_gestures_[event.touch_id()] = target; 219 touch_id_target_for_gestures_[event.touch_id()] = target;
256 } 220 }
257 } 221 }
258 222
259 GestureSequence::Gestures* GestureRecognizerImpl::AdvanceTouchQueueByOne(
260 GestureConsumer* consumer,
261 ui::EventResult result) {
262 CHECK(event_queue_[consumer]);
263 CHECK(!event_queue_[consumer]->empty());
264
265 ScopedPop pop(event_queue_[consumer]);
266 TouchEvent* event = event_queue_[consumer]->front();
267 GestureSequence* sequence = GetGestureSequenceForConsumer(consumer);
268 if (result != ER_UNHANDLED &&
269 event->type() == ET_TOUCH_RELEASED) {
270 // A touch release was was processed (e.g. preventDefault()ed by a
271 // web-page), but we still need to process a touch cancel.
272 CancelledTouchEvent cancelled(event);
273 return sequence->ProcessTouchEventForGesture(cancelled,
274 ER_UNHANDLED);
275 }
276 return sequence->ProcessTouchEventForGesture(*event, result);
277 }
278
279 GestureSequence::Gestures* GestureRecognizerImpl::ProcessTouchEventForGesture( 223 GestureSequence::Gestures* GestureRecognizerImpl::ProcessTouchEventForGesture(
280 const TouchEvent& event, 224 const TouchEvent& event,
281 ui::EventResult result, 225 ui::EventResult result,
282 GestureConsumer* target) { 226 GestureConsumer* target) {
283 if (event_queue_[target] && event_queue_[target]->size() > 0) {
284 // There are some queued touch-events for this target. Processing |event|
285 // before those queued events will result in unexpected gestures. So
286 // postpone the processing of the events until the queued events have been
287 // processed.
288 event_queue_[target]->push(new QueuedTouchEvent(&event, result));
289 return NULL;
290 }
291
292 SetupTargets(event, target); 227 SetupTargets(event, target);
293
294 GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target); 228 GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target);
295 return gesture_sequence->ProcessTouchEventForGesture(event, result); 229 return gesture_sequence->ProcessTouchEventForGesture(event, result);
296 } 230 }
297 231
298 void GestureRecognizerImpl::QueueTouchEventForGesture(GestureConsumer* consumer, 232 void GestureRecognizerImpl::CleanupStateForConsumer(GestureConsumer* consumer) {
299 const TouchEvent& event) {
300 if (!event_queue_[consumer])
301 event_queue_[consumer] = new std::queue<TouchEvent*>();
302 event_queue_[consumer]->push(
303 new QueuedTouchEvent(&event, ER_ASYNC));
304
305 SetupTargets(event, consumer);
306 }
307
308 GestureSequence::Gestures* GestureRecognizerImpl::AdvanceTouchQueue(
309 GestureConsumer* consumer,
310 bool processed) {
311 if (!event_queue_[consumer] || event_queue_[consumer]->empty()) {
312 LOG(ERROR) << "Trying to advance an empty gesture queue for " << consumer;
313 return NULL;
314 }
315
316 scoped_ptr<GestureSequence::Gestures> gestures(
317 AdvanceTouchQueueByOne(consumer, processed ? ER_HANDLED :
318 ER_UNHANDLED));
319
320 // Are there any queued touch-events that should be auto-dequeued?
321 while (!event_queue_[consumer]->empty()) {
322 QueuedTouchEvent* event =
323 static_cast<QueuedTouchEvent*>(event_queue_[consumer]->front());
324 if (event->result() == ER_ASYNC)
325 break;
326
327 scoped_ptr<GestureSequence::Gestures> current_gestures(
328 AdvanceTouchQueueByOne(consumer, event->result()));
329 if (current_gestures.get()) {
330 if (!gestures.get()) {
331 gestures.reset(current_gestures.release());
332 } else {
333 gestures->insert(gestures->end(), current_gestures->begin(),
334 current_gestures->end());
335 // The gestures in |current_gestures| are now owned by |gestures|. Make
336 // sure they don't get freed with |current_gestures|.
337 current_gestures->weak_clear();
338 }
339 }
340 }
341
342 return gestures.release();
343 }
344
345 void GestureRecognizerImpl::FlushTouchQueue(GestureConsumer* consumer) {
346 if (consumer_sequence_.count(consumer)) { 233 if (consumer_sequence_.count(consumer)) {
347 delete consumer_sequence_[consumer]; 234 delete consumer_sequence_[consumer];
348 consumer_sequence_.erase(consumer); 235 consumer_sequence_.erase(consumer);
349 } 236 }
350 237
351 if (event_queue_.count(consumer)) {
352 delete event_queue_[consumer];
353 event_queue_.erase(consumer);
354 }
355
356 RemoveConsumerFromMap(consumer, &touch_id_target_); 238 RemoveConsumerFromMap(consumer, &touch_id_target_);
357 RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_); 239 RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_);
358 } 240 }
359 241
360 // GestureRecognizer, static 242 // GestureRecognizer, static
361 GestureRecognizer* GestureRecognizer::Create(GestureEventHelper* helper) { 243 GestureRecognizer* GestureRecognizer::Create(GestureEventHelper* helper) {
362 return new GestureRecognizerImpl(helper); 244 return new GestureRecognizerImpl(helper);
363 } 245 }
364 246
365 } // namespace ui 247 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/gestures/gesture_recognizer_impl.h ('k') | ui/base/gestures/gesture_sequence.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698