Skip to content

Commit

Permalink
Merge lib package into the main one in the Android implementation (#…
Browse files Browse the repository at this point in the history
…2270)

## Description

This PR changes the structure of the Gesture Handler's Android code. For
some time GH could have been used as a native Android library for
handling gestures, but it has been removed since. The split into two
packages that was required by it is still there, along some of the now
redundant files (another `build.gradle` and `AndroidManifest`).

This PR removes the two-package split and moves the core files into a
new `core` subpackage, like the `react` one.

## Test plan

Build the example app.
  • Loading branch information
j-piasecki authored Oct 19, 2022
1 parent 1091a01 commit 49709ad
Show file tree
Hide file tree
Showing 36 changed files with 150 additions and 149 deletions.
5 changes: 0 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,8 @@ android {
exclude "**/libreact_render*.so"
}

// Include "lib/" as sources, unfortunately react-native link can't handle
// setting up alternative gradle modules. We still have "lib" defined as a
// standalone gradle module just to be used in AndroidNativeExample
sourceSets.main {
java {
srcDirs += 'lib/src/main/java'

// Include "common/" only when it's not provided by Reanimated to mitigate
// multiple definitions of the same class preventing build
if (shouldUseCommonInterfaceFromReanimated()) {
Expand Down
3 changes: 0 additions & 3 deletions android/lib/src/main/AndroidManifest.xml

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.facebook.react.bridge.ReactContext
import com.facebook.react.uimanager.events.Event

class ReanimatedEventDispatcher {
fun <T : Event<T>>sendEvent(event: T, reactApplicationContext: ReactContext) {
// no-op
}
fun <T : Event<T>>sendEvent(event: T, reactApplicationContext: ReactContext) {
// no-op
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import com.facebook.react.uimanager.events.Event
import com.swmansion.reanimated.ReanimatedModule

class ReanimatedEventDispatcher {
private var reanimatedModule: ReanimatedModule? = null
private var reanimatedModule: ReanimatedModule? = null

fun <T : Event<T>>sendEvent(event: T, reactApplicationContext: ReactContext) {
if (reanimatedModule == null) {
reanimatedModule = reactApplicationContext.getNativeModule(ReanimatedModule::class.java)
}

reanimatedModule?.nodesManager?.onEventDispatch(event)
fun <T : Event<T>>sendEvent(event: T, reactApplicationContext: ReactContext) {
if (reanimatedModule == null) {
reanimatedModule = reactApplicationContext.getNativeModule(ReanimatedModule::class.java)
}

reanimatedModule?.nodesManager?.onEventDispatch(event)
}
}
2 changes: 1 addition & 1 deletion android/spotless.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: "com.diffplug.spotless"

spotless {
kotlin {
target "src/**/*.kt"
target "src/**/*.kt", "reanimated/**/*.kt", "noreanimated/**/*.kt", "common/**/*.kt"
ktlint().editorConfigOverride([indent_size: 2])
trimTrailingWhitespace()
indentWithSpaces()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swmansion.gesturehandler
package com.swmansion.gesturehandler.core

import android.os.Handler
import android.os.Looper
Expand Down Expand Up @@ -37,14 +37,17 @@ class FlingGestureHandler : GestureHandler<FlingGestureHandler>() {

private fun tryEndFling(event: MotionEvent) = if (
maxNumberOfPointersSimultaneously == numberOfPointersRequired &&
(direction and DIRECTION_RIGHT != 0 &&
event.rawX - startX > minAcceptableDelta ||
direction and DIRECTION_LEFT != 0 &&
startX - event.rawX > minAcceptableDelta ||
direction and DIRECTION_UP != 0 &&
startY - event.rawY > minAcceptableDelta ||
direction and DIRECTION_DOWN != 0 &&
event.rawY - startY > minAcceptableDelta)) {
(
direction and DIRECTION_RIGHT != 0 &&
event.rawX - startX > minAcceptableDelta ||
direction and DIRECTION_LEFT != 0 &&
startX - event.rawX > minAcceptableDelta ||
direction and DIRECTION_UP != 0 &&
startY - event.rawY > minAcceptableDelta ||
direction and DIRECTION_DOWN != 0 &&
event.rawY - startY > minAcceptableDelta
)
) {
handler!!.removeCallbacksAndMessages(null)
activate()
true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swmansion.gesturehandler
package com.swmansion.gesturehandler.core

import android.app.Activity
import android.content.Context
Expand All @@ -14,6 +14,7 @@ import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.UiThreadUtil
import com.facebook.react.bridge.WritableArray
import com.facebook.react.uimanager.PixelUtil
import com.swmansion.gesturehandler.BuildConfig
import com.swmansion.gesturehandler.react.RNGestureHandlerTouchEvent
import java.lang.IllegalStateException
import java.util.*
Expand Down Expand Up @@ -48,7 +49,6 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
private val trackedPointers: Array<PointerData?> = Array(MAX_POINTERS_COUNT) { null }
var needsPointerData = false


private var hitSlop: FloatArray? = null
var eventCoalescingKey: Short = 0
private set
Expand Down Expand Up @@ -127,11 +127,15 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
}

fun setManualActivation(manualActivation: Boolean): ConcreteGestureHandlerT =
applySelf { this.manualActivation = manualActivation }
applySelf { this.manualActivation = manualActivation }

fun setHitSlop(
leftPad: Float, topPad: Float, rightPad: Float, bottomPad: Float,
width: Float, height: Float,
leftPad: Float,
topPad: Float,
rightPad: Float,
bottomPad: Float,
width: Float,
height: Float,
): ConcreteGestureHandlerT = applySelf {
if (hitSlop == null) {
hitSlop = FloatArray(6)
Expand Down Expand Up @@ -278,7 +282,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
}

// introduced in 1.11.0, remove if crashes are not reported
if(pointerProps.isEmpty()|| pointerCoords.isEmpty()){
if (pointerProps.isEmpty() || pointerCoords.isEmpty()) {
throw IllegalStateException("pointerCoords.size=${pointerCoords.size}, pointerProps.size=${pointerProps.size}")
}

Expand All @@ -289,8 +293,8 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
event.eventTime,
action,
count,
pointerProps, /* props are copied and hence it is safe to use static array here */
pointerCoords, /* same applies to coords */
pointerProps, /* props are copied and hence it is safe to use static array here */
pointerCoords, /* same applies to coords */
event.metaState,
event.buttonState,
event.xPrecision,
Expand All @@ -313,7 +317,8 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
handler: GestureHandler<*>,
event: MotionEvent,
e: IllegalArgumentException
) : Exception("""
) : Exception(
"""
handler: ${handler::class.simpleName}
state: ${handler.state}
view: ${handler.view}
Expand All @@ -324,14 +329,17 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
trackedPointersCount: ${handler.trackedPointersIDsCount}
trackedPointers: ${handler.trackedPointerIDs.joinToString(separator = ", ")}
while handling event: $event
""".trimIndent(), e) {}
""".trimIndent(),
e
)

fun handle(transformedEvent: MotionEvent, sourceEvent: MotionEvent) {
if (!isEnabled
|| state == STATE_CANCELLED
|| state == STATE_FAILED
|| state == STATE_END
|| trackedPointersIDsCount < 1) {
if (!isEnabled ||
state == STATE_CANCELLED ||
state == STATE_FAILED ||
state == STATE_END ||
trackedPointersIDsCount < 1
) {
return
}

Expand Down Expand Up @@ -380,11 +388,11 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
val offsetY = event.rawY - event.y

trackedPointers[pointerId] = PointerData(
pointerId,
event.getX(event.actionIndex),
event.getY(event.actionIndex),
event.getX(event.actionIndex) + offsetX - windowOffset[0],
event.getY(event.actionIndex) + offsetY - windowOffset[1],
pointerId,
event.getX(event.actionIndex),
event.getY(event.actionIndex),
event.getX(event.actionIndex) + offsetX - windowOffset[0],
event.getY(event.actionIndex) + offsetY - windowOffset[1],
)
trackedPointersCount++
addChangedPointer(trackedPointers[pointerId]!!)
Expand All @@ -402,11 +410,11 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
val offsetY = event.rawY - event.y

trackedPointers[pointerId] = PointerData(
pointerId,
event.getX(event.actionIndex),
event.getY(event.actionIndex),
event.getX(event.actionIndex) + offsetX - windowOffset[0],
event.getY(event.actionIndex) + offsetY - windowOffset[1],
pointerId,
event.getX(event.actionIndex),
event.getY(event.actionIndex),
event.getX(event.actionIndex) + offsetX - windowOffset[0],
event.getY(event.actionIndex) + offsetY - windowOffset[1],
)
addChangedPointer(trackedPointers[pointerId]!!)
trackedPointers[pointerId] = null
Expand Down Expand Up @@ -545,11 +553,11 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
}

fun wantEvents(): Boolean {
return isEnabled
&& state != STATE_FAILED
&& state != STATE_CANCELLED
&& state != STATE_END
&& trackedPointersIDsCount > 0
return isEnabled &&
state != STATE_FAILED &&
state != STATE_CANCELLED &&
state != STATE_END &&
trackedPointersIDsCount > 0
}

open fun shouldRequireToWaitForFailure(handler: GestureHandler<*>): Boolean {
Expand Down Expand Up @@ -745,7 +753,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
private lateinit var pointerCoords: Array<PointerCoords?>
private fun initPointerProps(size: Int) {
var size = size
if (!::pointerProps.isInitialized) {
if (!Companion::pointerProps.isInitialized) {
pointerProps = arrayOfNulls(MAX_POINTERS_COUNT)
pointerCoords = arrayOfNulls(MAX_POINTERS_COUNT)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swmansion.gesturehandler
package com.swmansion.gesturehandler.core

interface GestureHandlerInteractionController {
fun shouldWaitForHandlerFailure(handler: GestureHandler<*>, otherHandler: GestureHandler<*>): Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swmansion.gesturehandler
package com.swmansion.gesturehandler.core

import android.graphics.Matrix
import android.graphics.PointF
Expand Down Expand Up @@ -134,7 +134,10 @@ class GestureHandlerOrchestrator(
// their state is set to END and when the gesture they are waiting for activates they
// should be cancelled, however `cancel` was never sent as gestures were already in the END state.
// Send synthetic BEGAN -> CANCELLED to properly handle JS logic
otherHandler.dispatchStateChange(GestureHandler.STATE_CANCELLED, GestureHandler.STATE_BEGAN)
otherHandler.dispatchStateChange(
GestureHandler.STATE_CANCELLED,
GestureHandler.STATE_BEGAN
)
}
otherHandler.isAwaiting = false
} else {
Expand Down Expand Up @@ -253,10 +256,10 @@ class GestureHandlerOrchestrator(

val action = sourceEvent.actionMasked
val event = transformEventToViewCoords(handler.view, MotionEvent.obtain(sourceEvent))

// Touch events are sent before the handler itself has a chance to process them,
// mainly because `onTouchesUp` shoul be send befor gesture finishes. This means that
// the first `onTouchesDown` event is sent before a gesture begins, activation in
// the first `onTouchesDown` event is sent before a gesture begins, activation in
// callback for this event causes problems because the handler doesn't have a chance
// to initialize itself with starting values of pointer (in pan this causes translation
// to be equal to the coordinates of the pointer). The simplest solution is to send
Expand Down Expand Up @@ -475,9 +478,10 @@ class GestureHandlerOrchestrator(

// if the pointer is inside the view but it overflows its parent, handlers attached to the parent
// might not have been extracted (pointer might be in a child, but may be outside parent)
if (coords[0] in 0f..view.width.toFloat() && coords[1] in 0f..view.height.toFloat()
&& isViewOverflowingParent(view) && extractAncestorHandlers(view, coords, pointerId)) {
found = true
if (coords[0] in 0f..view.width.toFloat() && coords[1] in 0f..view.height.toFloat() &&
isViewOverflowingParent(view) && extractAncestorHandlers(view, coords, pointerId)
) {
found = true
}

return found
Expand Down Expand Up @@ -527,8 +531,10 @@ class GestureHandlerOrchestrator(
}
PointerEventsConfig.BOX_ONLY -> {
// This view is the target, its children don't matter
(recordViewHandlersForPointer(view, coords, pointerId)
|| shouldHandlerlessViewBecomeTouchTarget(view, coords))
(
recordViewHandlersForPointer(view, coords, pointerId) ||
shouldHandlerlessViewBecomeTouchTarget(view, coords)
)
}
PointerEventsConfig.BOX_NONE -> {
// This view can't be the target, but its children might
Expand Down Expand Up @@ -557,8 +563,10 @@ class GestureHandlerOrchestrator(
extractGestureHandlers(view, coords, pointerId)
} else false

(recordViewHandlersForPointer(view, coords, pointerId)
|| found || shouldHandlerlessViewBecomeTouchTarget(view, coords))
(
recordViewHandlersForPointer(view, coords, pointerId) ||
found || shouldHandlerlessViewBecomeTouchTarget(view, coords)
)
}
}

Expand All @@ -570,7 +578,6 @@ class GestureHandlerOrchestrator(
private fun isClipping(view: View) =
view !is ViewGroup || viewConfigHelper.isViewClippingChildren(view)


companion object {
// The limit doesn't necessarily need to exists, it was just simpler to implement it that way
// it is also more allocation-wise efficient to have a fixed limit
Expand Down Expand Up @@ -637,14 +644,15 @@ class GestureHandlerOrchestrator(
x in 0f..child.width.toFloat() && y in 0f..child.height.toFloat()

private fun shouldHandlerWaitForOther(handler: GestureHandler<*>, other: GestureHandler<*>): Boolean {
return handler !== other && (handler.shouldWaitForHandlerFailure(other)
|| other.shouldRequireToWaitForFailure(handler))
return handler !== other && (
handler.shouldWaitForHandlerFailure(other) ||
other.shouldRequireToWaitForFailure(handler)
)
}

private fun canRunSimultaneously(a: GestureHandler<*>, b: GestureHandler<*>) =
a === b || a.shouldRecognizeSimultaneously(b) || b.shouldRecognizeSimultaneously(a)


private fun shouldHandlerBeCancelledBy(handler: GestureHandler<*>, other: GestureHandler<*>): Boolean {
if (!handler.hasCommonPointers(other)) {
// if two handlers share no common pointer one can never trigger cancel for the other
Expand All @@ -656,16 +664,17 @@ class GestureHandlerOrchestrator(
return false
}
return if (handler !== other &&
(handler.isAwaiting || handler.state == GestureHandler.STATE_ACTIVE)) {
(handler.isAwaiting || handler.state == GestureHandler.STATE_ACTIVE)
) {
// in every other case as long as the handler is about to be activated or already in active
// state, we delegate the decision to the implementation of GestureHandler#shouldBeCancelledBy
handler.shouldBeCancelledBy(other)
} else true
}

private fun isFinished(state: Int) =
state == GestureHandler.STATE_CANCELLED
|| state == GestureHandler.STATE_FAILED
|| state == GestureHandler.STATE_END
state == GestureHandler.STATE_CANCELLED ||
state == GestureHandler.STATE_FAILED ||
state == GestureHandler.STATE_END
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swmansion.gesturehandler
package com.swmansion.gesturehandler.core

import android.view.View
import java.util.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swmansion.gesturehandler
package com.swmansion.gesturehandler.core

import android.view.MotionEvent

Expand Down
Loading

0 comments on commit 49709ad

Please sign in to comment.