@@ -19,13 +19,9 @@ class GestureHandlerOrchestrator(
19
19
* traversing view hierarchy and looking for gesture handlers.
20
20
*/
21
21
var minimumAlphaForTraversal = DEFAULT_MIN_ALPHA_FOR_TRAVERSAL
22
-
23
- private val gestureHandlers = arrayOfNulls<GestureHandler <* >? > (SIMULTANEOUS_GESTURE_HANDLER_LIMIT )
24
- private val awaitingHandlers = arrayOfNulls<GestureHandler <* >? > (SIMULTANEOUS_GESTURE_HANDLER_LIMIT )
25
- private val preparedHandlers = arrayOfNulls<GestureHandler <* >? > (SIMULTANEOUS_GESTURE_HANDLER_LIMIT )
26
- private val handlersToCancel = arrayOfNulls<GestureHandler <* >? > (SIMULTANEOUS_GESTURE_HANDLER_LIMIT )
27
- private var gestureHandlersCount = 0
28
- private var awaitingHandlersCount = 0
22
+ private val gestureHandlers = arrayListOf<GestureHandler <* >>()
23
+ private val awaitingHandlers = arrayListOf<GestureHandler <* >>()
24
+ private val preparedHandlers = arrayListOf<GestureHandler <* >>()
29
25
private var isHandlingTouch = false
30
26
private var handlingChangeSemaphore = 0
31
27
private var finishedHandlersCleanupScheduled = false
@@ -60,23 +56,9 @@ class GestureHandlerOrchestrator(
60
56
}
61
57
}
62
58
63
- private inline fun compactHandlersIf (handlers : Array <GestureHandler <* >? >, count : Int , predicate : (handler: GestureHandler <* >? ) -> Boolean ): Int {
64
- var out = 0
65
- for (i in 0 until count) {
66
- if (predicate(handlers[i])) {
67
- handlers[out ++ ] = handlers[i]
68
- }
69
- }
70
- return out
71
- }
72
-
73
59
private fun cleanupFinishedHandlers () {
74
- var shouldCleanEmptyCells = false
75
- for (i in gestureHandlersCount - 1 downTo 0 ) {
76
- val handler = gestureHandlers[i]!!
60
+ for (handler in gestureHandlers.asReversed()) {
77
61
if (isFinished(handler.state) && ! handler.isAwaiting) {
78
- gestureHandlers[i] = null
79
- shouldCleanEmptyCells = true
80
62
handler.reset()
81
63
handler.apply {
82
64
isActive = false
@@ -85,17 +67,14 @@ class GestureHandlerOrchestrator(
85
67
}
86
68
}
87
69
}
88
- if (shouldCleanEmptyCells) {
89
- gestureHandlersCount = compactHandlersIf(gestureHandlers, gestureHandlersCount) { handler ->
90
- handler != null
91
- }
92
- }
70
+
71
+ gestureHandlers.removeAll { isFinished(it.state) && ! it.isAwaiting }
72
+
93
73
finishedHandlersCleanupScheduled = false
94
74
}
95
75
96
76
private fun hasOtherHandlerToWaitFor (handler : GestureHandler <* >): Boolean {
97
- for (i in 0 until gestureHandlersCount) {
98
- val otherHandler = gestureHandlers[i]!!
77
+ for (otherHandler in gestureHandlers) {
99
78
if (! isFinished(otherHandler.state) && shouldHandlerWaitForOther(handler, otherHandler)) {
100
79
return true
101
80
}
@@ -115,19 +94,16 @@ class GestureHandlerOrchestrator(
115
94
}
116
95
117
96
private fun cleanupAwaitingHandlers () {
118
- awaitingHandlersCount = compactHandlersIf(awaitingHandlers, awaitingHandlersCount) { handler ->
119
- handler!! .isAwaiting
120
- }
97
+ awaitingHandlers.removeAll { ! it.isAwaiting }
121
98
}
122
99
123
100
/* package*/
124
101
fun onHandlerStateChange (handler : GestureHandler <* >, newState : Int , prevState : Int ) {
125
102
handlingChangeSemaphore + = 1
126
103
if (isFinished(newState)) {
127
104
// if there were handlers awaiting completion of this handler, we can trigger active state
128
- for (i in 0 until awaitingHandlersCount) {
129
- val otherHandler = awaitingHandlers[i]
130
- if (shouldHandlerWaitForOther(otherHandler!! , handler)) {
105
+ for (otherHandler in awaitingHandlers) {
106
+ if (shouldHandlerWaitForOther(otherHandler, handler)) {
131
107
if (newState == GestureHandler .STATE_END ) {
132
108
// gesture has ended, we need to kill the awaiting handler
133
109
otherHandler.cancel()
@@ -182,21 +158,15 @@ class GestureHandlerOrchestrator(
182
158
shouldResetProgress = true
183
159
activationIndex = this @GestureHandlerOrchestrator.activationIndex++
184
160
}
185
- var toCancelCount = 0
186
- // Cancel all handlers that are required to be cancel upon current handler's activation
187
- for (i in 0 until gestureHandlersCount) {
188
- val otherHandler = gestureHandlers[i]!!
161
+
162
+ for (otherHandler in gestureHandlers.asReversed()) {
189
163
if (shouldHandlerBeCancelledBy(otherHandler, handler)) {
190
- handlersToCancel[toCancelCount ++ ] = otherHandler
164
+ otherHandler.cancel()
191
165
}
192
166
}
193
- for (i in toCancelCount - 1 downTo 0 ) {
194
- handlersToCancel[i]!! .cancel()
195
- }
196
167
197
168
// Clear all awaiting handlers waiting for the current handler to fail
198
- for (i in awaitingHandlersCount - 1 downTo 0 ) {
199
- val otherHandler = awaitingHandlers[i]!!
169
+ for (otherHandler in awaitingHandlers.reversed()) {
200
170
if (shouldHandlerBeCancelledBy(otherHandler, handler)) {
201
171
otherHandler.cancel()
202
172
otherHandler.isAwaiting = false
@@ -218,32 +188,31 @@ class GestureHandlerOrchestrator(
218
188
private fun deliverEventToGestureHandlers (event : MotionEvent ) {
219
189
// Copy handlers to "prepared handlers" array, because the list of active handlers can change
220
190
// as a result of state updates
221
- val handlersCount = gestureHandlersCount
191
+ preparedHandlers.clear()
192
+ preparedHandlers.addAll(gestureHandlers)
222
193
223
- gestureHandlers.copyInto(preparedHandlers, 0 , 0 , handlersCount)
224
194
// We want to deliver events to active handlers first in order of their activation (handlers
225
195
// that activated first will first get event delivered). Otherwise we deliver events in the
226
196
// order in which handlers has been added ("most direct" children goes first). Therefore we rely
227
197
// on Arrays.sort providing a stable sort (as children are registered in order in which they
228
198
// should be tested)
229
- preparedHandlers.sortWith(handlersComparator, 0 , handlersCount )
230
- for (i in 0 until handlersCount ) {
231
- deliverEventToGestureHandler(preparedHandlers[i] !! , event)
199
+ preparedHandlers.sortWith(handlersComparator)
200
+ for (handler in preparedHandlers ) {
201
+ deliverEventToGestureHandler(handler , event)
232
202
}
233
203
}
234
204
235
205
private fun cancelAll () {
236
- for (i in awaitingHandlersCount - 1 downTo 0 ) {
237
- awaitingHandlers[i] !! .cancel()
206
+ for (handler in awaitingHandlers.reversed() ) {
207
+ handler .cancel()
238
208
}
239
209
// Copy handlers to "prepared handlers" array, because the list of active handlers can change
240
210
// as a result of state updates
241
- val handlersCount = gestureHandlersCount
242
- for (i in 0 until handlersCount) {
243
- preparedHandlers[i] = gestureHandlers[i]
244
- }
245
- for (i in handlersCount - 1 downTo 0 ) {
246
- preparedHandlers[i]!! .cancel()
211
+ preparedHandlers.clear()
212
+ preparedHandlers.addAll(gestureHandlers)
213
+
214
+ for (handler in gestureHandlers.reversed()) {
215
+ handler.cancel()
247
216
}
248
217
}
249
218
@@ -325,7 +294,7 @@ class GestureHandlerOrchestrator(
325
294
return parent == = wrapperView
326
295
}
327
296
328
- fun isAnyHandlerActive () = gestureHandlers.any { it? .state == GestureHandler .STATE_ACTIVE }
297
+ fun isAnyHandlerActive () = gestureHandlers.any { it.state == GestureHandler .STATE_ACTIVE }
329
298
330
299
/* *
331
300
* Transforms an event in the coordinates of wrapperView into the coordinate space of the received view.
@@ -399,27 +368,23 @@ class GestureHandlerOrchestrator(
399
368
}
400
369
401
370
private fun addAwaitingHandler (handler : GestureHandler <* >) {
402
- for (i in 0 until awaitingHandlersCount) {
403
- if (awaitingHandlers[i] == = handler) {
404
- return
405
- }
371
+ if (awaitingHandlers.contains(handler)) {
372
+ return
406
373
}
407
- check(awaitingHandlersCount < awaitingHandlers.size) { " Too many recognizers " }
408
- awaitingHandlers[awaitingHandlersCount ++ ] = handler
374
+
375
+ awaitingHandlers.add( handler)
409
376
with (handler) {
410
377
isAwaiting = true
411
378
activationIndex = this @GestureHandlerOrchestrator.activationIndex++
412
379
}
413
380
}
414
381
415
382
private fun recordHandlerIfNotPresent (handler : GestureHandler <* >, view : View ) {
416
- for (i in 0 until gestureHandlersCount) {
417
- if (gestureHandlers[i] == = handler) {
418
- return
419
- }
383
+ if (gestureHandlers.contains(handler)) {
384
+ return
420
385
}
421
- check(gestureHandlersCount < gestureHandlers.size) { " Too many recognizers " }
422
- gestureHandlers[gestureHandlersCount ++ ] = handler
386
+
387
+ gestureHandlers.add( handler)
423
388
handler.isActive = false
424
389
handler.isAwaiting = false
425
390
handler.activationIndex = Int .MAX_VALUE
@@ -608,7 +573,6 @@ class GestureHandlerOrchestrator(
608
573
companion object {
609
574
// The limit doesn't necessarily need to exists, it was just simpler to implement it that way
610
575
// it is also more allocation-wise efficient to have a fixed limit
611
- private const val SIMULTANEOUS_GESTURE_HANDLER_LIMIT = 20
612
576
613
577
// Be default fully transparent views can receive touch
614
578
private const val DEFAULT_MIN_ALPHA_FOR_TRAVERSAL = 0f
0 commit comments