Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
* @fantom_flags useSharedAnimatedBackend:true updateRuntimeShadowNodeReferencesOnCommitThread:* optimizedAnimatedPropUpdates:*
* @fantom_flags useSharedAnimatedBackend:true updateRuntimeShadowNodeReferencesOnCommitThread:* optimizedAnimatedPropUpdates:* enableCxxAnimatedDirectPathInBackend:*
* @flow strict-local
* @format
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* 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.
*
* @fantom_flags useSharedAnimatedBackend:true enableCxxAnimatedDirectPathInBackend:* updateRuntimeShadowNodeReferencesOnCommitThread:*
* @flow strict-local
* @format
*/

import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import type {HostInstance} from 'react-native';

import * as Fantom from '@react-native/fantom';
import * as React from 'react';
import {createRef, useState} from 'react';
import {Animated, View, useAnimatedValue} from 'react-native';

let _opacity;
let _setAnimatedWidth;

// `still` has the same position and structure as `animated` but never
// animates, so it is cloned only for the reasons unrelated to animations.
function MyApp({
animatedRef,
stillRef,
}: {
animatedRef: React.RefSetter<HostInstance>,
stillRef?: React.RefSetter<HostInstance>,
}) {
const opacity = useAnimatedValue(1);
const stillOpacity = useAnimatedValue(1);
const [animatedWidth, setAnimatedWidth] = useState(100);
_opacity = opacity;
_setAnimatedWidth = setAnimatedWidth;
return (
<View collapsable={false}>
<Animated.View
ref={animatedRef}
style={{
width: animatedWidth,
height: 100,
opacity,
}}
/>
<Animated.View
ref={stillRef}
style={{width: 100, height: 100, opacity: stillOpacity}}
/>
<View collapsable={false} style={{width: 100, height: 100}} />
</View>
);
}

function startOpacityAnimation(duration: number) {
Fantom.runTask(() => {
Animated.timing(_opacity, {
toValue: 0,
duration,
useNativeDriver: true,
}).start();
});
}

test('a React commit of the animated view keeps its direct animated value mounted', () => {
const animatedRef = createRef<HostInstance>();
const root = Fantom.createRoot();
Fantom.runTask(() => {
root.render(<MyApp animatedRef={animatedRef} />);
});

startOpacityAnimation(1000);
Fantom.unstable_produceFramesForDuration(500);

Fantom.runTask(() => {
_setAnimatedWidth(150);
});

expect(root.getRenderedOutput({props: ['opacity', 'width']}).toJSX()).toEqual(
<rn-view>
<rn-view key={0} opacity="0.5" width="150" />
<rn-view key={1} width="100" />
<rn-view key={2} width="100" />
</rn-view>,
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -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<<a89ede36c4631b7a7709899858a7f9c9>>
* @generated SignedSource<<e6a3e20f8cbff9506e51a3eef5652fe8>>
*/

/**
Expand Down Expand Up @@ -156,6 +156,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = accessor.enableCustomFocusSearchOnClippedElementsAndroid()

/**
* With the shared animation backend, C++ Animated keeps its non-layout values out of React commits and commits the final values once per surface when animations end, as it does without the backend.
*/
@JvmStatic
public fun enableCxxAnimatedDirectPathInBackend(): Boolean = accessor.enableCxxAnimatedDirectPathInBackend()

/**
* Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<cd3b4f6a7fb4e616d3f56ab8c9eb9658>>
* @generated SignedSource<<b6771291afa59d44d3f693b803231999>>
*/

/**
Expand Down Expand Up @@ -41,6 +41,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableBridgelessArchitectureCache: Boolean? = null
private var enableCppPropsIteratorSetterCache: Boolean? = null
private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null
private var enableCxxAnimatedDirectPathInBackendCache: Boolean? = null
private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null
private var enableDoubleMeasurementFixAndroidCache: Boolean? = null
private var enableEagerRootViewAttachmentCache: Boolean? = null
Expand Down Expand Up @@ -307,6 +308,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}

override fun enableCxxAnimatedDirectPathInBackend(): Boolean {
var cached = enableCxxAnimatedDirectPathInBackendCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableCxxAnimatedDirectPathInBackend()
enableCxxAnimatedDirectPathInBackendCache = cached
}
return cached
}

override fun enableDestroyShadowTreeRevisionAsync(): Boolean {
var cached = enableDestroyShadowTreeRevisionAsyncCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<6d86d4adbc261c9271b5bed72bd12dcf>>
* @generated SignedSource<<ec5f08343ce9c2e053445c15effef54b>>
*/

/**
Expand Down Expand Up @@ -70,6 +70,8 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean

@DoNotStrip @JvmStatic public external fun enableCxxAnimatedDirectPathInBackend(): Boolean

@DoNotStrip @JvmStatic public external fun enableDestroyShadowTreeRevisionAsync(): Boolean

@DoNotStrip @JvmStatic public external fun enableDoubleMeasurementFixAndroid(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<a1368426dd823245c54b4312ae7b14e6>>
* @generated SignedSource<<28e566c4e784a0bfc743ad46f316c50b>>
*/

/**
Expand Down Expand Up @@ -65,6 +65,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = true

override fun enableCxxAnimatedDirectPathInBackend(): Boolean = false

override fun enableDestroyShadowTreeRevisionAsync(): Boolean = false

override fun enableDoubleMeasurementFixAndroid(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<c305274be2fc6720b6c0eb75e78bd6b0>>
* @generated SignedSource<<d9391a3bef70fdab935a98b4f8affdb3>>
*/

/**
Expand Down Expand Up @@ -45,6 +45,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableBridgelessArchitectureCache: Boolean? = null
private var enableCppPropsIteratorSetterCache: Boolean? = null
private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null
private var enableCxxAnimatedDirectPathInBackendCache: Boolean? = null
private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null
private var enableDoubleMeasurementFixAndroidCache: Boolean? = null
private var enableEagerRootViewAttachmentCache: Boolean? = null
Expand Down Expand Up @@ -332,6 +333,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}

override fun enableCxxAnimatedDirectPathInBackend(): Boolean {
var cached = enableCxxAnimatedDirectPathInBackendCache
if (cached == null) {
cached = currentProvider.enableCxxAnimatedDirectPathInBackend()
accessedFeatureFlags.add("enableCxxAnimatedDirectPathInBackend")
enableCxxAnimatedDirectPathInBackendCache = cached
}
return cached
}

override fun enableDestroyShadowTreeRevisionAsync(): Boolean {
var cached = enableDestroyShadowTreeRevisionAsyncCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<da45e41e9a58711ee3b68a38965938fb>>
* @generated SignedSource<<e4b8bf98b7a7a845fd80820c668d969d>>
*/

/**
Expand Down Expand Up @@ -65,6 +65,8 @@ public interface ReactNativeFeatureFlagsProvider {

@DoNotStrip public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean

@DoNotStrip public fun enableCxxAnimatedDirectPathInBackend(): Boolean

@DoNotStrip public fun enableDestroyShadowTreeRevisionAsync(): Boolean

@DoNotStrip public fun enableDoubleMeasurementFixAndroid(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<944781e7a547e601f0637869a3a3ec5e>>
* @generated SignedSource<<30b22c622145cb7664db5550e6d82440>>
*/

/**
Expand Down Expand Up @@ -165,6 +165,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}

bool enableCxxAnimatedDirectPathInBackend() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableCxxAnimatedDirectPathInBackend");
return method(javaProvider_);
}

bool enableDestroyShadowTreeRevisionAsync() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableDestroyShadowTreeRevisionAsync");
Expand Down Expand Up @@ -730,6 +736,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableCustomFocusSearchOnClippedElement
return ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid();
}

bool JReactNativeFeatureFlagsCxxInterop::enableCxxAnimatedDirectPathInBackend(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableCxxAnimatedDirectPathInBackend();
}

bool JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync();
Expand Down Expand Up @@ -1204,6 +1215,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableCustomFocusSearchOnClippedElementsAndroid",
JReactNativeFeatureFlagsCxxInterop::enableCustomFocusSearchOnClippedElementsAndroid),
makeNativeMethod(
"enableCxxAnimatedDirectPathInBackend",
JReactNativeFeatureFlagsCxxInterop::enableCxxAnimatedDirectPathInBackend),
makeNativeMethod(
"enableDestroyShadowTreeRevisionAsync",
JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<ad9275a6afb74520bec7d446faafd1bc>>
* @generated SignedSource<<80d466e62bb754e4ed9b6f46f9b9b546>>
*/

/**
Expand Down Expand Up @@ -93,6 +93,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableCustomFocusSearchOnClippedElementsAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableCxxAnimatedDirectPathInBackend(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableDestroyShadowTreeRevisionAsync(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<56e127471f63e47798ec619e6fa56738>>
* @generated SignedSource<<b4695d8ba4fa3e58d3639c339eb53f92>>
*/

/**
Expand Down Expand Up @@ -110,6 +110,10 @@ bool ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid()
return getAccessor().enableCustomFocusSearchOnClippedElementsAndroid();
}

bool ReactNativeFeatureFlags::enableCxxAnimatedDirectPathInBackend() {
return getAccessor().enableCxxAnimatedDirectPathInBackend();
}

bool ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync() {
return getAccessor().enableDestroyShadowTreeRevisionAsync();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<6887b671526bc8a3b0678e3e45b4e3b4>>
* @generated SignedSource<<becdbd22259309c5c0047f16ddb3e1ad>>
*/

/**
Expand Down Expand Up @@ -146,6 +146,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableCustomFocusSearchOnClippedElementsAndroid();

/**
* With the shared animation backend, C++ Animated keeps its non-layout values out of React commits and commits the final values once per surface when animations end, as it does without the backend.
*/
RN_EXPORT static bool enableCxxAnimatedDirectPathInBackend();

/**
* Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work.
*/
Expand Down
Loading
Loading