ReactEventEmitter -> Kotlin (#48464)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/48464

# Changelog:
[Internal] -

As in the title.

Reviewed By: christophpurrer

Differential Revision: D67791375

fbshipit-source-id: eca1f999b43c405ce48aa5fa3518ec08363f5836
This commit is contained in:
Ruslan Shestopalyuk
2025-01-03 16:24:09 -08:00
committed by Facebook GitHub Bot
parent 076920647e
commit a6e6f5e869
4 changed files with 144 additions and 166 deletions
@@ -5780,6 +5780,13 @@ public final class com/facebook/react/uimanager/events/TouchEventType$Companion
public final fun getJSEventName (Lcom/facebook/react/uimanager/events/TouchEventType;)Ljava/lang/String;
}
public final class com/facebook/react/uimanager/events/TouchesHelper {
public static final field INSTANCE Lcom/facebook/react/uimanager/events/TouchesHelper;
public static final field TARGET_KEY Ljava/lang/String;
public static final fun sendTouchEvent (Lcom/facebook/react/uimanager/events/RCTModernEventEmitter;Lcom/facebook/react/uimanager/events/TouchEvent;)V
public static final fun sendTouchesLegacy (Lcom/facebook/react/uimanager/events/RCTEventEmitter;Lcom/facebook/react/uimanager/events/TouchEvent;)V
}
public final class com/facebook/react/uimanager/layoutanimation/InterpolatorType : java/lang/Enum {
public static final field Companion Lcom/facebook/react/uimanager/layoutanimation/InterpolatorType$Companion;
public static final field EASE_IN Lcom/facebook/react/uimanager/layoutanimation/InterpolatorType;
@@ -1,165 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.uimanager.events;
import static com.facebook.react.uimanager.events.TouchesHelper.TARGET_KEY;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactNoCrashSoftException;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.common.ViewUtil;
class ReactEventEmitter implements RCTModernEventEmitter {
private static final String TAG = "ReactEventEmitter";
/** Corresponds to {@link com.facebook.react.fabric.events.FabricEventEmitter} */
@Nullable private RCTModernEventEmitter mFabricEventEmitter = null;
/** Corresponds to (Paper) EventEmitter, which is a JS interface */
@Nullable private RCTEventEmitter mDefaultEventEmitter = null;
private final ReactApplicationContext mReactContext;
public ReactEventEmitter(ReactApplicationContext reactContext) {
mReactContext = reactContext;
}
public void register(@UIManagerType int uiManagerType, RCTModernEventEmitter eventEmitter) {
assert uiManagerType == UIManagerType.FABRIC;
mFabricEventEmitter = eventEmitter;
}
public void register(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) {
assert uiManagerType == UIManagerType.DEFAULT;
mDefaultEventEmitter = eventEmitter;
}
public void unregister(@UIManagerType int uiManagerType) {
if (uiManagerType == UIManagerType.DEFAULT) {
mDefaultEventEmitter = null;
} else {
mFabricEventEmitter = null;
}
}
@Override
public void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap event) {
receiveEvent(-1, targetReactTag, eventName, event);
}
@Override
public void receiveEvent(
int surfaceId, int targetTag, String eventName, @Nullable WritableMap event) {
// We assume this event can't be coalesced. `customCoalesceKey` has no meaning in Fabric.
receiveEvent(surfaceId, targetTag, eventName, false, 0, event, EventCategoryDef.UNSPECIFIED);
}
@Override
public void receiveTouches(
String eventName, WritableArray touches, WritableArray changedIndices) {
/*
* This method should be unused by default processing pipeline, but leaving it here to make sure
* that any custom code using it in legacy renderer is compatible
*/
Assertions.assertCondition(touches.size() > 0);
int reactTag = touches.getMap(0).getInt(TARGET_KEY);
@UIManagerType int uiManagerType = ViewUtil.getUIManagerType(reactTag);
if (uiManagerType == UIManagerType.DEFAULT && getDefaultEventEmitter() != null) {
mDefaultEventEmitter.receiveTouches(eventName, touches, changedIndices);
}
}
@Override
public void receiveTouches(TouchEvent event) {
int reactTag = event.getViewTag();
@UIManagerType
int uiManagerType = ViewUtil.getUIManagerType(event.getViewTag(), event.getSurfaceId());
if (uiManagerType == UIManagerType.FABRIC && mFabricEventEmitter != null) {
TouchesHelper.sendTouchEvent(mFabricEventEmitter, event);
} else if (uiManagerType == UIManagerType.DEFAULT && getDefaultEventEmitter() != null) {
TouchesHelper.sendTouchesLegacy(mDefaultEventEmitter, event);
} else {
ReactSoftExceptionLogger.logSoftException(
TAG,
new ReactNoCrashSoftException(
"Cannot find EventEmitter for receivedTouches: ReactTag["
+ reactTag
+ "] UIManagerType["
+ uiManagerType
+ "] EventName["
+ event.getEventName()
+ "]"));
}
}
/**
* Get default/Paper event emitter. Callers should have verified that this is not an event for a
* View managed by Fabric
*/
@Nullable
private RCTEventEmitter getDefaultEventEmitter() {
if (mDefaultEventEmitter == null) {
if (mReactContext.hasActiveReactInstance()) {
mDefaultEventEmitter = mReactContext.getJSModule(RCTEventEmitter.class);
} else {
ReactSoftExceptionLogger.logSoftException(
TAG,
new ReactNoCrashSoftException(
"Cannot get RCTEventEmitter from Context, no active Catalyst instance!"));
}
}
return mDefaultEventEmitter;
}
@Override
public void receiveEvent(
int surfaceId,
int targetReactTag,
String eventName,
boolean canCoalesceEvent,
int customCoalesceKey,
@Nullable WritableMap event,
@EventCategoryDef int category) {
@UIManagerType int uiManagerType = ViewUtil.getUIManagerType(targetReactTag, surfaceId);
if (uiManagerType == UIManagerType.FABRIC && mFabricEventEmitter != null) {
mFabricEventEmitter.receiveEvent(
surfaceId,
targetReactTag,
eventName,
canCoalesceEvent,
customCoalesceKey,
event,
category);
} else if (uiManagerType == UIManagerType.DEFAULT) {
RCTEventEmitter defaultEmitter = getDefaultEventEmitter();
if (defaultEmitter != null) {
defaultEmitter.receiveEvent(targetReactTag, eventName, event);
}
} else {
ReactSoftExceptionLogger.logSoftException(
TAG,
new ReactNoCrashSoftException(
"Cannot find EventEmitter for receiveEvent: SurfaceId["
+ surfaceId
+ "] ReactTag["
+ targetReactTag
+ "] UIManagerType["
+ uiManagerType
+ "] EventName["
+ eventName
+ "]"));
}
}
}
@@ -0,0 +1,136 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// RCTEventEmitter usage throughout:
@file:Suppress("DEPRECATION")
package com.facebook.react.uimanager.events
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactNoCrashSoftException
import com.facebook.react.bridge.ReactSoftExceptionLogger.logSoftException
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.common.UIManagerType
import com.facebook.react.uimanager.common.ViewUtil.getUIManagerType
internal class ReactEventEmitter(private val reactContext: ReactApplicationContext) :
RCTModernEventEmitter {
/** Corresponds to [com.facebook.react.fabric.events.FabricEventEmitter] */
private var fabricEventEmitter: RCTModernEventEmitter? = null
/** Corresponds to (Paper) EventEmitter, which is a JS interface */
private var defaultEventEmitter: RCTEventEmitter? = null
fun register(@UIManagerType uiManagerType: Int, eventEmitter: RCTModernEventEmitter?) {
check(uiManagerType == UIManagerType.FABRIC)
fabricEventEmitter = eventEmitter
}
fun register(@UIManagerType uiManagerType: Int, eventEmitter: RCTEventEmitter?) {
check(uiManagerType == UIManagerType.DEFAULT)
defaultEventEmitter = eventEmitter
}
fun unregister(@UIManagerType uiManagerType: Int) {
if (uiManagerType == UIManagerType.DEFAULT) {
defaultEventEmitter = null
} else {
fabricEventEmitter = null
}
}
@Deprecated("Please use RCTModernEventEmitter")
override fun receiveEvent(targetReactTag: Int, eventName: String, event: WritableMap?) {
receiveEvent(-1, targetReactTag, eventName, event)
}
override fun receiveEvent(
surfaceId: Int,
targetTag: Int,
eventName: String,
event: WritableMap?
) {
// We assume this event can't be coalesced. `customCoalesceKey` has no meaning in Fabric.
receiveEvent(surfaceId, targetTag, eventName, false, 0, event, EventCategoryDef.UNSPECIFIED)
}
@Deprecated("Please use RCTModernEventEmitter")
override fun receiveTouches(
eventName: String,
touches: WritableArray,
changedIndices: WritableArray
) {
/*
* This method should be unused by default processing pipeline, but leaving it here to make sure
* that any custom code using it in legacy renderer is compatible
*/
check(touches.size() > 0)
val reactTag = touches.getMap(0)?.getInt(TouchesHelper.TARGET_KEY) ?: 0
@UIManagerType val uiManagerType = getUIManagerType(reactTag)
if (uiManagerType == UIManagerType.DEFAULT) {
ensureDefaultEventEmitter()?.receiveTouches(eventName, touches, changedIndices)
}
}
@Deprecated("Please use RCTModernEventEmitter")
override fun receiveTouches(event: TouchEvent) {
@UIManagerType val uiManagerType = getUIManagerType(event.viewTag, event.surfaceId)
if (uiManagerType == UIManagerType.FABRIC) {
fabricEventEmitter?.let { TouchesHelper.sendTouchEvent(it, event) }
} else if (uiManagerType == UIManagerType.DEFAULT) {
ensureDefaultEventEmitter()?.let { TouchesHelper.sendTouchesLegacy(it, event) }
}
}
/**
* Get default/Paper event emitter. Callers should have verified that this is not an event for a
* View managed by Fabric
*/
private fun ensureDefaultEventEmitter(): RCTEventEmitter? {
if (defaultEventEmitter == null) {
if (reactContext.hasActiveReactInstance()) {
defaultEventEmitter = reactContext.getJSModule(RCTEventEmitter::class.java)
} else {
logSoftException(
TAG,
ReactNoCrashSoftException(
"Cannot get RCTEventEmitter from Context, no active Catalyst instance!"))
}
}
return defaultEventEmitter
}
override fun receiveEvent(
surfaceId: Int,
targetReactTag: Int,
eventName: String,
canCoalesceEvent: Boolean,
customCoalesceKey: Int,
event: WritableMap?,
@EventCategoryDef category: Int
) {
@UIManagerType val uiManagerType = getUIManagerType(targetReactTag, surfaceId)
if (uiManagerType == UIManagerType.FABRIC) {
fabricEventEmitter?.receiveEvent(
surfaceId,
targetReactTag,
eventName,
canCoalesceEvent,
customCoalesceKey,
event,
category)
} else if (uiManagerType == UIManagerType.DEFAULT) {
ensureDefaultEventEmitter()?.receiveEvent(targetReactTag, eventName, event)
}
}
companion object {
private const val TAG = "ReactEventEmitter"
}
}
@@ -15,7 +15,7 @@ import com.facebook.react.uimanager.events.TouchEventType.Companion.getJSEventNa
import com.facebook.systrace.Systrace
/** Class responsible for generating catalyst touch events based on android [MotionEvent]. */
internal object TouchesHelper {
public object TouchesHelper {
@JvmField @Deprecated("Not used in New Architecture") public val TARGET_KEY: String = "target"
private const val TARGET_SURFACE_KEY = "targetSurface"