Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ open class GestureHandler {
private set

// Host detector view is a reference to a Native Detector designated to handle events from a
// Logic Detector to which the gesture is assigned.
// Virtual Detector to which the gesture is assigned.
var hostDetectorView: RNGestureHandlerDetectorView? = null

val viewForEvents: RNGestureHandlerDetectorView
get() {
assert(usesNativeOrLogicDetector(actionType)) {
assert(usesNativeOrVirtualDetector(actionType)) {
"[react-native-gesture-handler] `viewForEvents` can only be used with NativeDetector."
}

val detector = if (actionType ==
ACTION_TYPE_LOGIC_DETECTOR
ACTION_TYPE_VIRTUAL_DETECTOR
) {
this.hostDetectorView
} else if (this is NativeViewGestureHandler) {
Expand Down Expand Up @@ -1020,7 +1020,7 @@ open class GestureHandler {
const val ACTION_TYPE_JS_FUNCTION_OLD_API = 3
const val ACTION_TYPE_JS_FUNCTION_NEW_API = 4
const val ACTION_TYPE_NATIVE_DETECTOR = 5
const val ACTION_TYPE_LOGIC_DETECTOR = 6
const val ACTION_TYPE_VIRTUAL_DETECTOR = 6
const val POINTER_TYPE_TOUCH = 0
const val POINTER_TYPE_STYLUS = 1
const val POINTER_TYPE_MOUSE = 2
Expand Down Expand Up @@ -1056,8 +1056,8 @@ open class GestureHandler {
return null
}

fun usesNativeOrLogicDetector(actionType: Int): Boolean =
actionType == ACTION_TYPE_NATIVE_DETECTOR || actionType == ACTION_TYPE_LOGIC_DETECTOR
fun usesNativeOrVirtualDetector(actionType: Int): Boolean =
actionType == ACTION_TYPE_NATIVE_DETECTOR || actionType == ACTION_TYPE_VIRTUAL_DETECTOR
}

private data class PointerData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
private val reactContext: ThemedReactContext
get() = context as ThemedReactContext
private var handlersToAttach: List<Int>? = null
private var virtualChildrenToAttach: List<VirtualChildren>? = null
private var nativeHandlers: MutableSet<Int> = mutableSetOf()
private var attachedHandlers: MutableSet<Int> = mutableSetOf()
private var attachedLogicHandlers: MutableMap<Int, MutableSet<Int>> = mutableMapOf()
private var attachedVirtualHandlers: MutableMap<Int, MutableSet<Int>> = mutableMapOf()
private var moduleId: Int = -1

data class LogicChildren(val handlerTags: List<Int>, val viewTag: Int)
data class VirtualChildren(val handlerTags: List<Int>, val viewTag: Int)

fun setHandlerTags(handlerTags: ReadableArray?) {
val newHandlers = handlerTags?.toArrayList()?.map { (it as Double).toInt() } ?: emptyList()
Expand All @@ -38,35 +39,21 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
this.moduleId = id
this.attachHandlers(handlersToAttach ?: return)
handlersToAttach = null
this.attachVirtualChildren(virtualChildrenToAttach ?: return)
virtualChildrenToAttach = null
}

fun setLogicChildren(newLogicChildren: ReadableArray?) {
val logicChildrenToDetach = attachedLogicHandlers.keys.toMutableSet()
fun setVirtualChildren(newVirtualChildren: ReadableArray?) {
val mappedChildren = newVirtualChildren?.mapVirtualChildren().orEmpty()

val mappedChildren = newLogicChildren?.mapLogicChildren().orEmpty()

for (child in mappedChildren) {
if (!attachedLogicHandlers.containsKey(child.viewTag)) {
attachedLogicHandlers[child.viewTag] = mutableSetOf()
}

logicChildrenToDetach.remove(child.viewTag)

attachHandlers(
child.handlerTags,
child.viewTag,
GestureHandler.ACTION_TYPE_LOGIC_DETECTOR,
attachedLogicHandlers[child.viewTag]!!,
)
if (moduleId == -1) {
// It's possible that handlerTags will be set before module id. In that case, store
// the handler ids and attach them after setting module id.
virtualChildrenToAttach = mappedChildren
return
}

val registry = RNGestureHandlerModule.registries[moduleId]
?: throw Exception("Tried to access a non-existent registry")

for (tag in logicChildrenToDetach) {
registry.detachHandler(tag)
attachedLogicHandlers.remove(tag)
}
attachVirtualChildren(mappedChildren)
}

private fun shouldAttachGestureToChildView(tag: Int): Boolean {
Expand Down Expand Up @@ -109,7 +96,7 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
nativeHandlers.add(tag)
} else {
registry.attachHandlerToView(tag, viewTag, actionType)
if (actionType == GestureHandler.ACTION_TYPE_LOGIC_DETECTOR) {
if (actionType == GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR) {
registry.getHandler(tag)?.hostDetectorView = this
}
attachedHandlers.add(tag)
Expand All @@ -131,6 +118,32 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
}
}

private fun attachVirtualChildren(virtualChildrenToAttach: List<VirtualChildren>) {
val virtualChildrenToDetach = attachedVirtualHandlers.keys.toMutableSet()

for (child in virtualChildrenToAttach) {
if (!attachedVirtualHandlers.containsKey(child.viewTag)) {
attachedVirtualHandlers[child.viewTag] = mutableSetOf()
}

virtualChildrenToDetach.remove(child.viewTag)
attachHandlers(
child.handlerTags,
child.viewTag,
GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR,
attachedVirtualHandlers[child.viewTag]!!,
)
}

val registry = RNGestureHandlerModule.registries[moduleId]
?: throw Exception("Tried to access a non-existent registry")

for (tag in virtualChildrenToDetach) {
registry.detachHandler(tag)
attachedVirtualHandlers.remove(tag)
}
}

private fun tryAttachNativeHandlersToChildView(childId: Int) {
val registry = RNGestureHandlerModule.registries[moduleId]
?: throw Exception("Tried to access a non-existent registry")
Expand Down Expand Up @@ -166,20 +179,20 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
attachedHandlers.remove(tag)
}

for (child in attachedLogicHandlers) {
for (child in attachedVirtualHandlers) {
for (tag in child.value) {
registry.detachHandler(tag)
}
child.value.clear()
}
}

private fun ReadableArray.mapLogicChildren(): List<LogicChildren> = List(size()) { i ->
private fun ReadableArray.mapVirtualChildren(): List<VirtualChildren> = List(size()) { i ->
val child = getMap(i) ?: return@List null
val handlerTags = child.getArray("handlerTags")?.toIntList().orEmpty()
val viewTag = child.getInt("viewTag")

LogicChildren(handlerTags, viewTag)
VirtualChildren(handlerTags, viewTag)
}.filterNotNull()

private fun ReadableArray.toIntList(): List<Int> = List(size()) { getInt(it) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class RNGestureHandlerDetectorViewManager :
view.setModuleId(value)
}

override fun setLogicChildren(view: RNGestureHandlerDetectorView, value: ReadableArray?) {
view.setLogicChildren(value)
override fun setVirtualChildren(view: RNGestureHandlerDetectorView, value: ReadableArray?) {
view.setVirtualChildren(value)
}

override fun onDropViewInstance(view: RNGestureHandlerDetectorView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
dataBuilder: GestureHandlerEventDataBuilder<T>,
eventHandlerType: EventHandlerType,
) {
val view = if (GestureHandler.usesNativeOrLogicDetector(handler.actionType)) {
val view = if (GestureHandler.usesNativeOrVirtualDetector(handler.actionType)) {
handler.viewForEvents
} else {
handler.view!!
Expand All @@ -39,7 +39,7 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
EVENTS_POOL.release(this)
}

override fun getEventName() = if (GestureHandler.usesNativeOrLogicDetector(actionType)) {
override fun getEventName() = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) {
if (eventHandlerType == EventHandlerType.ForAnimated) {
NATIVE_DETECTOR_ANIMATED_EVENT_NAME
} else if (eventHandlerType == EventHandlerType.ForReanimated) {
Expand All @@ -54,11 +54,11 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
}

// Unfortunately getCoalescingKey is not considered when sending event to C++, therefore we have to disable coalescing in v3
override fun canCoalesce() = !GestureHandler.usesNativeOrLogicDetector(actionType)
override fun canCoalesce() = !GestureHandler.usesNativeOrVirtualDetector(actionType)

override fun getCoalescingKey() = coalescingKey

override fun getEventData(): WritableMap = if (GestureHandler.usesNativeOrLogicDetector(actionType)) {
override fun getEventData(): WritableMap = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) {
createNativeEventData(dataBuilder!!)
} else {
createEventData(dataBuilder!!)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React
RNGestureHandlerEvent.createEventData(handlerFactory.createEventBuilder(handler))
sendEventForDeviceEvent(RNGestureHandlerEvent.EVENT_NAME, data)
}
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_LOGIC_DETECTOR -> {
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR -> {
val eventHandlerType = if (handler.dispatchesAnimatedEvents) {
EventHandlerType.ForAnimated
} else if (handler.dispatchesReanimatedEvents) {
Expand Down Expand Up @@ -136,7 +136,7 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React
sendEventForDeviceEvent(RNGestureHandlerStateChangeEvent.EVENT_NAME, data)
}

GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_LOGIC_DETECTOR -> {
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR -> {
val eventHandlerType = if (handler.dispatchesReanimatedEvents) {
EventHandlerType.ForReanimated
} else {
Expand Down Expand Up @@ -188,7 +188,7 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React
val data = RNGestureHandlerTouchEvent.createEventData(handler)
sendEventForDeviceEvent(RNGestureHandlerEvent.EVENT_NAME, data)
}
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_LOGIC_DETECTOR -> {
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_VIRTUAL_DETECTOR -> {
val eventHandlerType = if (handler.dispatchesReanimatedEvents) {
EventHandlerType.ForReanimated
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event<RNGestureHa
dataBuilder: GestureHandlerEventDataBuilder<T>,
eventHandlerType: EventHandlerType,
) {
val view = if (GestureHandler.usesNativeOrLogicDetector(handler.actionType)) {
val view = if (GestureHandler.usesNativeOrVirtualDetector(handler.actionType)) {
handler.viewForEvents
} else {
handler.view!!
Expand All @@ -45,7 +45,7 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event<RNGestureHa
EVENTS_POOL.release(this)
}

override fun getEventName() = if (GestureHandler.usesNativeOrLogicDetector(actionType)) {
override fun getEventName() = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) {
if (eventHandlerType == EventHandlerType.ForReanimated) REANIMATED_EVENT_NAME else EVENT_NAME
} else {
EVENT_NAME
Expand All @@ -57,7 +57,7 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event<RNGestureHa
// TODO: coalescing
override fun getCoalescingKey(): Short = 0

override fun getEventData(): WritableMap = if (GestureHandler.usesNativeOrLogicDetector(actionType)) {
override fun getEventData(): WritableMap = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) {
createNativeEventData(dataBuilder!!, newState, oldState)
} else {
createEventData(dataBuilder!!, newState, oldState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class RNGestureHandlerTouchEvent private constructor() : Event<RNGestureHandlerT
private lateinit var eventHandlerType: EventHandlerType

private fun <T : GestureHandler> init(handler: T, actionType: Int, eventHandlerType: EventHandlerType) {
val view = if (GestureHandler.usesNativeOrLogicDetector(handler.actionType)) {
val view = if (GestureHandler.usesNativeOrVirtualDetector(handler.actionType)) {
handler.viewForEvents
} else {
handler.view!!
Expand All @@ -33,13 +33,13 @@ class RNGestureHandlerTouchEvent private constructor() : Event<RNGestureHandlerT
EVENTS_POOL.release(this)
}

override fun getEventName() = if (GestureHandler.usesNativeOrLogicDetector(actionType)) {
override fun getEventName() = if (GestureHandler.usesNativeOrVirtualDetector(actionType)) {
if (eventHandlerType == EventHandlerType.ForReanimated) REANIMATED_EVENT_NAME else NATIVE_EVENT_NAME
} else {
EVENT_NAME
}

override fun canCoalesce() = !GestureHandler.usesNativeOrLogicDetector(actionType)
override fun canCoalesce() = !GestureHandler.usesNativeOrVirtualDetector(actionType)

override fun getCoalescingKey() = coalescingKey
override fun getEventData(): WritableMap? = extraData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer
// it that recognizer tried to send event, the app would crash because the target of the event
// would be nil.
if (view.reactTag == nil && _actionType != RNGestureHandlerActionTypeNativeDetector &&
_actionType != RNGestureHandlerActionTypeLogicDetector) {
_actionType != RNGestureHandlerActionTypeVirtualDetector) {
return;
}

Expand All @@ -314,7 +314,7 @@ - (void)handleGesture:(UIGestureRecognizer *)recognizer inState:(RNGestureHandle
tag = @(recognizer.view.tag);
}

if (_virtualViewTag != nil && _actionType == RNGestureHandlerActionTypeLogicDetector) {
if (_virtualViewTag != nil && _actionType == RNGestureHandlerActionTypeVirtualDetector) {
tag = _virtualViewTag;
}

Expand Down Expand Up @@ -673,7 +673,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
}

// Logic detector has a virtual view tag set only if the real hierarchy was folded into a single View
if (_actionType == RNGestureHandlerActionTypeLogicDetector && _virtualViewTag != nil) {
if (_actionType == RNGestureHandlerActionTypeVirtualDetector && _virtualViewTag != nil) {
// In this case, logic detector is attached to the DetectorView, which has a single subview representing
// the actual target view in the RN hierarchy
RNGHUIView *view = _recognizer.view.subviews[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ typedef NS_ENUM(NSInteger, RNGestureHandlerActionType) {
RNGestureHandlerActionTypeJSFunctionNewAPI, // JS function or Animated.event with useNativeDriver: false using new
// RNGH API
RNGestureHandlerActionTypeNativeDetector,
RNGestureHandlerActionTypeLogicDetector,
RNGestureHandlerActionTypeVirtualDetector,
};
Loading
Loading