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

Side by Side Diff: ui/events/gestures/gesture_event_queue.cc

Issue 101933004: Eager Gesture Recognizer (WIP) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Starting work on Android. Created 6 years, 11 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/events/gestures/gesture_event_queue.h"
6 #include "ui/events/gestures/gesture_sequence.h"
7
8 namespace ui {
9
10 GestureEventQueue::GestureWithState::GestureWithState(
11 GestureEvent* event,
12 std::vector<TouchPointState*>& touch_point_states)
13 : event_(event) {
14 touch_point_states_.swap(touch_point_states);
15 }
16
17 GestureEventQueue::GestureWithState::~GestureWithState() {
18 CHECK(event_->IsGestureEvent());
19 }
20
21 GestureEventQueue::GestureEventQueue(GestureEventQueueDelegate* geqd)
22 : gesture_event_queue_delegate_(geqd) {
23 touch_point_states_.resize(GestureSequence::kMaxGesturePoints);
24 acked_touch_point_states_.resize(GestureSequence::kMaxGesturePoints);
25 consumed_touch_point_states_.resize(GestureSequence::kMaxGesturePoints);
26
27 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) {
28 touch_point_states_[i] = new TouchPointState(i);
29 acked_touch_point_states_[i] = new TouchPointState(i);
30 consumed_touch_point_states_[i] = new TouchPointState(i);
31 }
32 }
33
34 GestureEventQueue::~GestureEventQueue() {
35 while (!sequences_.empty()) {
36 delete sequences_.front();
37 sequences_.pop_front();
38 }
39 }
40
41 void GestureEventQueue::OnTouchEvent(const TouchEvent& event) {
42 touch_point_states_[event.touch_id()]->Update(event);
43
44 // TODO - remove this
45 if (!sequences_.empty() && !(*sequences_.begin())->empty()) {
46 LOG(ERROR) << "length of first sequence is "
47 << (*sequences_.begin())->size();
48 }
49 }
50
51 void GestureEventQueue::OnTouchEventAck(
52 const TouchEvent& event,
53 EventResult result) {
54 if (result == ER_CONSUMED)
55 consumed_touch_point_states_[event.touch_id()]->Update(event);
56 else
57 acked_touch_point_states_[event.touch_id()]->Update(event);
58
59 DeleteConsumedEvents();
60 SendAckedEvents();
61
62 if (event.type() == ET_TOUCH_RELEASED ||
63 event.type() == ET_TOUCH_CANCELLED) {
64 touch_point_states_[event.touch_id()]->Reset();
65 consumed_touch_point_states_[event.touch_id()]->Reset();
66 acked_touch_point_states_[event.touch_id()]->Reset();
67 }
68 }
69
70 void GestureEventQueue::QueueGestureEvent(
71 GestureEvent* event,
72 TouchPointState::RequiresAck requires_ack) {
73 std::vector<TouchPointState*> tps;
74
75 for (ScopedVector<TouchPointState>::iterator it = touch_point_states_.begin();
76 it != touch_point_states_.end();
77 ++it) {
78 if ((*it)->has_press())
79 tps.push_back((*it)->CopyForGestureType(event->type(), requires_ack));
80 }
81 // Takes ownership of entries in tps.
82 QueueGestureEvent(event, tps);
83 }
84
85 void GestureEventQueue::TimerFired() {
86 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) {
87 if (touch_point_states_[i]->has_press())
88 acked_touch_point_states_[i]->TimerFired();
89 }
90 SendAckedEvents();
91 }
92
93 void GestureEventQueue::TimerCancelled() {
94 for (int i = 0; i < GestureSequence::kMaxGesturePoints; ++i) {
95 if (touch_point_states_[i]->has_press())
96 consumed_touch_point_states_[i]->TimerFired();
97 }
98 DeleteConsumedEvents();
99 SendAckedEvents();
100 }
101
102 void GestureEventQueue::QueueGestureEvent(
103 GestureEvent* event,
104 std::vector<TouchPointState*>& touch_point_states) {
105 CHECK(event->IsGestureEvent()) << "Event of type " << event->type();
106 // If this marks the beginning of a new sequence, construct a new
107 // |Sequence|. Deleted in |OnTouchEventAck|, and |~GestureEventQueue|.
108 if (event->type() == ET_GESTURE_BEGIN && event->details().touch_points() == 1)
109 sequences_.push_back(new Sequence());
110
111 DCHECK(!sequences_.empty()) << "Possibly missing a gesture begin";
112
113 if (sequences_.empty())
114 LOG(ERROR) << "Missing a gesture begin?";
115 // TODO - this shouldn't be necessary...
116 if (sequences_.empty())
117 sequences_.push_back(new Sequence());
118
119 Sequence* sequence = sequences_.back();
120
121 // The GestureWithState takes ownership of the elements of touch_point_states.
122 sequence->push_back(new GestureWithState(event, touch_point_states));
123
124 if (sequences_.empty()) {
125 LOG(ERROR) << "No sequence";
126 } else if ((*sequences_.begin())->empty())
127 LOG(ERROR) << "First sequence empty";
128 else {
129 LOG(ERROR) << "length of first sequence is "
130 << (*sequences_.begin())->size();
131 LOG(ERROR) << "First element is "
132 << (*(*sequences_.begin())->begin())->event()->type();
133 }
134
135 DeleteConsumedEvents();
136 SendAckedEvents();
137 }
138
139 void GestureEventQueue::SendGestureEvent(GestureEvent* event) {
140 gesture_event_queue_delegate_->DispatchGestureEvent(event);
141 }
142
143 bool GestureEventQueue::CanSend(
144 const std::vector<TouchPointState*>& gesture_touches) const {
145 if (gesture_touches.empty())
146 return true;
147 std::vector<TouchPointState*>::const_iterator it;
148 for (it = gesture_touches.begin();
149 it != gesture_touches.end();
150 ++it) {
151 const TouchPointState& current =
152 *acked_touch_point_states_[(*it)->touch_id()];
153
154 if (!current.Contains(*(*it)))
155 return false;
156 }
157 return true;
158 }
159
160 bool GestureEventQueue::CanDelete(
161 const std::vector<TouchPointState*>& gesture_touches) const {
162 if (gesture_touches.empty())
163 return false;
164 std::vector<TouchPointState*>::const_iterator it;
165 for (it = gesture_touches.begin();
166 it != gesture_touches.end();
167 ++it) {
168 const TouchPointState& current =
169 *consumed_touch_point_states_[(*it)->touch_id()];
170 if (!current.HasEmptyIntersection(*(*it)))
171 return true;
172 }
173 return false;
174 }
175
176 void GestureEventQueue::SendAckedEvents() {
177 RemoveEmptyFirstSequence();
178 LOG(ERROR) << "SendAckedEvents";
179 // TODO - should these be DCHECKs?
180 if (sequences_.empty()) {
181 LOG(ERROR) << "sequences_ is empty, bailing";
182 return;
183 }
184 Sequence* sequence = sequences_.front();
185 if (sequence->empty()) {
186 LOG(ERROR) << "sequence is empty, bailing";
187 return;
188 }
189 DCHECK(!sequence->empty());
190 for (Sequence::iterator it = sequence->begin();
191 it != sequence->end();) {
192 GestureEvent* event = (*it)->event();
193 CHECK(event->IsGestureEvent()) << "Event of type " << event->type();
194 if (CanSend((*it)->touch_point_states())) {
195 SendGestureEvent(event);
196 LOG(ERROR) << "SENT! " << event->type();
197 it = sequence->erase(it);
198 LOG(ERROR) << "ERASED!";
199 } else if (event->type() == ET_GESTURE_LONG_PRESS ||
200 event->type() == ET_GESTURE_SHOW_PRESS) {
201 // We don't need to respect the ordering of timed events.
202 ++it;
203 } else {
204 break;
205 }
206 }
207 }
208
209 void GestureEventQueue::DeleteConsumedEvents() {
210 RemoveEmptyFirstSequence();
211 // TODO - should this be a CHECK?
212 if (sequences_.empty())
213 return;
214 Sequence* sequence = sequences_.front();
215 if (sequence->empty())
216 return;
217 DCHECK(!sequence->empty());
218 for (Sequence::iterator it = sequence->begin();
219 it != sequence->end();) {
220 GestureEvent* event = (*it)->event();
221 CHECK(event->IsGestureEvent()) << "Event of type " << event->type();
222 if (CanDelete((*it)->touch_point_states())) {
223 it = sequence->erase(it);
224 } else
225 ++it;
226 }
227 }
228
229 void GestureEventQueue::RemoveEmptyFirstSequence() {
230 // If we've sent or deleted everything in the current sequence, and a new
231 // sequence has started, get rid of the current sequence.
232 if (sequences_.size() > 1 && sequences_.front()->empty()) {
233 delete sequences_.front();
234 sequences_.pop_front();
235 }
236 }
237
238 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/gestures/gesture_event_queue.h ('k') | ui/events/gestures/gesture_event_queue_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698