diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 50eabadaab6..57dc500d336 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<20c445fde7a1c2607b58b7797346431f>> + * @generated SignedSource<> */ /** @@ -76,6 +76,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableSpannableBuildingUnification(): Boolean = accessor.enableSpannableBuildingUnification() + /** + * Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread). + */ + @JvmStatic + public fun enableSynchronousStateUpdates(): Boolean = accessor.enableSynchronousStateUpdates() + /** * Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution). */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 7df37086a8a..d02b7bef8a5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6e973dcdcdfae14c77a6130207333551>> + * @generated SignedSource<<9184044883f829855c2de9db42566287>> */ /** @@ -28,6 +28,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableMicrotasksCache: Boolean? = null private var enableMountHooksAndroidCache: Boolean? = null private var enableSpannableBuildingUnificationCache: Boolean? = null + private var enableSynchronousStateUpdatesCache: Boolean? = null private var enableUIConsistencyCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null @@ -105,6 +106,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableSynchronousStateUpdates(): Boolean { + var cached = enableSynchronousStateUpdatesCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableSynchronousStateUpdates() + enableSynchronousStateUpdatesCache = cached + } + return cached + } + override fun enableUIConsistency(): Boolean { var cached = enableUIConsistencyCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 465c71cf32c..155338b4f95 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<0d34567fc05555ae401e7f5180dc8771>> + * @generated SignedSource<<4154c0f81f2e5ad7ff03e252c4aa965c>> */ /** @@ -44,6 +44,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableSpannableBuildingUnification(): Boolean + @DoNotStrip @JvmStatic public external fun enableSynchronousStateUpdates(): Boolean + @DoNotStrip @JvmStatic public external fun enableUIConsistency(): Boolean @DoNotStrip @JvmStatic public external fun inspectorEnableCxxInspectorPackagerConnection(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 1e0f7a392d8..5931f315b79 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -39,6 +39,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableSpannableBuildingUnification(): Boolean = false + override fun enableSynchronousStateUpdates(): Boolean = false + override fun enableUIConsistency(): Boolean = false override fun inspectorEnableCxxInspectorPackagerConnection(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 698251ab09d..bd486e40c1e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8908de9b9d0186f1916d8b55d5854cb2>> + * @generated SignedSource<> */ /** @@ -32,6 +32,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableMicrotasksCache: Boolean? = null private var enableMountHooksAndroidCache: Boolean? = null private var enableSpannableBuildingUnificationCache: Boolean? = null + private var enableSynchronousStateUpdatesCache: Boolean? = null private var enableUIConsistencyCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null @@ -117,6 +118,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableSynchronousStateUpdates(): Boolean { + var cached = enableSynchronousStateUpdatesCache + if (cached == null) { + cached = currentProvider.enableSynchronousStateUpdates() + accessedFeatureFlags.add("enableSynchronousStateUpdates") + enableSynchronousStateUpdatesCache = cached + } + return cached + } + override fun enableUIConsistency(): Boolean { var cached = enableUIConsistencyCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 1bd4b3ad6a4..195b7e7b096 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7555a704535615fcea44c1261095419a>> + * @generated SignedSource<> */ /** @@ -39,6 +39,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableSpannableBuildingUnification(): Boolean + @DoNotStrip public fun enableSynchronousStateUpdates(): Boolean + @DoNotStrip public fun enableUIConsistency(): Boolean @DoNotStrip public fun inspectorEnableCxxInspectorPackagerConnection(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index d24467eb205..a34874f06bd 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -87,6 +87,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableSynchronousStateUpdates() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableSynchronousStateUpdates"); + return method(javaProvider_); + } + bool enableUIConsistency() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableUIConsistency"); @@ -155,6 +161,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification( return ReactNativeFeatureFlags::enableSpannableBuildingUnification(); } +bool JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableSynchronousStateUpdates(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableUIConsistency( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableUIConsistency(); @@ -216,6 +227,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableSpannableBuildingUnification", JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification), + makeNativeMethod( + "enableSynchronousStateUpdates", + JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates), makeNativeMethod( "enableUIConsistency", JReactNativeFeatureFlagsCxxInterop::enableUIConsistency), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 27e41e73a4e..bc4e40765d1 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<6b33129341a4b68cdbbdbce9f57e4d63>> */ /** @@ -54,6 +54,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableSpannableBuildingUnification( facebook::jni::alias_ref); + static bool enableSynchronousStateUpdates( + facebook::jni::alias_ref); + static bool enableUIConsistency( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 2a4c352c5a4..b960e7889c2 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<56f79a4cb62a993f9c3a8ea01eed2ab6>> */ /** @@ -53,6 +53,10 @@ bool ReactNativeFeatureFlags::enableSpannableBuildingUnification() { return getAccessor().enableSpannableBuildingUnification(); } +bool ReactNativeFeatureFlags::enableSynchronousStateUpdates() { + return getAccessor().enableSynchronousStateUpdates(); +} + bool ReactNativeFeatureFlags::enableUIConsistency() { return getAccessor().enableUIConsistency(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 0354f83b547..15c05e75435 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -77,6 +77,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableSpannableBuildingUnification(); + /** + * Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread). + */ + RN_EXPORT static bool enableSynchronousStateUpdates(); + /** * Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution). */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index f7a4feb4dbb..3310842f48f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2ff39fd4c8330ddca994fc40cdeaaf4c>> + * @generated SignedSource<<5b42b33319369b7936662a2608794ba5>> */ /** @@ -173,6 +173,24 @@ bool ReactNativeFeatureFlagsAccessor::enableSpannableBuildingUnification() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { + auto flagValue = enableSynchronousStateUpdates_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(8, "enableSynchronousStateUpdates"); + + flagValue = currentProvider_->enableSynchronousStateUpdates(); + enableSynchronousStateUpdates_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { auto flagValue = enableUIConsistency_.load(); @@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(8, "enableUIConsistency"); + markFlagAsAccessed(9, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableCxxInspectorPackagerConnect // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "inspectorEnableCxxInspectorPackagerConnection"); + markFlagAsAccessed(10, "inspectorEnableCxxInspectorPackagerConnection"); flagValue = currentProvider_->inspectorEnableCxxInspectorPackagerConnection(); inspectorEnableCxxInspectorPackagerConnection_ = flagValue; @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableModernCDPRegistry() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "inspectorEnableModernCDPRegistry"); + markFlagAsAccessed(11, "inspectorEnableModernCDPRegistry"); flagValue = currentProvider_->inspectorEnableModernCDPRegistry(); inspectorEnableModernCDPRegistry_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "useModernRuntimeScheduler"); + markFlagAsAccessed(12, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index dc3b1f0b99c..9591c3fc030 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -39,6 +39,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableMicrotasks(); bool enableMountHooksAndroid(); bool enableSpannableBuildingUnification(); + bool enableSynchronousStateUpdates(); bool enableUIConsistency(); bool inspectorEnableCxxInspectorPackagerConnection(); bool inspectorEnableModernCDPRegistry(); @@ -53,7 +54,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 12> accessedFeatureFlags_; + std::array, 13> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> batchRenderingUpdatesInEventLoop_; @@ -63,6 +64,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableMicrotasks_; std::atomic> enableMountHooksAndroid_; std::atomic> enableSpannableBuildingUnification_; + std::atomic> enableSynchronousStateUpdates_; std::atomic> enableUIConsistency_; std::atomic> inspectorEnableCxxInspectorPackagerConnection_; std::atomic> inspectorEnableModernCDPRegistry_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 0115a835c63..b9ff005fd37 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<1450d89abc68821fb348574016874719>> + * @generated SignedSource<<9fd009411ce19224a3102d2713b0b042>> */ /** @@ -59,6 +59,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableSynchronousStateUpdates() override { + return false; + } + bool enableUIConsistency() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index cbf80cf641e..21c6cfb65ef 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<7384eeb8615a45b79cdcceb731d98e9d>> */ /** @@ -33,6 +33,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableMicrotasks() = 0; virtual bool enableMountHooksAndroid() = 0; virtual bool enableSpannableBuildingUnification() = 0; + virtual bool enableSynchronousStateUpdates() = 0; virtual bool enableUIConsistency() = 0; virtual bool inspectorEnableCxxInspectorPackagerConnection() = 0; virtual bool inspectorEnableModernCDPRegistry() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 8a957343c12..195a87f9bce 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7e09a7ad1d178850bdcf73da3eb5623b>> + * @generated SignedSource<<08ed8c4c27411ba5a04acb314eb36b63>> */ /** @@ -77,6 +77,11 @@ bool NativeReactNativeFeatureFlags::enableSpannableBuildingUnification( return ReactNativeFeatureFlags::enableSpannableBuildingUnification(); } +bool NativeReactNativeFeatureFlags::enableSynchronousStateUpdates( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableSynchronousStateUpdates(); +} + bool NativeReactNativeFeatureFlags::enableUIConsistency( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableUIConsistency(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index bdc52a818d5..55a2530553f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -51,6 +51,8 @@ class NativeReactNativeFeatureFlags bool enableSpannableBuildingUnification(jsi::Runtime& runtime); + bool enableSynchronousStateUpdates(jsi::Runtime& runtime); + bool enableUIConsistency(jsi::Runtime& runtime); bool inspectorEnableCxxInspectorPackagerConnection(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt index 8ffaf81af56..4a2f93bfb38 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/core/CMakeLists.txt @@ -25,6 +25,7 @@ target_link_libraries(react_render_core logger react_config react_debug + react_featureflags react_render_debug react_render_graphics react_render_mapbuffer diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp index 693e6820811..2c8175dc0aa 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.cpp @@ -7,6 +7,7 @@ #include "EventDispatcher.h" #include +#include #include #include "EventLogger.h" @@ -19,11 +20,13 @@ EventDispatcher::EventDispatcher( const EventQueueProcessor& eventProcessor, const EventBeat::Factory& asynchronousEventBeatFactory, const EventBeat::SharedOwnerBox& ownerBox, - RuntimeScheduler& runtimeScheduler) + RuntimeScheduler& runtimeScheduler, + StatePipe statePipe) : eventQueue_(EventQueue( eventProcessor, asynchronousEventBeatFactory(ownerBox), - runtimeScheduler)) {} + runtimeScheduler)), + statePipe_(std::move(statePipe)) {} void EventDispatcher::dispatchEvent(RawEvent&& rawEvent) const { // Allows the event listener to interrupt default event dispatch @@ -43,7 +46,11 @@ void EventDispatcher::experimental_flushSync() const { } void EventDispatcher::dispatchStateUpdate(StateUpdate&& stateUpdate) const { - eventQueue_.enqueueStateUpdate(std::move(stateUpdate)); + if (ReactNativeFeatureFlags::enableSynchronousStateUpdates()) { + statePipe_(stateUpdate); + } else { + eventQueue_.enqueueStateUpdate(std::move(stateUpdate)); + } } void EventDispatcher::dispatchUniqueEvent(RawEvent&& rawEvent) const { diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h index b974e5e6ea0..d0331166cef 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace facebook::react { @@ -31,7 +32,8 @@ class EventDispatcher { const EventQueueProcessor& eventProcessor, const EventBeat::Factory& asynchronousEventBeatFactory, const EventBeat::SharedOwnerBox& ownerBox, - RuntimeScheduler& runtimeScheduler); + RuntimeScheduler& runtimeScheduler, + StatePipe statePipe); /* * Dispatches a raw event with given priority using event-delivery pipe. @@ -69,6 +71,7 @@ class EventDispatcher { private: EventQueue eventQueue_; + const StatePipe statePipe_; mutable EventListenerContainer eventListeners_; }; diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 9f5dc0e75f4..7a34d992dcd 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -91,7 +91,8 @@ Scheduler::Scheduler( EventQueueProcessor(eventPipe, eventPipeConclusion, statePipe), schedulerToolbox.asynchronousEventBeatFactory, eventOwnerBox, - *runtimeScheduler); + *runtimeScheduler, + statePipe); // Casting to `std::shared_ptr`. auto eventDispatcher = diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 91e3dd69c8f..396d3290700 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -67,6 +67,11 @@ const definitions: FeatureFlagDefinitions = { description: 'Uses new, deduplicated logic for constructing Android Spannables from text fragments', }, + enableSynchronousStateUpdates: { + defaultValue: false, + description: + 'Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread).', + }, enableUIConsistency: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index dffe28a86f1..2e642c0017e 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<366b36d877532c93aa6e5a97b85edd06>> * @flow strict-local */ @@ -48,6 +48,7 @@ export type ReactNativeFeatureFlags = { enableMicrotasks: Getter, enableMountHooksAndroid: Getter, enableSpannableBuildingUnification: Getter, + enableSynchronousStateUpdates: Getter, enableUIConsistency: Getter, inspectorEnableCxxInspectorPackagerConnection: Getter, inspectorEnableModernCDPRegistry: Getter, @@ -126,6 +127,10 @@ export const enableMountHooksAndroid: Getter = createNativeFlagGetter(' * Uses new, deduplicated logic for constructing Android Spannables from text fragments */ export const enableSpannableBuildingUnification: Getter = createNativeFlagGetter('enableSpannableBuildingUnification', false); +/** + * Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread). + */ +export const enableSynchronousStateUpdates: Getter = createNativeFlagGetter('enableSynchronousStateUpdates', false); /** * Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution). */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index ac17e38ee02..227f49d7cfa 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2f4c06a0e456d55a4bbd6b8c48c7f22d>> + * @generated SignedSource<<0d744f7a8519800a42cb0c3957862775>> * @flow strict-local */ @@ -31,6 +31,7 @@ export interface Spec extends TurboModule { +enableMicrotasks?: () => boolean; +enableMountHooksAndroid?: () => boolean; +enableSpannableBuildingUnification?: () => boolean; + +enableSynchronousStateUpdates?: () => boolean; +enableUIConsistency?: () => boolean; +inspectorEnableCxxInspectorPackagerConnection?: () => boolean; +inspectorEnableModernCDPRegistry?: () => boolean;