From 05e720adfbdbc29367b973fbffab4ae09305e0a7 Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Wed, 12 Mar 2025 11:55:15 -0700 Subject: [PATCH] Add feature flag for universal calls to start|finishOperationBatch (#49908) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49908 There are various batching mechanisms across react-native platforms. The NativeAnimated startOperationBatch and finishOperationBatch methods are a useful way to signal that complete animation graphs are established for atomic flushes to the UI thread. Setting up this feature flag for use across non-Android React Native platforms. ## Changelog [Internal] Reviewed By: javache Differential Revision: D70827938 fbshipit-source-id: 4c4a74e9a11f75090152637d6195092f5af866a0 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 ++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 ++- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 ++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 100 +++++++++++------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- ...eactNativeFeatureFlagsOverridesOSSCanary.h | 4 +- ...tiveFeatureFlagsOverridesOSSExperimental.h | 4 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 10 ++ .../private/animated/NativeAnimatedHelper.js | 19 +++- .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 23 files changed, 199 insertions(+), 64 deletions(-) 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 81c00d0ef1e..f7c5264dda7 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<> + * @generated SignedSource<> */ /** @@ -34,6 +34,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun commonTestFlag(): Boolean = accessor.commonTestFlag() + /** + * Enables start- and finishOperationBatch on any platform. + */ + @JvmStatic + public fun animatedShouldSignalBatch(): Boolean = accessor.animatedShouldSignalBatch() + /** * Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread */ 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 9b17c105a18..a7f7bee1fe6 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<> + * @generated SignedSource<<9813fd15c7f54d69d3de6084f733c3a6>> */ /** @@ -21,6 +21,7 @@ package com.facebook.react.internal.featureflags internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor { private var commonTestFlagCache: Boolean? = null + private var animatedShouldSignalBatchCache: Boolean? = null private var disableMountItemReorderingAndroidCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -71,6 +72,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun animatedShouldSignalBatch(): Boolean { + var cached = animatedShouldSignalBatchCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.animatedShouldSignalBatch() + animatedShouldSignalBatchCache = cached + } + return cached + } + override fun disableMountItemReorderingAndroid(): Boolean { var cached = disableMountItemReorderingAndroidCache 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 f6477a227f5..0f0bdfe2b6b 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<<1e7421f38e1dd6629e42492b2c7a4ee1>> + * @generated SignedSource<<06c5ef75b624d953e7a8d9297feaf816>> */ /** @@ -30,6 +30,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun commonTestFlag(): Boolean + @DoNotStrip @JvmStatic public external fun animatedShouldSignalBatch(): Boolean + @DoNotStrip @JvmStatic public external fun disableMountItemReorderingAndroid(): Boolean @DoNotStrip @JvmStatic public external fun enableAccumulatedUpdatesInRawPropsAndroid(): 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 ca492be3ebc..d7f4afb4a83 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<<0f22538afea52085aaf605e8608eaff8>> + * @generated SignedSource<> */ /** @@ -25,6 +25,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun commonTestFlag(): Boolean = false + override fun animatedShouldSignalBatch(): Boolean = false + override fun disableMountItemReorderingAndroid(): Boolean = false override fun enableAccumulatedUpdatesInRawPropsAndroid(): 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 bfc297d89fa..a958b7c90cb 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<<1693dced312625bbfedce5f2dfa9816c>> + * @generated SignedSource<<0fb76e329360157ea9772a0d8bebc873>> */ /** @@ -25,6 +25,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private val accessedFeatureFlags = mutableSetOf() private var commonTestFlagCache: Boolean? = null + private var animatedShouldSignalBatchCache: Boolean? = null private var disableMountItemReorderingAndroidCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -76,6 +77,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun animatedShouldSignalBatch(): Boolean { + var cached = animatedShouldSignalBatchCache + if (cached == null) { + cached = currentProvider.animatedShouldSignalBatch() + accessedFeatureFlags.add("animatedShouldSignalBatch") + animatedShouldSignalBatchCache = cached + } + return cached + } + override fun disableMountItemReorderingAndroid(): Boolean { var cached = disableMountItemReorderingAndroidCache 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 1be5ddf2db7..9d194b9ce6a 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<<2f2bbf0a92c3af728de6ea38dc374b94>> + * @generated SignedSource<<0c16f7af743a6c4d7aaabf010c1c7327>> */ /** @@ -25,6 +25,8 @@ import com.facebook.proguard.annotations.DoNotStrip public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun commonTestFlag(): Boolean + @DoNotStrip public fun animatedShouldSignalBatch(): Boolean + @DoNotStrip public fun disableMountItemReorderingAndroid(): Boolean @DoNotStrip public fun enableAccumulatedUpdatesInRawPropsAndroid(): 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 1131bc8acbb..c720ea8b1bc 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<<14c3186a1395a23befb73fc9da972de7>> + * @generated SignedSource<> */ /** @@ -45,6 +45,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool animatedShouldSignalBatch() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("animatedShouldSignalBatch"); + return method(javaProvider_); + } + bool disableMountItemReorderingAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("disableMountItemReorderingAndroid"); @@ -294,6 +300,11 @@ bool JReactNativeFeatureFlagsCxxInterop::commonTestFlag( return ReactNativeFeatureFlags::commonTestFlag(); } +bool JReactNativeFeatureFlagsCxxInterop::animatedShouldSignalBatch( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::animatedShouldSignalBatch(); +} + bool JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::disableMountItemReorderingAndroid(); @@ -528,6 +539,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "commonTestFlag", JReactNativeFeatureFlagsCxxInterop::commonTestFlag), + makeNativeMethod( + "animatedShouldSignalBatch", + JReactNativeFeatureFlagsCxxInterop::animatedShouldSignalBatch), makeNativeMethod( "disableMountItemReorderingAndroid", JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid), 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 b95d995bc49..08f10d5dad3 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<<5edcb3baccc7a27525ba6ca43b2aab8a>> + * @generated SignedSource<> */ /** @@ -33,6 +33,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool commonTestFlag( facebook::jni::alias_ref); + static bool animatedShouldSignalBatch( + facebook::jni::alias_ref); + static bool disableMountItemReorderingAndroid( 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 23639ca4d33..ece27d06f80 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<<98c62bb40ef9c03af6e3e2d758cef7ec>> + * @generated SignedSource<<4d47f61435ba3a74e84752a02def81c2>> */ /** @@ -30,6 +30,10 @@ bool ReactNativeFeatureFlags::commonTestFlag() { return getAccessor().commonTestFlag(); } +bool ReactNativeFeatureFlags::animatedShouldSignalBatch() { + return getAccessor().animatedShouldSignalBatch(); +} + bool ReactNativeFeatureFlags::disableMountItemReorderingAndroid() { return getAccessor().disableMountItemReorderingAndroid(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 72ddff55792..e6536c2895e 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<<452dc78526d49a23c5052bd1ecd130d2>> + * @generated SignedSource<<29cdbefbe02064df4fb65388e64f95a4>> */ /** @@ -44,6 +44,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool commonTestFlag(); + /** + * Enables start- and finishOperationBatch on any platform. + */ + RN_EXPORT static bool animatedShouldSignalBatch(); + /** * Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index e4b33b35fdc..91bf73707b4 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<> + * @generated SignedSource<<353677101629176192534f1f234e2de4>> */ /** @@ -47,6 +47,24 @@ bool ReactNativeFeatureFlagsAccessor::commonTestFlag() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::animatedShouldSignalBatch() { + auto flagValue = animatedShouldSignalBatch_.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(1, "animatedShouldSignalBatch"); + + flagValue = currentProvider_->animatedShouldSignalBatch(); + animatedShouldSignalBatch_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() { auto flagValue = disableMountItemReorderingAndroid_.load(); @@ -56,7 +74,7 @@ bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(1, "disableMountItemReorderingAndroid"); + markFlagAsAccessed(2, "disableMountItemReorderingAndroid"); flagValue = currentProvider_->disableMountItemReorderingAndroid(); disableMountItemReorderingAndroid_ = flagValue; @@ -74,7 +92,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAccumulatedUpdatesInRawPropsAndroid( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(2, "enableAccumulatedUpdatesInRawPropsAndroid"); + markFlagAsAccessed(3, "enableAccumulatedUpdatesInRawPropsAndroid"); flagValue = currentProvider_->enableAccumulatedUpdatesInRawPropsAndroid(); enableAccumulatedUpdatesInRawPropsAndroid_ = flagValue; @@ -92,7 +110,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(3, "enableBridgelessArchitecture"); + markFlagAsAccessed(4, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -110,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(4, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(5, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -128,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(5, "enableEagerRootViewAttachment"); + markFlagAsAccessed(6, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -146,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(6, "enableFabricLogs"); + markFlagAsAccessed(7, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -164,7 +182,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(7, "enableFabricRenderer"); + markFlagAsAccessed(8, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(8, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(9, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(10, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableJSRuntimeGCOnMemoryPressureOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "enableJSRuntimeGCOnMemoryPressureOnIOS"); + markFlagAsAccessed(11, "enableJSRuntimeGCOnMemoryPressureOnIOS"); flagValue = currentProvider_->enableJSRuntimeGCOnMemoryPressureOnIOS(); enableJSRuntimeGCOnMemoryPressureOnIOS_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(12, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(13, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableLongTaskAPI"); + markFlagAsAccessed(14, "enableLongTaskAPI"); flagValue = currentProvider_->enableLongTaskAPI(); enableLongTaskAPI_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableNativeCSSParsing"); + markFlagAsAccessed(15, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableNewBackgroundAndBorderDrawables"); + markFlagAsAccessed(16, "enableNewBackgroundAndBorderDrawables"); flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); enableNewBackgroundAndBorderDrawables_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(17, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableReportEventPaintTime"); + markFlagAsAccessed(18, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableSynchronousStateUpdates"); + markFlagAsAccessed(19, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -380,7 +398,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(19, "enableUIConsistency"); + markFlagAsAccessed(20, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableViewCulling"); + markFlagAsAccessed(21, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableViewRecycling"); + markFlagAsAccessed(22, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableViewRecyclingForText"); + markFlagAsAccessed(23, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableViewRecyclingForView"); + markFlagAsAccessed(24, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorEmittingUpdatesWithWrongP // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "fixDifferentiatorEmittingUpdatesWithWrongParentTag"); + markFlagAsAccessed(25, "fixDifferentiatorEmittingUpdatesWithWrongParentTag"); flagValue = currentProvider_->fixDifferentiatorEmittingUpdatesWithWrongParentTag(); fixDifferentiatorEmittingUpdatesWithWrongParentTag_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(26, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(27, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "fuseboxEnabledRelease"); + markFlagAsAccessed(28, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(29, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "lazyAnimationCallbacks"); + markFlagAsAccessed(30, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::removeTurboModuleManagerDelegateMutex() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "removeTurboModuleManagerDelegateMutex"); + markFlagAsAccessed(31, "removeTurboModuleManagerDelegateMutex"); flagValue = currentProvider_->removeTurboModuleManagerDelegateMutex(); removeTurboModuleManagerDelegateMutex_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::throwExceptionInsteadOfDeadlockOnTurboModu // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS"); + markFlagAsAccessed(32, "throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS"); flagValue = currentProvider_->throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS(); throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(33, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(34, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useEditTextStockAndroidFocusBehavior() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "useEditTextStockAndroidFocusBehavior"); + markFlagAsAccessed(35, "useEditTextStockAndroidFocusBehavior"); flagValue = currentProvider_->useEditTextStockAndroidFocusBehavior(); useEditTextStockAndroidFocusBehavior_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "useFabricInterop"); + markFlagAsAccessed(36, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(38, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useRawPropsJsiValue"); + markFlagAsAccessed(39, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useTurboModuleInterop"); + markFlagAsAccessed(40, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useTurboModules"); + markFlagAsAccessed(41, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 25ec36b18d1..1d0e986c4b4 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<<00f623d5f3920895eb2c1b530dce6a7d>> */ /** @@ -33,6 +33,7 @@ class ReactNativeFeatureFlagsAccessor { ReactNativeFeatureFlagsAccessor(); bool commonTestFlag(); + bool animatedShouldSignalBatch(); bool disableMountItemReorderingAndroid(); bool enableAccumulatedUpdatesInRawPropsAndroid(); bool enableBridgelessArchitecture(); @@ -84,9 +85,10 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 41> accessedFeatureFlags_; + std::array, 42> accessedFeatureFlags_; std::atomic> commonTestFlag_; + std::atomic> animatedShouldSignalBatch_; std::atomic> disableMountItemReorderingAndroid_; std::atomic> enableAccumulatedUpdatesInRawPropsAndroid_; std::atomic> enableBridgelessArchitecture_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 844da14bea7..4cb62cd067f 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<<132471a831b3041cc6cae8915de33982>> + * @generated SignedSource<<140e6580100dab5806194e780610f122>> */ /** @@ -31,6 +31,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool animatedShouldSignalBatch() override { + return false; + } + bool disableMountItemReorderingAndroid() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index a628c82a4ce..bfd2a802d94 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.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<> */ /** @@ -54,6 +54,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::commonTestFlag(); } + bool animatedShouldSignalBatch() override { + auto value = values_["animatedShouldSignalBatch"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::animatedShouldSignalBatch(); + } + bool disableMountItemReorderingAndroid() override { auto value = values_["disableMountItemReorderingAndroid"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSCanary.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSCanary.h index 9237e69e41d..3dbcd2356cc 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSCanary.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSCanary.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<<7bd8ef01ed492807df85a3d4a7f6a55c>> + * @generated SignedSource<> */ /** @@ -33,6 +33,8 @@ class ReactNativeFeatureFlagsOverridesOSSCanary : public ReactNativeFeatureFlags + + bool enableBridgelessArchitecture() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h index aca1e3fe4b2..0d63daa28ba 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.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<<25f75edcfc62e5ce24c2d1bd10244e40>> + * @generated SignedSource<> */ /** @@ -105,6 +105,8 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur + + diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 263c9d01f48..e9ddbd4c1c9 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<<0845c9b1618ac1e18ce4aeb5d03a70f5>> */ /** @@ -26,6 +26,7 @@ class ReactNativeFeatureFlagsProvider { virtual ~ReactNativeFeatureFlagsProvider() = default; virtual bool commonTestFlag() = 0; + virtual bool animatedShouldSignalBatch() = 0; virtual bool disableMountItemReorderingAndroid() = 0; virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0; virtual bool enableBridgelessArchitecture() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index f4c6259cb76..4f831b521d9 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<<2e88c46eee92923e11e44bc63a297f91>> + * @generated SignedSource<<7493403280d2ac7ec348eb3d78d915c2>> */ /** @@ -49,6 +49,11 @@ bool NativeReactNativeFeatureFlags::commonTestFlagWithoutNativeImplementation( return false; } +bool NativeReactNativeFeatureFlags::animatedShouldSignalBatch( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::animatedShouldSignalBatch(); +} + bool NativeReactNativeFeatureFlags::disableMountItemReorderingAndroid( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::disableMountItemReorderingAndroid(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index daf6d3cfd14..831c819ed98 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<<976dc1d9e9df5d843d796ba71fab2e27>> + * @generated SignedSource<<36b55f5cfd86d9aaad26c760dec7c875>> */ /** @@ -39,6 +39,8 @@ class NativeReactNativeFeatureFlags bool commonTestFlagWithoutNativeImplementation(jsi::Runtime& runtime); + bool animatedShouldSignalBatch(jsi::Runtime& runtime); + bool disableMountItemReorderingAndroid(jsi::Runtime& runtime); bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 750ef7673da..1b3ab17044a 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -60,6 +60,16 @@ const testDefinitions: FeatureFlagDefinitions = { const definitions: FeatureFlagDefinitions = { common: { ...testDefinitions.common, + animatedShouldSignalBatch: { + defaultValue: false, + metadata: { + dateAdded: '2025-03-07', + description: 'Enables start- and finishOperationBatch on any platform.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, disableMountItemReorderingAndroid: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/animated/NativeAnimatedHelper.js b/packages/react-native/src/private/animated/NativeAnimatedHelper.js index 9074d7c22e2..a440e32c207 100644 --- a/packages/react-native/src/private/animated/NativeAnimatedHelper.js +++ b/packages/react-native/src/private/animated/NativeAnimatedHelper.js @@ -57,6 +57,8 @@ const eventListenerAnimationFinishedCallbacks: { let globalEventEmitterGetValueListener: ?EventSubscription = null; let globalEventEmitterAnimationFinishedListener: ?EventSubscription = null; +const shouldSignalBatch = ReactNativeFeatureFlags.animatedShouldSignalBatch(); + function createNativeOperations(): $NonMaybeType { const methodNames = [ 'createAnimatedNode', // 1 @@ -106,6 +108,11 @@ function createNativeOperations(): $NonMaybeType { if (queueOperations || queue.length !== 0) { // $FlowExpectedError[incompatible-call] - Dynamism. queue.push(() => method(...args)); + } else if (shouldSignalBatch) { + // $FlowExpectedError[incompatible-call] - Dynamism. + queue.push(() => method(...args)); + clearImmediate(flushQueueImmediate); + flushQueueImmediate = setImmediate(API.flushQueue); } else { // $FlowExpectedError[incompatible-call] - Dynamism. method(...args); @@ -138,6 +145,10 @@ const API = { }) as $NonMaybeType['getValue'], setWaitingForIdentifier(id: string): void { + if (shouldSignalBatch) { + return; + } + waitingForQueuedOperations.add(id); queueOperations = true; if ( @@ -149,6 +160,10 @@ const API = { }, unsetWaitingForIdentifier(id: string): void { + if (shouldSignalBatch) { + return; + } + waitingForQueuedOperations.delete(id); if (waitingForQueuedOperations.size === 0) { @@ -202,7 +217,7 @@ const API = { return; } - if (Platform.OS === 'android') { + if (Platform.OS === 'android' || shouldSignalBatch) { NativeAnimatedModule?.startOperationBatch?.(); } @@ -211,7 +226,7 @@ const API = { } queue.length = 0; - if (Platform.OS === 'android') { + if (Platform.OS === 'android' || shouldSignalBatch) { NativeAnimatedModule?.finishOperationBatch?.(); } }) as () => void, diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 071aece80eb..9c9bd26ff2a 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<<4f1befe0cec24eeb531d7ecca6bc451b>> + * @generated SignedSource<<99bbe1c87a7620b6381705db9795fd77>> * @flow strict */ @@ -49,6 +49,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ ...ReactNativeFeatureFlagsJsOnly, commonTestFlag: Getter, commonTestFlagWithoutNativeImplementation: Getter, + animatedShouldSignalBatch: Getter, disableMountItemReorderingAndroid: Getter, enableAccumulatedUpdatesInRawPropsAndroid: Getter, enableBridgelessArchitecture: Getter, @@ -169,6 +170,10 @@ export const commonTestFlag: Getter = createNativeFlagGetter('commonTes * Common flag for testing (without native implementation). Do NOT modify. */ export const commonTestFlagWithoutNativeImplementation: Getter = createNativeFlagGetter('commonTestFlagWithoutNativeImplementation', false); +/** + * Enables start- and finishOperationBatch on any platform. + */ +export const animatedShouldSignalBatch: Getter = createNativeFlagGetter('animatedShouldSignalBatch', false); /** * Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 55a635d3de4..52291574329 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<> + * @generated SignedSource<<22d8e7623a2eee5182c786f2ec914401>> * @flow strict */ @@ -25,6 +25,7 @@ import * as TurboModuleRegistry from '../../../../Libraries/TurboModule/TurboMod export interface Spec extends TurboModule { +commonTestFlag?: () => boolean; +commonTestFlagWithoutNativeImplementation?: () => boolean; + +animatedShouldSignalBatch?: () => boolean; +disableMountItemReorderingAndroid?: () => boolean; +enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean; +enableBridgelessArchitecture?: () => boolean;