Convert InteropEvent and InteropEventEmitter to Kotlin (#42358)

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

Just converting those two classes to Kotlin as I was going over them.

Changelog:
[Internal] [Changed] - Convert InteropEvent and InteropEventEmitter to Kotlin

Reviewed By: javache

Differential Revision: D52869490

fbshipit-source-id: 2d585dd3d21dc89c5e55de645e9519d36f67b849
This commit is contained in:
Nicola Corti
2024-01-19 05:00:28 -08:00
committed by Facebook GitHub Bot
parent e2a02f0558
commit 26ecd3817c
5 changed files with 88 additions and 109 deletions
@@ -1,41 +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.internal.interop;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.events.Event;
/**
* An {@link Event} class used by the {@link InteropEventEmitter}. This class is just holding the
* event name and the data which is received by the `receiveEvent` method and will be passed over
* the the {@link com.facebook.react.uimanager.events.EventDispatcher}
*/
class InteropEvent extends Event<InteropEvent> {
private final String mName;
private final WritableMap mEventData;
InteropEvent(String name, @Nullable WritableMap eventData, int surfaceId, int viewTag) {
super(surfaceId, viewTag);
mName = name;
mEventData = eventData;
}
@Override
public String getEventName() {
return mName;
}
@Override
@VisibleForTesting
public WritableMap getEventData() {
return mEventData;
}
}
@@ -0,0 +1,27 @@
/*
* 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.internal.interop
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.events.Event
/**
* An [Event] class used by the [InteropEventEmitter]. This class is just holding the event name and
* the data which is received by the `receiveEvent` method and will be passed over the the
* [com.facebook.react.uimanager.events.EventDispatcher]
*/
class InteropEvent(
@get:JvmName("eventName") val eventName: String,
@get:JvmName("eventData") val eventData: WritableMap?,
surfaceId: Int,
viewTag: Int
) : Event<InteropEvent>(surfaceId, viewTag) {
override fun getEventName(): String = eventName
override fun getEventData(): WritableMap? = eventData
}
@@ -1,65 +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.internal.interop;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.events.RCTEventEmitter;
/**
* A reimplementation of {@link RCTEventEmitter} which is using a {@link EventDispatcher} under the
* hood.
*
* <p>On Fabric, you're supposed to use {@link EventDispatcher} to dispatch events. However, we
* provide an interop layer for non-Fabric migrated components.
*
* <p>This instance will be returned if the user is invoking `context.getJsModule(RCTEventEmitter)
* and is providing support for the `receiveEvent` method, so that non-Fabric ViewManagers can
* continue to deliver events also when Fabric is turned on.
*/
public class InteropEventEmitter implements RCTEventEmitter {
private final ReactContext mReactContext;
private @Nullable EventDispatcher mEventDispatcherOverride;
public InteropEventEmitter(ReactContext reactContext) {
mReactContext = reactContext;
}
@Override
public void receiveEvent(int targetReactTag, String eventName, @Nullable WritableMap eventData) {
EventDispatcher dispatcher;
if (mEventDispatcherOverride != null) {
dispatcher = mEventDispatcherOverride;
} else {
dispatcher = UIManagerHelper.getEventDispatcherForReactTag(mReactContext, targetReactTag);
}
int surfaceId = UIManagerHelper.getSurfaceId(mReactContext);
if (dispatcher != null) {
dispatcher.dispatchEvent(new InteropEvent(eventName, eventData, surfaceId, targetReactTag));
}
}
@Override
public void receiveTouches(
String eventName, WritableArray touches, WritableArray changedIndices) {
throw new UnsupportedOperationException(
"EventEmitter#receiveTouches is not supported by the Fabric Interop Layer");
}
@VisibleForTesting
void overrideEventDispatcher(EventDispatcher eventDispatcherOverride) {
mEventDispatcherOverride = eventDispatcherOverride;
}
}
@@ -0,0 +1,55 @@
/*
* 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.
*/
@file:Suppress("DEPRECATION") // We want to use RCTEventEmitter for interop purposes
package com.facebook.react.internal.interop
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableMap
import com.facebook.react.common.annotations.VisibleForTesting
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.uimanager.events.RCTEventEmitter
/**
* A reimplementation of [RCTEventEmitter] which is using a [EventDispatcher] under the hood.
*
* On Fabric, you're supposed to use [EventDispatcher] to dispatch events. However, we provide an
* interop layer for non-Fabric migrated components.
*
* This instance will be returned if the user is invoking `context.getJsModule(RCTEventEmitter) and
* is providing support for the `receiveEvent` method, so that non-Fabric ViewManagers can continue
* to deliver events also when Fabric is turned on.
*/
class InteropEventEmitter(private val reactContext: ReactContext) : RCTEventEmitter {
private var eventDispatcherOverride: EventDispatcher? = null
@Deprecated("Deprecated in Java")
override fun receiveEvent(targetReactTag: Int, eventName: String, eventData: WritableMap?) {
val dispatcher: EventDispatcher? =
eventDispatcherOverride
?: UIManagerHelper.getEventDispatcherForReactTag(reactContext, targetReactTag)
val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
dispatcher?.dispatchEvent(InteropEvent(eventName, eventData, surfaceId, targetReactTag))
}
override fun receiveTouches(
eventName: String,
touches: WritableArray,
changedIndices: WritableArray
) {
throw UnsupportedOperationException(
"EventEmitter#receiveTouches is not supported by the Fabric Interop Layer")
}
@VisibleForTesting
fun overrideEventDispatcher(eventDispatcherOverride: EventDispatcher?) {
this.eventDispatcherOverride = eventDispatcherOverride
}
}
@@ -5,8 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/
@file:Suppress("DEPRECATION") // We want to use RCTEventEmitter for interop purposes
package com.facebook.react.internal.interop
import com.facebook.react.bridge.JavaOnlyArray
import com.facebook.react.bridge.JavaOnlyMap
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContext
@@ -50,8 +53,8 @@ class InteropEventEmitterTest {
eventEmitter.receiveEvent(42, "onTest", eventData)
val event = eventDispatcher.getRecordedDispatchedEvents().get(0) as InteropEvent
val dispatchedEventData = event.getEventData()
val event = eventDispatcher.getRecordedDispatchedEvents()[0] as InteropEvent
val dispatchedEventData = event.eventData
assertNotNull(dispatchedEventData)
assertEquals("indigo", dispatchedEventData!!.getString("color"))
}
@@ -59,6 +62,6 @@ class InteropEventEmitterTest {
@Test(expected = java.lang.UnsupportedOperationException::class)
fun receiveTouches_isNotSupported() {
val eventEmitter = InteropEventEmitter(reactContext)
eventEmitter.receiveTouches("a touch", null, null)
eventEmitter.receiveTouches("a touch", JavaOnlyArray.of(), JavaOnlyArray.of())
}
}