diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 2a0baaeace09..54bd00292407 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -1108,8 +1108,6 @@ public void receiveEvent( * that C++ may coalesce the event optionally. Otherwise, coalescing can happen in Java before * emitting. * - *

{@code customCoalesceKey} is currently unused. - * * @param surfaceId * @param reactTag * @param eventName @@ -1142,8 +1140,6 @@ public void receiveEvent( * that C++ may coalesce the event optionally. Otherwise, coalescing can happen in Java before * emitting. * - *

{@code customCoalesceKey} is currently unused. - * * @param surfaceId * @param reactTag * @param eventName @@ -1179,8 +1175,6 @@ public void receiveEvent( * that C++ may coalesce the event optionally. Otherwise, coalescing can happen in Java before * emitting. * - *

{@code customCoalesceKey} is currently unused. - * * @param surfaceId * @param reactTag * @param eventName @@ -1200,6 +1194,28 @@ public void receiveEvent( @EventCategoryDef int eventCategory, boolean experimentalIsSynchronous, long eventTimestamp) { + receiveEvent( + surfaceId, + reactTag, + eventName, + canCoalesceEvent, + params, + eventCategory, + experimentalIsSynchronous, + eventTimestamp, + 0); + } + + public void receiveEvent( + int surfaceId, + int reactTag, + String eventName, + boolean canCoalesceEvent, + @Nullable WritableMap params, + @EventCategoryDef int eventCategory, + boolean experimentalIsSynchronous, + long eventTimestamp, + int customCoalesceKey) { if (ReactBuildConfig.DEBUG && surfaceId == View.NO_ID) { FLog.d(TAG, "Emitted event without surfaceId: [%d] %s", reactTag, eventName); @@ -1225,7 +1241,14 @@ public void receiveEvent( } mMountingManager.dispatchEvent( - surfaceId, reactTag, eventName, canCoalesceEvent, params, eventCategory, eventTimestamp); + surfaceId, + reactTag, + eventName, + canCoalesceEvent, + params, + eventCategory, + eventTimestamp, + customCoalesceKey); } @Override diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.kt index 4a61bf606ad9..83fac4d69318 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/EventEmitterWrapper.kt @@ -40,6 +40,7 @@ internal class EventEmitterWrapper private constructor() : HybridClassBase() { eventName: String, params: NativeMap?, eventTimestamp: Long, + customCoalesceKey: Int, ) /** @@ -82,10 +83,29 @@ internal class EventEmitterWrapper private constructor() : HybridClassBase() { */ @Synchronized fun dispatchUnique(eventName: String, params: WritableMap?, eventTimestamp: Long) { + dispatchUnique(eventName, params, eventTimestamp, 0) + } + + /** + * Invokes the execution of the C++ EventEmitter. C++ will coalesce events sent to the same target + * with the same event name and coalescing key. + * + * @param eventName [String] name of the event to execute. + * @param params [WritableMap] payload of the event + * @param eventTimestamp timestamp when the event was triggered (in milliseconds since boot) + * @param customCoalesceKey key that determines which same-name events can coalesce together + */ + @Synchronized + fun dispatchUnique( + eventName: String, + params: WritableMap?, + eventTimestamp: Long, + customCoalesceKey: Int, + ) { if (!isValid) { return } - dispatchUniqueEvent(eventName, params as NativeMap?, eventTimestamp) + dispatchUniqueEvent(eventName, params as NativeMap?, eventTimestamp, customCoalesceKey) } @Synchronized diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.kt index dad9cd3d5556..d0ad8bc28d4f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/events/FabricEventEmitter.kt @@ -58,6 +58,7 @@ internal class FabricEventEmitter(private val uiManager: FabricUIManager) : RCTM category, false, eventTimestamp, + customCoalesceKey, ) } finally { Systrace.endSection(Systrace.TRACE_TAG_REACT) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt index 48410a98298a..26dbef85d737 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.kt @@ -335,6 +335,7 @@ internal class MountingManager( params: WritableMap?, @EventCategoryDef eventCategory: Int, eventTimestamp: Long, + customCoalesceKey: Int = 0, ) { val smm = getSurfaceMountingManager(surfaceId, reactTag) if (smm == null) { @@ -347,7 +348,15 @@ internal class MountingManager( ) return } - smm.dispatchEvent(reactTag, eventName, canCoalesceEvent, params, eventCategory, eventTimestamp) + smm.dispatchEvent( + reactTag, + eventName, + canCoalesceEvent, + params, + eventCategory, + eventTimestamp, + customCoalesceKey, + ) } private fun getSurfaceMountingManager(surfaceId: Int, reactTag: Int): SurfaceMountingManager? = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt index f02de8b36971..85d54385bc95 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.kt @@ -1204,6 +1204,7 @@ internal constructor( params: WritableMap?, @EventCategoryDef eventCategory: Int, eventTimestamp: Long, + customCoalesceKey: Int = 0, ) { val viewState = registryGet(reactTag) if (viewState == null) { @@ -1225,7 +1226,14 @@ internal constructor( viewState.pendingEventQueue ?: LinkedList().also { viewState.pendingEventQueue = it } queue.add( - PendingViewEvent(eventName, params, eventCategory, canCoalesceEvent, eventTimestamp) + PendingViewEvent( + eventName, + params, + eventCategory, + canCoalesceEvent, + eventTimestamp, + customCoalesceKey, + ) ) return } @@ -1241,7 +1249,7 @@ internal constructor( checkNotNull(emitter) if (canCoalesceEvent) { - emitter.dispatchUnique(eventName, params, eventTimestamp) + emitter.dispatchUnique(eventName, params, eventTimestamp, customCoalesceKey) } else { emitter.dispatch(eventName, params, eventCategory, eventTimestamp) } @@ -1286,10 +1294,11 @@ internal constructor( @field:EventCategoryDef private val eventCategory: Int, private val canCoalesceEvent: Boolean, private val eventTimestamp: Long, + private val customCoalesceKey: Int, ) { fun dispatch(eventEmitter: EventEmitterWrapper) { if (canCoalesceEvent) { - eventEmitter.dispatchUnique(eventName, params, eventTimestamp) + eventEmitter.dispatchUnique(eventName, params, eventTimestamp, customCoalesceKey) } else { eventEmitter.dispatch(eventName, params, eventCategory, eventTimestamp) } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.kt index 2720516397b7..c18b073bb989 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/RCTModernEventEmitter.kt @@ -30,7 +30,7 @@ public interface RCTModernEventEmitter : RCTEventEmitter { @Deprecated("Use the overload with eventTimestamp parameter instead.") public fun receiveEvent(surfaceId: Int, targetTag: Int, eventName: String, params: WritableMap?) { - // We assume this event can't be coalesced. `customCoalesceKey` has no meaning in Fabric. + // We assume this event can't be coalesced. receiveEvent(surfaceId, targetTag, eventName, false, 0, params, EventCategoryDef.UNSPECIFIED) } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp index 5d76e5e197fe..81c23be9fb79 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.cpp @@ -66,7 +66,8 @@ void EventEmitterWrapper::dispatchEventSynchronously( void EventEmitterWrapper::dispatchUniqueEvent( std::string eventName, NativeMap* payload, - jlong eventTimestamp) { + jlong eventTimestamp, + int customCoalesceKey) { // It is marginal, but possible for this to be constructed without a valid // EventEmitter. In those cases, make sure we noop/blackhole events instead of // crashing. @@ -74,7 +75,8 @@ void EventEmitterWrapper::dispatchUniqueEvent( eventEmitter->dispatchUniqueEvent( std::move(eventName), (payload != nullptr) ? payload->consume() : folly::dynamic::object(), - highResTimeStampFromMillis(eventTimestamp)); + highResTimeStampFromMillis(eventTimestamp), + customCoalesceKey); } } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h index 50143ad8f6c9..2d89b07cfead 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h @@ -27,7 +27,11 @@ class EventEmitterWrapper : public jni::HybridClass { void dispatchEvent(std::string eventName, NativeMap *payload, int category, jlong eventTimestamp); void dispatchEventSynchronously(std::string eventName, NativeMap *params, jlong eventTimestamp); - void dispatchUniqueEvent(std::string eventName, NativeMap *payload, jlong eventTimestamp); + void dispatchUniqueEvent( + std::string eventName, + NativeMap *payload, + jlong eventTimestamp, + int customCoalesceKey); }; } // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/SurfaceMountingManagerEventOrderingTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/SurfaceMountingManagerEventOrderingTest.kt index af0e1893d3f9..bc2252e0abd1 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/SurfaceMountingManagerEventOrderingTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/SurfaceMountingManagerEventOrderingTest.kt @@ -167,7 +167,7 @@ class SurfaceMountingManagerEventOrderingTest { ) verify(emitter, never()).dispatch(any(), any(), any(), any()) - verify(emitter, never()).dispatchUnique(any(), any(), any()) + verify(emitter, never()).dispatchUnique(any(), any(), any(), any()) verifyNoMoreInteractions(emitter) } @@ -179,10 +179,21 @@ class SurfaceMountingManagerEventOrderingTest { smm.dispatchEvent(reactTag, "topScroll", true, null, EventCategoryDef.UNSPECIFIED, 0L) - verify(emitter).dispatchUnique("topScroll", null, 0L) + verify(emitter).dispatchUnique("topScroll", null, 0L, 0) verify(emitter, never()).dispatch("topScroll", null, EventCategoryDef.UNSPECIFIED, 0L) } + @Test + fun dispatchEvent_forwardsCoalescingKey_forCoalesceableEvents() { + val smm = startSurfaceWithView() + val emitter: EventEmitterWrapper = mock() + smm.updateEventEmitter(reactTag, emitter) + + smm.dispatchEvent(reactTag, "topScroll", true, null, EventCategoryDef.UNSPECIFIED, 0L, 7) + + verify(emitter).dispatchUnique("topScroll", null, 0L, 7) + } + @Test fun dispatchEvent_coalesceableEvents_drainedFromQueueUseDispatchUnique() { val smm = startSurfaceWithView() @@ -192,7 +203,19 @@ class SurfaceMountingManagerEventOrderingTest { val emitter: EventEmitterWrapper = mock() smm.updateEventEmitter(reactTag, emitter) - verify(emitter).dispatchUnique("topScroll", null, 1L) + verify(emitter).dispatchUnique("topScroll", null, 1L, 0) + } + + @Test + fun dispatchEvent_coalesceableEvents_drainedFromQueueForwardCoalescingKey() { + val smm = startSurfaceWithView() + + smm.dispatchEvent(reactTag, "topScroll", true, null, EventCategoryDef.UNSPECIFIED, 1L, 9) + + val emitter: EventEmitterWrapper = mock() + smm.updateEventEmitter(reactTag, emitter) + + verify(emitter).dispatchUnique("topScroll", null, 1L, 9) } /** After a drain cycle, subsequent events should dispatch directly (fast path). */ @@ -308,7 +331,7 @@ class SurfaceMountingManagerEventOrderingTest { val ordered = inOrder(emitter) ordered.verify(emitter).dispatch("topChange", null, EventCategoryDef.UNSPECIFIED, 1L) - ordered.verify(emitter).dispatchUnique("topScroll", null, 2L) + ordered.verify(emitter).dispatchUnique("topScroll", null, 2L, 0) ordered.verify(emitter).dispatch("topFocus", null, EventCategoryDef.UNSPECIFIED, 3L) } diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/FabricEventEmitterTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/FabricEventEmitterTest.kt new file mode 100644 index 000000000000..1ad2236bd63b --- /dev/null +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/fabric/events/FabricEventEmitterTest.kt @@ -0,0 +1,109 @@ +/* + * 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.fabric.events + +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReactTestHelper +import com.facebook.react.bridge.WritableMap +import com.facebook.react.fabric.FabricUIManager +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests +import com.facebook.react.uimanager.ViewManager +import com.facebook.react.uimanager.ViewManagerRegistry +import com.facebook.react.uimanager.events.BatchEventDispatchedListener +import com.facebook.react.uimanager.events.EventCategoryDef +import com.facebook.testutils.shadows.ShadowSoLoader +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(shadows = [ShadowSoLoader::class]) +class FabricEventEmitterTest { + @Before + fun setUp() { + ReactNativeFeatureFlagsForTests.setUp() + } + + @Test + fun receiveEvent_forwardsCustomCoalesceKey() { + val reactContext = ReactTestHelper.createCatalystContextForTest() + val uiManager = RecordingFabricUIManager(reactContext) + val eventEmitter = FabricEventEmitter(uiManager) + + eventEmitter.receiveEvent( + surfaceId = 1, + targetTag = 2, + eventName = "topChange", + canCoalesceEvent = true, + customCoalesceKey = 37, + params = null, + category = EventCategoryDef.UNSPECIFIED, + eventTimestamp = 123L, + ) + + assertThat(uiManager.receivedEvent) + .isEqualTo( + ReceivedEvent( + surfaceId = 1, + reactTag = 2, + eventName = "topChange", + canCoalesceEvent = true, + eventCategory = EventCategoryDef.UNSPECIFIED, + experimentalIsSynchronous = false, + eventTimestamp = 123L, + customCoalesceKey = 37, + )) + } + + private class RecordingFabricUIManager(reactContext: ReactApplicationContext) : + FabricUIManager( + reactContext, + ViewManagerRegistry(emptyList>()), + BatchEventDispatchedListener {}, + ) { + var receivedEvent: ReceivedEvent? = null + + override fun receiveEvent( + surfaceId: Int, + reactTag: Int, + eventName: String, + canCoalesceEvent: Boolean, + params: WritableMap?, + eventCategory: Int, + experimentalIsSynchronous: Boolean, + eventTimestamp: Long, + customCoalesceKey: Int, + ) { + receivedEvent = + ReceivedEvent( + surfaceId, + reactTag, + eventName, + canCoalesceEvent, + eventCategory, + experimentalIsSynchronous, + eventTimestamp, + customCoalesceKey, + ) + } + } + + private data class ReceivedEvent( + val surfaceId: Int, + val reactTag: Int, + val eventName: String, + val canCoalesceEvent: Boolean, + val eventCategory: Int, + val experimentalIsSynchronous: Boolean, + val eventTimestamp: Long, + val customCoalesceKey: Int, + ) +} diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h index 88a9a953e423..81cf2b8f5b0a 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h @@ -48,8 +48,8 @@ class EventDispatcher { /* * Dispatches a raw event with asynchronous batched priority. Before the - * dispatch we make sure that no other RawEvent of same type and same target - * is on the queue. + * dispatch we make sure that no other RawEvent of same type, same target, + * and same coalescing key is on the queue. */ void dispatchUniqueEvent(RawEvent &&rawEvent) const; diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp index 2d6ac50e3730..e83ea7f53366 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp @@ -92,6 +92,18 @@ void EventEmitter::dispatchUniqueEvent( eventTimestamp); } +void EventEmitter::dispatchUniqueEvent( + std::string type, + folly::dynamic&& payload, + HighResTimeStamp eventTimestamp, + RawEvent::CoalescingKey coalescingKey) const { + dispatchUniqueEvent( + std::move(type), + DynamicEventPayload::create(std::move(payload)), + eventTimestamp, + coalescingKey); +} + void EventEmitter::dispatchEvent( std::string type, const ValueFactory& payloadFactory, @@ -181,6 +193,18 @@ void EventEmitter::dispatchUniqueEvent( std::string type, SharedEventPayload payload, HighResTimeStamp eventTimestamp) const { + dispatchUniqueEvent( + std::move(type), + std::move(payload), + eventTimestamp, + RawEvent::DefaultCoalescingKey); +} + +void EventEmitter::dispatchUniqueEvent( + std::string type, + SharedEventPayload payload, + HighResTimeStamp eventTimestamp, + RawEvent::CoalescingKey coalescingKey) const { TraceSection s("EventEmitter::dispatchUniqueEvent"); auto eventDispatcher = eventDispatcher_.lock(); @@ -203,7 +227,8 @@ void EventEmitter::dispatchUniqueEvent( std::move(shadowNodeFamily), RawEvent::Category::Continuous, true, - eventTimestamp)); + eventTimestamp, + coalescingKey)); } void EventEmitter::setEnabled(bool enabled) { diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h index f3e9a4c334e7..53dee21a52fb 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h @@ -126,8 +126,20 @@ class EventEmitter { void dispatchUniqueEvent(std::string type, folly::dynamic &&payload, HighResTimeStamp eventTimestamp) const; + void dispatchUniqueEvent( + std::string type, + folly::dynamic &&payload, + HighResTimeStamp eventTimestamp, + RawEvent::CoalescingKey coalescingKey) const; + void dispatchUniqueEvent(std::string type, SharedEventPayload payload, HighResTimeStamp eventTimestamp) const; + void dispatchUniqueEvent( + std::string type, + SharedEventPayload payload, + HighResTimeStamp eventTimestamp, + RawEvent::CoalescingKey coalescingKey) const; + private: friend class UIManagerBinding; diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp index 6e99fd71bb7a..6a475396c5b5 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.cpp @@ -35,7 +35,8 @@ void EventQueue::enqueueEvent(RawEvent&& rawEvent) const { // for the same target. If the same target has event types A1, B1 // in the event queue and event A2 occurs. A1 has to stay in the // queue. - if (it->isUnique && it->type == rawEvent.type) { + if (it->isUnique && it->type == rawEvent.type && + it->coalescingKey == rawEvent.coalescingKey) { repeatedEvent = it; } diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h index f525767478aa..e0462a5ce0a5 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventQueue.h @@ -47,7 +47,8 @@ class EventQueue { /* * Enqueues and (probably later) dispatches a given event. - * Deletes last RawEvent from the queue if it has the same type and target. + * Deletes last RawEvent from the queue if it has the same type, target, and + * coalescing key. * Can be called on any thread. */ void enqueueUniqueEvent(RawEvent &&rawEvent) const; diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp index bced302982b1..33714e6c552f 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.cpp @@ -16,13 +16,15 @@ RawEvent::RawEvent( std::weak_ptr shadowNodeFamily, Category category, bool isUnique, - HighResTimeStamp eventStartTimeStamp) + HighResTimeStamp eventStartTimeStamp, + CoalescingKey coalescingKey) : type(std::move(type)), eventPayload(std::move(eventPayload)), eventTarget(std::move(eventTarget)), shadowNodeFamily(std::move(shadowNodeFamily)), category(category), isUnique(isUnique), + coalescingKey(coalescingKey), eventStartTimeStamp(eventStartTimeStamp) {} } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h index 3111ee7cddfe..fbbdc2e603ac 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h +++ b/packages/react-native/ReactCommon/react/renderer/core/RawEvent.h @@ -23,6 +23,9 @@ class ShadowNodeFamily; * Represents ready-to-dispatch event object. */ struct RawEvent { + using CoalescingKey = int; + static constexpr CoalescingKey DefaultCoalescingKey = 0; + /* * Defines category of a native platform event. This is used to deduce types * of events for Concurrent Mode. @@ -74,7 +77,8 @@ struct RawEvent { std::weak_ptr shadowNodeFamily, Category category = Category::Unspecified, bool isUnique = false, - HighResTimeStamp eventStartTimeStamp = HighResTimeStamp::now()); + HighResTimeStamp eventStartTimeStamp = HighResTimeStamp::now(), + CoalescingKey coalescingKey = DefaultCoalescingKey); std::string type; SharedEventPayload eventPayload; @@ -83,6 +87,7 @@ struct RawEvent { Category category; EventTag loggingTag{0}; bool isUnique{false}; + CoalescingKey coalescingKey{DefaultCoalescingKey}; // The timestamp for the event start time. This defaults to the current // time if not specified by the client (e.g., when MotionEvent was triggered diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp b/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp index 346474533719..39a72a474153 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/EventQueueProcessorTest.cpp @@ -10,12 +10,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -65,6 +67,81 @@ class EventQueueProcessorTest : public testing::Test { ValueFactory dummyValueFactory_; }; +class NoopEventBeat final : public EventBeat { + public: + explicit NoopEventBeat(RuntimeScheduler& runtimeScheduler) + : EventBeat(std::make_shared(), runtimeScheduler) {} + + void request() const override {} + void requestSynchronous() const override {} +}; + +class TestEventQueue final : public EventQueue { + public: + using EventQueue::EventQueue; + + void flush(jsi::Runtime& runtime) const { + flushEvents(runtime); + } +}; + +class EventQueueCoalescingTest : public testing::Test { + protected: + void SetUp() override { + runtime_ = facebook::hermes::makeHermesRuntime(); + + RuntimeExecutor runtimeExecutor = + [](std::function&& /*callback*/) {}; + runtimeScheduler_ = std::make_unique(runtimeExecutor); + } + + std::unique_ptr createEventQueue() { + auto eventPipe = [this]( + jsi::Runtime& /*runtime*/, + const EventTarget* /*eventTarget*/, + const std::string& type, + ReactEventPriority /*priority*/, + const EventPayload& /*payload*/, + HighResTimeStamp eventTimestamp) { + eventTypes_.push_back(type); + eventTimestamps_.push_back(eventTimestamp); + }; + + auto dummyEventPipeConclusion = [](jsi::Runtime&) {}; + auto dummyStatePipe = [](const StateUpdate&) {}; + auto mockEventLogger = std::make_shared(); + + return std::make_unique( + EventQueueProcessor( + eventPipe, + dummyEventPipeConclusion, + dummyStatePipe, + mockEventLogger), + std::make_unique(*runtimeScheduler_)); + } + + RawEvent createRawEvent( + std::string type, + RawEvent::CoalescingKey coalescingKey, + HighResTimeStamp eventTimestamp) { + return RawEvent( + std::move(type), + std::make_shared(dummyValueFactory_), + nullptr, + {}, + RawEvent::Category::Continuous, + false, + eventTimestamp, + coalescingKey); + } + + std::unique_ptr runtime_; + std::unique_ptr runtimeScheduler_; + std::vector eventTypes_; + std::vector eventTimestamps_; + ValueFactory dummyValueFactory_; +}; + TEST_F(EventQueueProcessorTest, singleUnspecifiedEvent) { eventProcessor_->flushEvents( *runtime_, @@ -205,4 +282,42 @@ TEST_F(EventQueueProcessorTest, releasesEventTargetsWhenDispatchThrows) { EXPECT_TRUE(eventTarget->getInstanceHandle(*runtime_).isNull()); } +TEST_F(EventQueueCoalescingTest, uniqueEventsWithSameCoalescingKeyCoalesce) { + auto eventQueue = createEventQueue(); + auto firstTimestamp = HighResTimeStamp::fromDOMHighResTimeStamp(1); + auto secondTimestamp = HighResTimeStamp::fromDOMHighResTimeStamp(2); + + eventQueue->enqueueUniqueEvent( + createRawEvent("topChange", 3, firstTimestamp)); + eventQueue->enqueueUniqueEvent( + createRawEvent("topChange", 3, secondTimestamp)); + + eventQueue->flush(*runtime_); + + ASSERT_EQ(eventTypes_.size(), 1); + EXPECT_EQ(eventTypes_[0], "topChange"); + EXPECT_EQ(eventTimestamps_[0], secondTimestamp); +} + +TEST_F( + EventQueueCoalescingTest, + uniqueEventsWithDifferentCoalescingKeysDoNotCoalesce) { + auto eventQueue = createEventQueue(); + auto firstTimestamp = HighResTimeStamp::fromDOMHighResTimeStamp(1); + auto secondTimestamp = HighResTimeStamp::fromDOMHighResTimeStamp(2); + + eventQueue->enqueueUniqueEvent( + createRawEvent("topChange", 3, firstTimestamp)); + eventQueue->enqueueUniqueEvent( + createRawEvent("topChange", 4, secondTimestamp)); + + eventQueue->flush(*runtime_); + + ASSERT_EQ(eventTypes_.size(), 2); + EXPECT_EQ(eventTypes_[0], "topChange"); + EXPECT_EQ(eventTypes_[1], "topChange"); + EXPECT_EQ(eventTimestamps_[0], firstTimestamp); + EXPECT_EQ(eventTimestamps_[1], secondTimestamp); +} + } // namespace facebook::react diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index eefd72a75641..babd78387cad 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -2257,8 +2257,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -2270,7 +2272,7 @@ class facebook::react::EventEmitterWrapper : public jni::HybridClass shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index 28e0d6e0a386..576370b3b87d 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -2240,8 +2240,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -2253,7 +2255,7 @@ class facebook::react::EventEmitterWrapper : public jni::HybridClass shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 46b71e3e4ad4..44acf7b1d874 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -2255,8 +2255,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -2268,7 +2270,7 @@ class facebook::react::EventEmitterWrapper : public jni::HybridClass shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 9ff8dcb229e6..339132d9a330 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -4774,8 +4774,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -9772,15 +9774,18 @@ struct facebook::react::RadialGradientSize::Dimensions { } struct facebook::react::RawEvent { - public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 7de39e2e86d2..0f5d378d9584 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -4745,8 +4745,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -9599,15 +9601,18 @@ struct facebook::react::RadialGradientSize::Dimensions { } struct facebook::react::RawEvent { - public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index f1e8fb0dd9b0..13e23c8635ef 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -4772,8 +4772,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -9763,15 +9765,18 @@ struct facebook::react::RadialGradientSize::Dimensions { } struct facebook::react::RawEvent { - public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index 2ca392777132..0a378200fb98 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -1488,8 +1488,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -5865,15 +5867,18 @@ struct facebook::react::RadialGradientSize::Dimensions { } struct facebook::react::RawEvent { - public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index 6f08190e5e4f..adba7d8c398e 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -1472,8 +1472,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -5705,15 +5707,18 @@ struct facebook::react::RadialGradientSize::Dimensions { } struct facebook::react::RawEvent { - public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category { diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index 28af4addc62d..1166c318cc73 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -1486,8 +1486,10 @@ class facebook::react::EventEmitter { public void dispatchUniqueEvent(std::string type, const facebook::react::ValueFactory& payloadFactory, facebook::react::HighResTimeStamp eventTimestamp) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload) const; public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, facebook::react::SharedEventPayload payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const; public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp) const; + public void dispatchUniqueEvent(std::string type, folly::dynamic&& payload, facebook::react::HighResTimeStamp eventTimestamp, facebook::react::RawEvent::CoalescingKey coalescingKey) const; public void setEnabled(bool enabled); public void setShadowNodeFamily(std::weak_ptr shadowNodeFamily); } @@ -5856,15 +5858,18 @@ struct facebook::react::RadialGradientSize::Dimensions { } struct facebook::react::RawEvent { - public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now()); + public RawEvent(std::string type, facebook::react::SharedEventPayload eventPayload, facebook::react::SharedEventTarget eventTarget, std::weak_ptr shadowNodeFamily, facebook::react::RawEvent::Category category = facebook::react::RawEvent::Category::Unspecified, bool isUnique = false, facebook::react::HighResTimeStamp eventStartTimeStamp = facebook::react::HighResTimeStamp::now(), facebook::react::RawEvent::CoalescingKey coalescingKey = facebook::react::RawEvent::DefaultCoalescingKey); public bool isUnique; public facebook::react::EventTag loggingTag; public facebook::react::HighResTimeStamp eventStartTimeStamp; public facebook::react::RawEvent::Category category; + public facebook::react::RawEvent::CoalescingKey coalescingKey; public facebook::react::SharedEventPayload eventPayload; public facebook::react::SharedEventTarget eventTarget; + public static constexpr facebook::react::RawEvent::CoalescingKey DefaultCoalescingKey; public std::string type; public std::weak_ptr shadowNodeFamily; + public using CoalescingKey = int; } enum facebook::react::RawEvent::Category {