Skip to content

Commit d0083b9

Browse files
committed
Make base GestureHandler non generic
1 parent 1ace527 commit d0083b9

24 files changed

Lines changed: 116 additions & 147 deletions

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import android.view.VelocityTracker
88
import com.facebook.react.bridge.ReadableMap
99
import com.swmansion.gesturehandler.react.eventbuilders.FlingGestureHandlerEventDataBuilder
1010

11-
class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {
11+
class FlingGestureHandler : GestureHandler() {
1212
var numberOfPointersRequired = DEFAULT_NUMBER_OF_TOUCHES_REQUIRED
1313
var direction = DEFAULT_DIRECTION
1414

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import com.swmansion.gesturehandler.react.eventbuilders.GestureHandlerEventDataB
2323
import java.lang.IllegalStateException
2424
import java.util.*
2525

26-
open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestureHandlerT>> {
26+
open class GestureHandler {
2727
private val trackedPointerIDs = IntArray(MAX_POINTERS_COUNT)
2828
private var trackedPointersIDsCount = 0
2929
private val windowOffset = IntArray(2) { 0 }
@@ -79,37 +79,30 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
7979
protected set
8080
protected var shouldCancelWhenOutside = false
8181
protected var orchestrator: GestureHandlerOrchestrator? = null
82-
private var onTouchEventListener: OnTouchEventListener? = null
82+
var onTouchEventListener: OnTouchEventListener? = null
8383
private var interactionController: GestureHandlerInteractionController? = null
8484
var pointerType: Int = POINTER_TYPE_OTHER
8585
private set
8686

8787
protected var mouseButton = 0
8888

89-
@Suppress("UNCHECKED_CAST")
90-
protected fun self(): ConcreteGestureHandlerT = this as ConcreteGestureHandlerT
91-
92-
protected inline fun applySelf(block: ConcreteGestureHandlerT.() -> Unit): ConcreteGestureHandlerT = self().apply {
93-
block()
94-
}
95-
9689
// properties set and accessed only by the orchestrator
9790
var activationIndex = 0
9891
var isActive = false
9992
var isAwaiting = false
10093
var shouldResetProgress = false
10194

10295
open fun dispatchStateChange(newState: Int, prevState: Int) {
103-
onTouchEventListener?.onStateChange(self(), newState, prevState)
96+
onTouchEventListener?.onStateChange(this, newState, prevState)
10497
}
10598

10699
open fun dispatchHandlerUpdate(event: MotionEvent) {
107-
onTouchEventListener?.onHandlerUpdate(self(), event)
100+
onTouchEventListener?.onHandlerUpdate(this, event)
108101
}
109102

110103
open fun dispatchTouchEvent() {
111104
if (changedTouchesPayload != null) {
112-
onTouchEventListener?.onTouchEvent(self())
105+
onTouchEventListener?.onTouchEvent(this)
113106
}
114107
}
115108

@@ -122,7 +115,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
122115
mouseButton = DEFAULT_MOUSE_BUTTON
123116
}
124117

125-
fun hasCommonPointers(other: GestureHandler<*>): Boolean {
118+
fun hasCommonPointers(other: GestureHandler): Boolean {
126119
for (i in trackedPointerIDs.indices) {
127120
if (trackedPointerIDs[i] != -1 && other.trackedPointerIDs[i] != -1) {
128121
return true
@@ -131,14 +124,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
131124
return false
132125
}
133126

134-
fun setHitSlop(
135-
leftPad: Float,
136-
topPad: Float,
137-
rightPad: Float,
138-
bottomPad: Float,
139-
width: Float,
140-
height: Float,
141-
): ConcreteGestureHandlerT = applySelf {
127+
fun setHitSlop(leftPad: Float, topPad: Float, rightPad: Float, bottomPad: Float, width: Float, height: Float) {
142128
if (hitSlop == null) {
143129
hitSlop = FloatArray(6)
144130
}
@@ -162,10 +148,9 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
162148
}
163149
}
164150

165-
fun setHitSlop(padding: Float): ConcreteGestureHandlerT =
166-
setHitSlop(padding, padding, padding, padding, HIT_SLOP_NONE, HIT_SLOP_NONE)
151+
fun setHitSlop(padding: Float) = setHitSlop(padding, padding, padding, padding, HIT_SLOP_NONE, HIT_SLOP_NONE)
167152

168-
fun setInteractionController(controller: GestureHandlerInteractionController?): ConcreteGestureHandlerT = applySelf {
153+
fun setInteractionController(controller: GestureHandlerInteractionController?) {
169154
interactionController = controller
170155
}
171156

@@ -331,7 +316,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
331316
}
332317

333318
// exception to help debug https://github.com/software-mansion/react-native-gesture-handler/issues/1188
334-
class AdaptEventException(handler: GestureHandler<*>, event: MotionEvent, e: IllegalArgumentException) :
319+
class AdaptEventException(handler: GestureHandler, event: MotionEvent, e: IllegalArgumentException) :
335320
Exception(
336321
"""
337322
handler: ${handler::class.simpleName}
@@ -594,31 +579,31 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
594579
state != STATE_END &&
595580
trackedPointersIDsCount > 0
596581

597-
open fun shouldRequireToWaitForFailure(handler: GestureHandler<*>): Boolean {
582+
open fun shouldRequireToWaitForFailure(handler: GestureHandler): Boolean {
598583
if (handler === this) {
599584
return false
600585
}
601586

602587
return interactionController?.shouldRequireHandlerToWaitForFailure(this, handler) ?: false
603588
}
604589

605-
fun shouldWaitForHandlerFailure(handler: GestureHandler<*>): Boolean {
590+
fun shouldWaitForHandlerFailure(handler: GestureHandler): Boolean {
606591
if (handler === this) {
607592
return false
608593
}
609594

610595
return interactionController?.shouldWaitForHandlerFailure(this, handler) ?: false
611596
}
612597

613-
open fun shouldRecognizeSimultaneously(handler: GestureHandler<*>): Boolean {
598+
open fun shouldRecognizeSimultaneously(handler: GestureHandler): Boolean {
614599
if (handler === this) {
615600
return true
616601
}
617602

618603
return interactionController?.shouldRecognizeSimultaneously(this, handler) ?: false
619604
}
620605

621-
open fun shouldBeCancelledBy(handler: GestureHandler<*>): Boolean {
606+
open fun shouldBeCancelledBy(handler: GestureHandler): Boolean {
622607
if (handler === this) {
623608
return false
624609
}
@@ -713,7 +698,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
713698
* Returns true if the view this handler is attached to is a descendant of the view the other handler
714699
* is attached to and false otherwise.
715700
*/
716-
fun isDescendantOf(of: GestureHandler<*>): Boolean {
701+
fun isDescendantOf(of: GestureHandler): Boolean {
717702
var view = this.view?.parent as? View
718703
while (view != null) {
719704
if (view == of.view) {
@@ -829,11 +814,6 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
829814
}
830815
}
831816

832-
fun setOnTouchEventListener(listener: OnTouchEventListener?): GestureHandler<*> {
833-
onTouchEventListener = listener
834-
return this
835-
}
836-
837817
override fun toString(): String {
838818
val viewString = if (view == null) null else view!!.javaClass.simpleName
839819
return this.javaClass.simpleName + "@[" + tag + "]:" + viewString
@@ -849,7 +829,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
849829
val lastPositionInWindowY: Float
850830
get() = lastAbsolutePositionY + lastEventOffsetY - windowOffset[1]
851831

852-
abstract class Factory<T : GestureHandler<T>> {
832+
abstract class Factory<T : GestureHandler> {
853833
abstract val type: Class<T>
854834
abstract val name: String
855835

@@ -897,7 +877,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
897877
private const val KEY_HIT_SLOP_WIDTH = "width"
898878
private const val KEY_HIT_SLOP_HEIGHT = "height"
899879

900-
private fun handleHitSlopProperty(handler: GestureHandler<*>, config: ReadableMap) {
880+
private fun handleHitSlopProperty(handler: GestureHandler, config: ReadableMap) {
901881
if (config.getType(KEY_HIT_SLOP) == ReadableType.Number) {
902882
val hitSlop = PixelUtil.toPixelFromDIP(config.getDouble(KEY_HIT_SLOP))
903883
handler.setHitSlop(
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.swmansion.gesturehandler.core
22

33
interface GestureHandlerInteractionController {
4-
fun shouldWaitForHandlerFailure(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
5-
fun shouldRequireHandlerToWaitForFailure(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
6-
fun shouldRecognizeSimultaneously(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
7-
fun shouldHandlerBeCancelledBy(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
4+
fun shouldWaitForHandlerFailure(handler: GestureHandler, otherHandler: GestureHandler): Boolean
5+
fun shouldRequireHandlerToWaitForFailure(handler: GestureHandler, otherHandler: GestureHandler): Boolean
6+
fun shouldRecognizeSimultaneously(handler: GestureHandler, otherHandler: GestureHandler): Boolean
7+
fun shouldHandlerBeCancelledBy(handler: GestureHandler, otherHandler: GestureHandler): Boolean
88
}

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ class GestureHandlerOrchestrator(
2020
* traversing view hierarchy and looking for gesture handlers.
2121
*/
2222
var minimumAlphaForTraversal = DEFAULT_MIN_ALPHA_FOR_TRAVERSAL
23-
private val gestureHandlers = arrayListOf<GestureHandler<*>>()
24-
private val awaitingHandlers = arrayListOf<GestureHandler<*>>()
25-
private val preparedHandlers = arrayListOf<GestureHandler<*>>()
23+
private val gestureHandlers = arrayListOf<GestureHandler>()
24+
private val awaitingHandlers = arrayListOf<GestureHandler>()
25+
private val preparedHandlers = arrayListOf<GestureHandler>()
2626

2727
// In `onHandlerStateChange` method we iterate through `awaitingHandlers`, but calling `tryActivate` may modify this list.
2828
// To avoid `ConcurrentModificationException` we iterate through copy. There is one more problem though - if handler was
@@ -85,22 +85,20 @@ class GestureHandlerOrchestrator(
8585
finishedHandlersCleanupScheduled = false
8686
}
8787

88-
private fun hasOtherHandlerToWaitFor(handler: GestureHandler<*>) = gestureHandlers.any {
89-
!isFinished(it.state) && shouldHandlerWaitForOther(handler, it)
90-
}
88+
private fun hasOtherHandlerToWaitFor(handler: GestureHandler) =
89+
gestureHandlers.any { !isFinished(it.state) && shouldHandlerWaitForOther(handler, it) }
9190

92-
private fun shouldBeCancelledByFinishedHandler(handler: GestureHandler<*>) = gestureHandlers.any {
93-
shouldHandlerWaitForOther(handler, it) && it.state == GestureHandler.STATE_END
94-
}
91+
private fun shouldBeCancelledByFinishedHandler(handler: GestureHandler) =
92+
gestureHandlers.any { shouldHandlerWaitForOther(handler, it) && it.state == GestureHandler.STATE_END }
9593

96-
private fun shouldBeCancelledByActiveHandler(handler: GestureHandler<*>) = gestureHandlers.any {
94+
private fun shouldBeCancelledByActiveHandler(handler: GestureHandler) = gestureHandlers.any {
9795
handler.hasCommonPointers(it) &&
9896
it.state == GestureHandler.STATE_ACTIVE &&
9997
!canRunSimultaneously(handler, it) &&
10098
handler.isDescendantOf(it)
10199
}
102100

103-
private fun tryActivate(handler: GestureHandler<*>) {
101+
private fun tryActivate(handler: GestureHandler) {
104102
// If we are waiting for a gesture that has successfully finished, we should cancel handler
105103
if (shouldBeCancelledByFinishedHandler(handler) || shouldBeCancelledByActiveHandler(handler)) {
106104
handler.cancel()
@@ -129,7 +127,7 @@ class GestureHandlerOrchestrator(
129127
}
130128

131129
/*package*/
132-
fun onHandlerStateChange(handler: GestureHandler<*>, newState: Int, prevState: Int) {
130+
fun onHandlerStateChange(handler: GestureHandler, newState: Int, prevState: Int) {
133131
handlingChangeSemaphore += 1
134132
if (isFinished(newState)) {
135133
// We have to loop through copy in order to avoid modifying collection
@@ -193,7 +191,7 @@ class GestureHandlerOrchestrator(
193191
scheduleFinishedHandlersCleanup()
194192
}
195193

196-
private fun makeActive(handler: GestureHandler<*>) {
194+
private fun makeActive(handler: GestureHandler) {
197195
val currentState = handler.state
198196
with(handler) {
199197
isAwaiting = false
@@ -270,7 +268,7 @@ class GestureHandlerOrchestrator(
270268
}
271269
}
272270

273-
private fun deliverEventToGestureHandler(handler: GestureHandler<*>, sourceEvent: MotionEvent) {
271+
private fun deliverEventToGestureHandler(handler: GestureHandler, sourceEvent: MotionEvent) {
274272
if (!isViewAttachedUnderWrapper(handler.view)) {
275273
handler.cancel()
276274
return
@@ -424,7 +422,7 @@ class GestureHandlerOrchestrator(
424422
return point
425423
}
426424

427-
private fun addAwaitingHandler(handler: GestureHandler<*>) {
425+
private fun addAwaitingHandler(handler: GestureHandler) {
428426
if (awaitingHandlers.contains(handler)) {
429427
return
430428
}
@@ -438,7 +436,7 @@ class GestureHandlerOrchestrator(
438436
}
439437
}
440438

441-
private fun recordHandlerIfNotPresent(handler: GestureHandler<*>, view: View) {
439+
private fun recordHandlerIfNotPresent(handler: GestureHandler, view: View) {
442440
if (gestureHandlers.contains(handler)) {
443441
return
444442
}
@@ -497,7 +495,7 @@ class GestureHandlerOrchestrator(
497495
// There's only one exception - RootViewGestureHandler. TalkBack uses hover events,
498496
// so we need to pass them into RootViewGestureHandler, otherwise press and hold
499497
// gesture stops working correctly (see https://github.com/software-mansion/react-native-gesture-handler/issues/3407)
500-
private fun shouldHandlerSkipHoverEvents(handler: GestureHandler<*>, action: Int): Boolean {
498+
private fun shouldHandlerSkipHoverEvents(handler: GestureHandler, action: Int): Boolean {
501499
val shouldSkipHoverEvents =
502500
handler !is HoverGestureHandler &&
503501
handler !is RNGestureHandlerRootHelper.RootViewGestureHandler
@@ -672,7 +670,7 @@ class GestureHandlerOrchestrator(
672670
private val matrixTransformCoords = FloatArray(2)
673671
private val inverseMatrix = Matrix()
674672
private val tempCoords = FloatArray(2)
675-
private val handlersComparator = Comparator<GestureHandler<*>> { a, b ->
673+
private val handlersComparator = Comparator<GestureHandler> { a, b ->
676674
return@Comparator if (a.isActive && b.isActive || a.isAwaiting && b.isAwaiting) {
677675
// both A and B are either active or awaiting activation, in which case we prefer one that
678676
// has activated (or turned into "awaiting" state) earlier
@@ -726,17 +724,16 @@ class GestureHandlerOrchestrator(
726724
private fun isTransformedTouchPointInView(x: Float, y: Float, child: View) =
727725
x in 0f..child.width.toFloat() && y in 0f..child.height.toFloat()
728726

729-
private fun shouldHandlerWaitForOther(handler: GestureHandler<*>, other: GestureHandler<*>): Boolean =
730-
handler !== other &&
731-
(
732-
handler.shouldWaitForHandlerFailure(other) ||
733-
other.shouldRequireToWaitForFailure(handler)
734-
)
727+
private fun shouldHandlerWaitForOther(handler: GestureHandler, other: GestureHandler): Boolean =
728+
handler !== other && (
729+
handler.shouldWaitForHandlerFailure(other) ||
730+
other.shouldRequireToWaitForFailure(handler)
731+
)
735732

736-
private fun canRunSimultaneously(a: GestureHandler<*>, b: GestureHandler<*>) =
733+
private fun canRunSimultaneously(a: GestureHandler, b: GestureHandler) =
737734
a === b || a.shouldRecognizeSimultaneously(b) || b.shouldRecognizeSimultaneously(a)
738735

739-
private fun shouldHandlerBeCancelledBy(handler: GestureHandler<*>, other: GestureHandler<*>): Boolean {
736+
private fun shouldHandlerBeCancelledBy(handler: GestureHandler, other: GestureHandler): Boolean {
740737
if (!handler.hasCommonPointers(other)) {
741738
// if two handlers share no common pointer one can never trigger cancel for the other
742739
return false

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerRegistry.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import android.view.View
44
import java.util.*
55

66
interface GestureHandlerRegistry {
7-
fun getHandlersForView(view: View): ArrayList<GestureHandler<*>>?
7+
fun getHandlersForView(view: View): ArrayList<GestureHandler>?
88
}

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/HoverGestureHandler.kt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ import com.swmansion.gesturehandler.react.RNGestureHandlerRootHelper
1010
import com.swmansion.gesturehandler.react.RNViewConfigurationHelper
1111
import com.swmansion.gesturehandler.react.eventbuilders.HoverGestureHandlerEventDataBuilder
1212

13-
class HoverGestureHandler : GestureHandler<HoverGestureHandler>() {
13+
class HoverGestureHandler : GestureHandler() {
1414
private var handler: Handler? = null
1515
private var finishRunnable = Runnable { finish() }
1616
var stylusData: StylusData = StylusData()
1717
private set
1818

19-
private infix fun isAncestorOf(other: GestureHandler<*>): Boolean {
19+
private infix fun isAncestorOf(other: GestureHandler): Boolean {
2020
var current: View? = other.view
2121

2222
while (current != null) {
@@ -50,15 +50,15 @@ class HoverGestureHandler : GestureHandler<HoverGestureHandler>() {
5050
return null
5151
}
5252

53-
override fun shouldBeCancelledBy(handler: GestureHandler<*>): Boolean {
53+
override fun shouldBeCancelledBy(handler: GestureHandler): Boolean {
5454
if (handler is HoverGestureHandler && !(handler isAncestorOf this)) {
5555
return isViewDisplayedOverAnother(handler.view!!, this.view!!)!!
5656
}
5757

5858
return super.shouldBeCancelledBy(handler)
5959
}
6060

61-
override fun shouldRequireToWaitForFailure(handler: GestureHandler<*>): Boolean {
61+
override fun shouldRequireToWaitForFailure(handler: GestureHandler): Boolean {
6262
if (handler is HoverGestureHandler) {
6363
if (!(this isAncestorOf handler) && !(handler isAncestorOf this)) {
6464
isViewDisplayedOverAnother(this.view!!, handler.view!!)?.let {
@@ -70,10 +70,8 @@ class HoverGestureHandler : GestureHandler<HoverGestureHandler>() {
7070
return super.shouldRequireToWaitForFailure(handler)
7171
}
7272

73-
override fun shouldRecognizeSimultaneously(handler: GestureHandler<*>): Boolean {
74-
if (handler is HoverGestureHandler &&
75-
(this isAncestorOf handler || handler isAncestorOf this)
76-
) {
73+
override fun shouldRecognizeSimultaneously(handler: GestureHandler): Boolean {
74+
if (handler is HoverGestureHandler && (this isAncestorOf handler || handler isAncestorOf this)) {
7775
return true
7876
}
7977

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import com.facebook.react.bridge.ReadableMap
99
import com.facebook.react.uimanager.PixelUtil
1010
import com.swmansion.gesturehandler.react.eventbuilders.LongPressGestureHandlerEventDataBuilder
1111

12-
class LongPressGestureHandler(context: Context) : GestureHandler<LongPressGestureHandler>() {
12+
class LongPressGestureHandler(context: Context) : GestureHandler() {
1313
var minDurationMs = DEFAULT_MIN_DURATION_MS
1414
val duration: Int
1515
get() = (previousTime - startTime).toInt()

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/ManualGestureHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import android.content.Context
44
import android.view.MotionEvent
55
import com.swmansion.gesturehandler.react.eventbuilders.ManualGestureHandlerEventDataBuilder
66

7-
class ManualGestureHandler : GestureHandler<ManualGestureHandler>() {
7+
class ManualGestureHandler : GestureHandler() {
88
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
99
if (state == STATE_UNDETERMINED) {
1010
begin()

0 commit comments

Comments
 (0)