mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
delete state alignment mechanism (#46658)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46658 changelog: [internal] We are shipping a better solution: Runtime Shadow Node Reference Syncing which is being rolled out. Reviewed By: lenaic, rubennorte Differential Revision: D63456344 fbshipit-source-id: e70b7dd4be7bf0670366e5200a910195b929a14d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d1f47f7ad5
commit
4e38493d71
+1
-7
@@ -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<<70e68165b567734a2609b77656b2c183>>
|
||||
* @generated SignedSource<<346573dc832f9de6a2e29a4cfde558c5>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -328,12 +328,6 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean = accessor.useRuntimeShadowNodeReferenceUpdateOnLayout()
|
||||
|
||||
/**
|
||||
* When enabled, it uses optimised state reconciliation algorithm.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun useStateAlignmentMechanism(): Boolean = accessor.useStateAlignmentMechanism()
|
||||
|
||||
/**
|
||||
* In Bridgeless mode, should legacy NativeModules use the TurboModule system?
|
||||
*/
|
||||
|
||||
+1
-11
@@ -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<<2f8da8585f1ac040bd26953263b08392>>
|
||||
* @generated SignedSource<<71fd4a070f4eb1429f38221e34135062>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -70,7 +70,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
|
||||
private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null
|
||||
private var useRuntimeShadowNodeReferenceUpdateOnLayoutCache: Boolean? = null
|
||||
private var useStateAlignmentMechanismCache: Boolean? = null
|
||||
private var useTurboModuleInteropCache: Boolean? = null
|
||||
private var useTurboModulesCache: Boolean? = null
|
||||
|
||||
@@ -524,15 +523,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useStateAlignmentMechanism(): Boolean {
|
||||
var cached = useStateAlignmentMechanismCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.useStateAlignmentMechanism()
|
||||
useStateAlignmentMechanismCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useTurboModuleInterop(): Boolean {
|
||||
var cached = useTurboModuleInteropCache
|
||||
if (cached == null) {
|
||||
|
||||
+1
-3
@@ -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<<4055cd2fa9070549fba3eda675e8d6f6>>
|
||||
* @generated SignedSource<<c35eeb0695671be65b1543ea0664468b>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -128,8 +128,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useStateAlignmentMechanism(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useTurboModuleInterop(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useTurboModules(): Boolean
|
||||
|
||||
+1
-3
@@ -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<<340a2b27d0a0281746e3f4b02be5e1bb>>
|
||||
* @generated SignedSource<<e1352f772c20f824f636f1f73a541444>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -123,8 +123,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean = false
|
||||
|
||||
override fun useStateAlignmentMechanism(): Boolean = false
|
||||
|
||||
override fun useTurboModuleInterop(): Boolean = false
|
||||
|
||||
override fun useTurboModules(): Boolean = false
|
||||
|
||||
+1
-12
@@ -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<<bb25a0d771f0f129ab3f224640053ac3>>
|
||||
* @generated SignedSource<<0d8f65a06ed20f44e5de58b764635602>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
|
||||
private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null
|
||||
private var useRuntimeShadowNodeReferenceUpdateOnLayoutCache: Boolean? = null
|
||||
private var useStateAlignmentMechanismCache: Boolean? = null
|
||||
private var useTurboModuleInteropCache: Boolean? = null
|
||||
private var useTurboModulesCache: Boolean? = null
|
||||
|
||||
@@ -578,16 +577,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useStateAlignmentMechanism(): Boolean {
|
||||
var cached = useStateAlignmentMechanismCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.useStateAlignmentMechanism()
|
||||
accessedFeatureFlags.add("useStateAlignmentMechanism")
|
||||
useStateAlignmentMechanismCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useTurboModuleInterop(): Boolean {
|
||||
var cached = useTurboModuleInteropCache
|
||||
if (cached == null) {
|
||||
|
||||
+1
-3
@@ -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<<509b61021c01bf47c54724bc9ba81c9c>>
|
||||
* @generated SignedSource<<6d70976da58a1120c79704210899b893>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -123,8 +123,6 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean
|
||||
|
||||
@DoNotStrip public fun useStateAlignmentMechanism(): Boolean
|
||||
|
||||
@DoNotStrip public fun useTurboModuleInterop(): Boolean
|
||||
|
||||
@DoNotStrip public fun useTurboModules(): Boolean
|
||||
|
||||
+1
-15
@@ -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<<8b39b99e91976d5bf63956e6501e180f>>
|
||||
* @generated SignedSource<<1f027e4e66bce1536fb259a547bb6a00>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -339,12 +339,6 @@ class ReactNativeFeatureFlagsProviderHolder
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool useStateAlignmentMechanism() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useStateAlignmentMechanism");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool useTurboModuleInterop() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useTurboModuleInterop");
|
||||
@@ -611,11 +605,6 @@ bool JReactNativeFeatureFlagsCxxInterop::useRuntimeShadowNodeReferenceUpdateOnLa
|
||||
return ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdateOnLayout();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::useStateAlignmentMechanism(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::useStateAlignmentMechanism();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::useTurboModuleInterop();
|
||||
@@ -793,9 +782,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"useRuntimeShadowNodeReferenceUpdateOnLayout",
|
||||
JReactNativeFeatureFlagsCxxInterop::useRuntimeShadowNodeReferenceUpdateOnLayout),
|
||||
makeNativeMethod(
|
||||
"useStateAlignmentMechanism",
|
||||
JReactNativeFeatureFlagsCxxInterop::useStateAlignmentMechanism),
|
||||
makeNativeMethod(
|
||||
"useTurboModuleInterop",
|
||||
JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop),
|
||||
|
||||
+1
-4
@@ -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<<896ca4611f7fa5de92279fbbf2095e3e>>
|
||||
* @generated SignedSource<<b99b1f3a29b875f4c456f77a276f4db3>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -180,9 +180,6 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool useRuntimeShadowNodeReferenceUpdateOnLayout(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool useStateAlignmentMechanism(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool useTurboModuleInterop(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
|
||||
@@ -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<<6e2b92ee7e4fb51de5286792004f649d>>
|
||||
* @generated SignedSource<<4efee607ab3716723debee8a451604ef>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -221,10 +221,6 @@ bool ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdateOnLayout() {
|
||||
return getAccessor().useRuntimeShadowNodeReferenceUpdateOnLayout();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::useStateAlignmentMechanism() {
|
||||
return getAccessor().useStateAlignmentMechanism();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::useTurboModuleInterop() {
|
||||
return getAccessor().useTurboModuleInterop();
|
||||
}
|
||||
|
||||
@@ -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<<646023269f07d6ae792b8aad5ef2d3c1>>
|
||||
* @generated SignedSource<<d2afeedcfb81ca31bd7f0c19fd406ae6>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -287,11 +287,6 @@ class ReactNativeFeatureFlags {
|
||||
*/
|
||||
RN_EXPORT static bool useRuntimeShadowNodeReferenceUpdateOnLayout();
|
||||
|
||||
/**
|
||||
* When enabled, it uses optimised state reconciliation algorithm.
|
||||
*/
|
||||
RN_EXPORT static bool useStateAlignmentMechanism();
|
||||
|
||||
/**
|
||||
* In Bridgeless mode, should legacy NativeModules use the TurboModule system?
|
||||
*/
|
||||
|
||||
+3
-21
@@ -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<<e35262c26447dec6e71e20f6a4fd8984>>
|
||||
* @generated SignedSource<<1bbb59bff4ce77b34ee94d0a2095d71f>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -929,24 +929,6 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() {
|
||||
auto flagValue = useStateAlignmentMechanism_.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(50, "useStateAlignmentMechanism");
|
||||
|
||||
flagValue = currentProvider_->useStateAlignmentMechanism();
|
||||
useStateAlignmentMechanism_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
|
||||
auto flagValue = useTurboModuleInterop_.load();
|
||||
|
||||
@@ -956,7 +938,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(51, "useTurboModuleInterop");
|
||||
markFlagAsAccessed(50, "useTurboModuleInterop");
|
||||
|
||||
flagValue = currentProvider_->useTurboModuleInterop();
|
||||
useTurboModuleInterop_ = flagValue;
|
||||
@@ -974,7 +956,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(52, "useTurboModules");
|
||||
markFlagAsAccessed(51, "useTurboModules");
|
||||
|
||||
flagValue = currentProvider_->useTurboModules();
|
||||
useTurboModules_ = flagValue;
|
||||
|
||||
+2
-4
@@ -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<<261b4e8fae45ad2780f0bd2b17c86d5c>>
|
||||
* @generated SignedSource<<5c64457d2fbe154d7e57b3e3e2e6a33a>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,6 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool useOptimizedEventBatchingOnAndroid();
|
||||
bool useRuntimeShadowNodeReferenceUpdate();
|
||||
bool useRuntimeShadowNodeReferenceUpdateOnLayout();
|
||||
bool useStateAlignmentMechanism();
|
||||
bool useTurboModuleInterop();
|
||||
bool useTurboModules();
|
||||
|
||||
@@ -94,7 +93,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
|
||||
bool wasOverridden_;
|
||||
|
||||
std::array<std::atomic<const char*>, 53> accessedFeatureFlags_;
|
||||
std::array<std::atomic<const char*>, 52> accessedFeatureFlags_;
|
||||
|
||||
std::atomic<std::optional<bool>> commonTestFlag_;
|
||||
std::atomic<std::optional<bool>> allowRecursiveCommitsWithSynchronousMountOnAndroid_;
|
||||
@@ -146,7 +145,6 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> useOptimizedEventBatchingOnAndroid_;
|
||||
std::atomic<std::optional<bool>> useRuntimeShadowNodeReferenceUpdate_;
|
||||
std::atomic<std::optional<bool>> useRuntimeShadowNodeReferenceUpdateOnLayout_;
|
||||
std::atomic<std::optional<bool>> useStateAlignmentMechanism_;
|
||||
std::atomic<std::optional<bool>> useTurboModuleInterop_;
|
||||
std::atomic<std::optional<bool>> useTurboModules_;
|
||||
};
|
||||
|
||||
+1
-5
@@ -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<<c08358e66009eff69107a684681feba9>>
|
||||
* @generated SignedSource<<001d0b39664b190385442ca8661a08a8>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -227,10 +227,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useStateAlignmentMechanism() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useTurboModuleInterop() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
+1
-2
@@ -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<<eca1f4ea2447e754c5cfa8998c2e7903>>
|
||||
* @generated SignedSource<<ddd6b6977c8ee0e40d710947b4a23c3c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -75,7 +75,6 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool useOptimizedEventBatchingOnAndroid() = 0;
|
||||
virtual bool useRuntimeShadowNodeReferenceUpdate() = 0;
|
||||
virtual bool useRuntimeShadowNodeReferenceUpdateOnLayout() = 0;
|
||||
virtual bool useStateAlignmentMechanism() = 0;
|
||||
virtual bool useTurboModuleInterop() = 0;
|
||||
virtual bool useTurboModules() = 0;
|
||||
};
|
||||
|
||||
+1
-6
@@ -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<<cfb1dc3fb447f3e4b014533a757e6c23>>
|
||||
* @generated SignedSource<<74bbe88f1a61cca088a504bb2a1bc19c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -287,11 +287,6 @@ bool NativeReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdateOnLayout(
|
||||
return ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdateOnLayout();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::useStateAlignmentMechanism(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::useStateAlignmentMechanism();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::useTurboModuleInterop(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::useTurboModuleInterop();
|
||||
|
||||
+1
-3
@@ -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<<3f8b503d5402563b0eb94fe46ffa2814>>
|
||||
* @generated SignedSource<<447e801fe9b49d2413d8bfbc106019a0>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -135,8 +135,6 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
bool useRuntimeShadowNodeReferenceUpdateOnLayout(jsi::Runtime& runtime);
|
||||
|
||||
bool useStateAlignmentMechanism(jsi::Runtime& runtime);
|
||||
|
||||
bool useTurboModuleInterop(jsi::Runtime& runtime);
|
||||
|
||||
bool useTurboModules(jsi::Runtime& runtime);
|
||||
|
||||
@@ -78,7 +78,6 @@ ShadowNode::ShadowNode(
|
||||
react_native_assert(children_);
|
||||
|
||||
traits_.set(ShadowNodeTraits::Trait::ChildrenAreShared);
|
||||
traits_.set(fragment.traits.get());
|
||||
|
||||
for (const auto& child : *children_) {
|
||||
child->family_->setParent(family_);
|
||||
@@ -110,9 +109,7 @@ ShadowNode::ShadowNode(
|
||||
|
||||
// State could have been progressed above by checking
|
||||
// `sourceShadowNode.getMostRecentState()`.
|
||||
traits_.unset(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
traits_.set(ShadowNodeTraits::Trait::ChildrenAreShared);
|
||||
traits_.set(fragment.traits.get());
|
||||
|
||||
if (fragment.children) {
|
||||
for (const auto& child : *children_) {
|
||||
@@ -136,8 +133,7 @@ ShadowNode::Unshared ShadowNode::clone(
|
||||
*this,
|
||||
{.props = props,
|
||||
.children = fragment.children,
|
||||
.state = fragment.state,
|
||||
.traits = fragment.traits});
|
||||
.state = fragment.state});
|
||||
return clonedNode;
|
||||
} else {
|
||||
// TODO: We might need to merge fragment.priops with
|
||||
@@ -293,23 +289,6 @@ bool ShadowNode::getHasBeenPromoted() const {
|
||||
return hasBeenMounted_.load();
|
||||
}
|
||||
|
||||
bool ShadowNode::progressStateIfNecessary() {
|
||||
auto hasBeenPromoted = hasBeenMounted_.load();
|
||||
if (!hasBeenPromoted && state_) {
|
||||
ensureUnsealed();
|
||||
auto mostRecentState = family_->getMostRecentStateIfObsolete(*state_);
|
||||
if (mostRecentState) {
|
||||
state_ = mostRecentState;
|
||||
const auto& componentDescriptor = family_->componentDescriptor_;
|
||||
// Must call ComponentDescriptor::adopt to trigger any side effect
|
||||
// state may have. E.g. adjusting padding.
|
||||
componentDescriptor.adopt(*this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShadowNode::setRuntimeShadowNodeReference(
|
||||
const std::shared_ptr<ShadowNodeWrapper>& runtimeShadowNodeReference)
|
||||
const {
|
||||
@@ -342,8 +321,7 @@ const ShadowNodeFamily& ShadowNode::getFamily() const {
|
||||
ShadowNode::Unshared ShadowNode::cloneTree(
|
||||
const ShadowNodeFamily& shadowNodeFamily,
|
||||
const std::function<ShadowNode::Unshared(const ShadowNode& oldShadowNode)>&
|
||||
callback,
|
||||
ShadowNodeTraits traits) const {
|
||||
callback) const {
|
||||
auto ancestors = shadowNodeFamily.getAncestors(*this);
|
||||
|
||||
if (ancestors.empty()) {
|
||||
@@ -371,8 +349,7 @@ ShadowNode::Unshared ShadowNode::cloneTree(
|
||||
children[childIndex] = childNode;
|
||||
|
||||
childNode = parentNode.clone(
|
||||
{.children = std::make_shared<ShadowNode::ListOfShared>(children),
|
||||
.traits = traits});
|
||||
{.children = std::make_shared<ShadowNode::ListOfShared>(children)});
|
||||
}
|
||||
|
||||
return std::const_pointer_cast<ShadowNode>(childNode);
|
||||
|
||||
@@ -102,8 +102,8 @@ class ShadowNode : public Sealable,
|
||||
*/
|
||||
Unshared cloneTree(
|
||||
const ShadowNodeFamily& shadowNodeFamily,
|
||||
const std::function<Unshared(const ShadowNode& oldShadowNode)>& callback,
|
||||
ShadowNodeTraits traits = {}) const;
|
||||
const std::function<Unshared(const ShadowNode& oldShadowNode)>& callback)
|
||||
const;
|
||||
|
||||
#pragma mark - Getters
|
||||
|
||||
@@ -178,17 +178,6 @@ class ShadowNode : public Sealable,
|
||||
*/
|
||||
bool getHasBeenPromoted() const;
|
||||
|
||||
/*
|
||||
* Applies the most recent state to the ShadowNode if following conditions are
|
||||
* met:
|
||||
* - ShadowNode has a state.
|
||||
* - ShadowNode has not been mounted before.
|
||||
* - ShadowNode's current state is obsolete.
|
||||
*
|
||||
* Returns true if the state was applied, false otherwise.
|
||||
*/
|
||||
bool progressStateIfNecessary();
|
||||
|
||||
/*
|
||||
* Bind the runtime reference to this `ShadowNode` with a weak pointer,
|
||||
* allowing to update the reference to this `ShadowNode` when cloned.
|
||||
|
||||
@@ -26,7 +26,6 @@ struct ShadowNodeFragment {
|
||||
const Props::Shared& props = propsPlaceholder();
|
||||
const ShadowNode::SharedListOfShared& children = childrenPlaceholder();
|
||||
const State::Shared& state = statePlaceholder();
|
||||
const ShadowNodeTraits traits = {};
|
||||
const bool runtimeShadowNodeReference = true;
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,14 +70,11 @@ class ShadowNodeTraits {
|
||||
// to be cloned before the first mutation.
|
||||
ChildrenAreShared = 1 << 8,
|
||||
|
||||
// Indicates that the node was cloned because of native state update.
|
||||
ClonedByNativeStateUpdate = 1 << 9,
|
||||
|
||||
// Indicates that direct children of the node should not be collapsed
|
||||
ChildrenFormStackingContext = 1 << 10,
|
||||
ChildrenFormStackingContext = 1 << 9,
|
||||
|
||||
// Inherits `YogaLayoutableShadowNode` and has a custom baseline function.
|
||||
BaselineYogaNode = 1 << 11,
|
||||
BaselineYogaNode = 1 << 10,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -244,26 +244,6 @@ TEST_P(ShadowNodeTest, handleCloneFunction) {
|
||||
EXPECT_EQ(nodeAB_->getProps(), nodeABClone->getProps());
|
||||
}
|
||||
|
||||
TEST_P(ShadowNodeTest, handleCloningWithTraits) {
|
||||
auto clonedWithoutTraits = nodeAB_->clone({});
|
||||
|
||||
EXPECT_FALSE(clonedWithoutTraits->getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto clonedWithTraits = clonedWithoutTraits->clone({.traits = newTraits});
|
||||
|
||||
EXPECT_TRUE(clonedWithTraits->getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
|
||||
auto clonedAgain = clonedWithTraits->clone({});
|
||||
|
||||
EXPECT_FALSE(clonedAgain->getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
}
|
||||
|
||||
TEST_P(ShadowNodeTest, handleState) {
|
||||
auto family = componentDescriptor_.createFamily(ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
@@ -319,37 +299,6 @@ TEST_P(ShadowNodeTest, handleState) {
|
||||
"Attempt to mutate a sealed object.");
|
||||
}
|
||||
|
||||
TEST_P(ShadowNodeTest, testCloneTree) {
|
||||
auto& family = nodeABA_->getFamily();
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
auto rootNode = nodeA_->cloneTree(
|
||||
family,
|
||||
[newTraits](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
|
||||
EXPECT_TRUE(rootNode->getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
|
||||
EXPECT_FALSE(rootNode->getChildren()[0]->getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
|
||||
const auto& firstLevelChild = *rootNode->getChildren()[1];
|
||||
|
||||
EXPECT_TRUE(firstLevelChild.getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
|
||||
EXPECT_FALSE(firstLevelChild.getChildren()[1]->getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
|
||||
const auto& secondLevelchild = *firstLevelChild.getChildren()[0];
|
||||
|
||||
EXPECT_TRUE(secondLevelchild.getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate));
|
||||
}
|
||||
|
||||
TEST_P(ShadowNodeTest, handleRuntimeReferenceTransferOnClone) {
|
||||
auto nodeABRev1 = nodeAB_->clone({});
|
||||
auto wrappedShadowNode = std::make_shared<ShadowNodeWrapper>(nodeABRev1);
|
||||
|
||||
@@ -298,6 +298,7 @@ ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairs(
|
||||
}
|
||||
|
||||
size_t startOfStaticIndex = 0;
|
||||
|
||||
sliceChildShadowNodeViewPairsRecursively(
|
||||
pairList, startOfStaticIndex, scope, layoutOffset, shadowNode);
|
||||
|
||||
|
||||
@@ -26,115 +26,6 @@ namespace facebook::react {
|
||||
using CommitStatus = ShadowTree::CommitStatus;
|
||||
using CommitMode = ShadowTree::CommitMode;
|
||||
|
||||
// --- State Alignment Mechanism algorithm ---
|
||||
// Note: Ideally, we don't have to const_cast but our use of constness in
|
||||
// C++ is overly restrictive. We do const_cast here but the only place where
|
||||
// we change ShadowNode is by calling `ShadowNode::progressStateIfNecessary`
|
||||
// where checks are in place to avoid manipulating a sealed ShadowNode.
|
||||
|
||||
static void progressStateIfNecessary(
|
||||
ShadowNode& newShadowNode,
|
||||
const ShadowNode& baseShadowNode);
|
||||
|
||||
/*
|
||||
* Looks at the new parent, new child and base child node to determine how to
|
||||
* reconcile the state.
|
||||
*
|
||||
* Only to be called when baseChildNode has trait `ClonedByNativeStateUpdate`.
|
||||
*/
|
||||
static void progressStateIfNecessary(
|
||||
ShadowNode& newShadowNode,
|
||||
const ShadowNode& newChildNode,
|
||||
const ShadowNode& baseChildNode,
|
||||
size_t suggestedIndex) {
|
||||
auto& shadowNode = const_cast<ShadowNode&>(newChildNode);
|
||||
if (shadowNode.progressStateIfNecessary()) {
|
||||
// State was progressed without the need to clone.
|
||||
// We are done with this node, but need to keep traversing.
|
||||
progressStateIfNecessary(shadowNode, baseChildNode);
|
||||
} else if (newChildNode.getHasBeenPromoted()) {
|
||||
// `newShadowNode` was cloned from react and cloned from a native state
|
||||
// update. This child node was cloned only from a native state update.
|
||||
// This is branching and it is safe to promote the new branch from
|
||||
// native state update.
|
||||
auto clonedChildNode = baseChildNode.clone({});
|
||||
newShadowNode.replaceChild(newChildNode, clonedChildNode, suggestedIndex);
|
||||
} else {
|
||||
// `newShadowNode` was cloned from react and cloned from a native state
|
||||
// update. This child node was cloned also by react.
|
||||
// we can't reason about this on this layer and need to keep traversing.
|
||||
progressStateIfNecessary(shadowNode, baseChildNode);
|
||||
}
|
||||
}
|
||||
|
||||
static void progressStateIfNecessary(
|
||||
ShadowNode& newShadowNode,
|
||||
const ShadowNode& baseShadowNode) {
|
||||
auto& newChildren = newShadowNode.getChildren();
|
||||
auto& baseChildren = baseShadowNode.getChildren();
|
||||
|
||||
auto newChildrenSize = newChildren.size();
|
||||
auto baseChildrenSize = baseChildren.size();
|
||||
auto index = size_t{0};
|
||||
|
||||
for (index = 0; index < newChildrenSize && index < baseChildrenSize;
|
||||
++index) {
|
||||
const auto& newChildNode = *newChildren[index];
|
||||
const auto& baseChildNode = *baseChildren[index];
|
||||
|
||||
if (&newChildNode == &baseChildNode) {
|
||||
// Nodes are identical. They are shared between `newShadowNode` and
|
||||
// `baseShadowNode` and it is safe to skipping.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ShadowNode::sameFamily(newChildNode, baseChildNode)) {
|
||||
// React has changed the structure of the tree. We will realign the
|
||||
// structure below.
|
||||
break;
|
||||
}
|
||||
|
||||
if (!baseChildNode.getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)) {
|
||||
// was not cloned with a new state, we can continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
progressStateIfNecessary(newShadowNode, newChildNode, baseChildNode, index);
|
||||
}
|
||||
|
||||
// === Realigning the tree ===
|
||||
|
||||
auto unprocessedBaseChildren = baseChildren.begin();
|
||||
std::advance(unprocessedBaseChildren, index);
|
||||
for (; index < newChildrenSize; ++index) {
|
||||
const auto& newChildNode = *newChildren[index];
|
||||
auto baseChildNodeIterator = std::find_if(
|
||||
unprocessedBaseChildren,
|
||||
baseChildren.end(),
|
||||
[&newChildNode](auto baseChildNode) {
|
||||
return ShadowNode::sameFamily(newChildNode, *baseChildNode);
|
||||
});
|
||||
if (baseChildNodeIterator == baseChildren.end()) {
|
||||
// This must never happen and there is a mismatch between the two trees.
|
||||
// No way of recover from this, let's just continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& baseChildNode = *(*baseChildNodeIterator);
|
||||
|
||||
if (!baseChildNode.getTraits().check(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate)) {
|
||||
// was not cloned with a new state, we can continue.
|
||||
continue;
|
||||
}
|
||||
|
||||
progressStateIfNecessary(newShadowNode, newChildNode, baseChildNode, index);
|
||||
}
|
||||
}
|
||||
|
||||
// --- End of State Alignment Mechanism algorithm ---
|
||||
|
||||
/*
|
||||
* Generates (possibly) a new tree where all nodes with non-obsolete `State`
|
||||
* objects. If all `State` objects in the tree are not obsolete for the moment
|
||||
@@ -393,15 +284,11 @@ CommitStatus ShadowTree::tryCommit(
|
||||
}
|
||||
|
||||
if (commitOptions.enableStateReconciliation) {
|
||||
if (ReactNativeFeatureFlags::useStateAlignmentMechanism()) {
|
||||
progressStateIfNecessary(*newRootShadowNode, *oldRootShadowNode);
|
||||
} else {
|
||||
auto updatedNewRootShadowNode =
|
||||
progressState(*newRootShadowNode, *oldRootShadowNode);
|
||||
if (updatedNewRootShadowNode) {
|
||||
newRootShadowNode =
|
||||
std::static_pointer_cast<RootShadowNode>(updatedNewRootShadowNode);
|
||||
}
|
||||
auto updatedNewRootShadowNode =
|
||||
progressState(*newRootShadowNode, *oldRootShadowNode);
|
||||
if (updatedNewRootShadowNode) {
|
||||
newRootShadowNode =
|
||||
std::static_pointer_cast<RootShadowNode>(updatedNewRootShadowNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-108
@@ -24,20 +24,6 @@
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
class StateReconciliationTestFeatureFlags
|
||||
: public ReactNativeFeatureFlagsDefaults {
|
||||
public:
|
||||
explicit StateReconciliationTestFeatureFlags(bool useStateAlignmentMechanism)
|
||||
: useStateAlignmentMechanism_(useStateAlignmentMechanism) {}
|
||||
|
||||
bool useStateAlignmentMechanism() override {
|
||||
return useStateAlignmentMechanism_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool useStateAlignmentMechanism_;
|
||||
};
|
||||
|
||||
class DummyShadowTreeDelegate : public ShadowTreeDelegate {
|
||||
public:
|
||||
RootShadowNode::Unshared shadowTreeWillCommit(
|
||||
@@ -82,20 +68,10 @@ class StateReconciliationTest : public ::testing::TestWithParam<bool> {
|
||||
public:
|
||||
StateReconciliationTest() : builder_(simpleComponentBuilder()) {}
|
||||
|
||||
void SetUp() override {
|
||||
ReactNativeFeatureFlags::dangerouslyReset();
|
||||
ReactNativeFeatureFlags::override(
|
||||
std::make_unique<StateReconciliationTestFeatureFlags>(GetParam()));
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
ReactNativeFeatureFlags::dangerouslyReset();
|
||||
}
|
||||
|
||||
ComponentBuilder builder_;
|
||||
};
|
||||
|
||||
TEST_P(StateReconciliationTest, testStateReconciliation) {
|
||||
TEST_F(StateReconciliationTest, testStateReconciliation) {
|
||||
// ==== SETUP ====
|
||||
|
||||
/*
|
||||
@@ -158,15 +134,10 @@ TEST_P(StateReconciliationTest, testStateReconciliation) {
|
||||
auto state2 = scrollViewComponentDescriptor.createState(
|
||||
scrollViewFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto rootShadowNodeState2 = initialRootShadowNode->cloneTree(
|
||||
scrollViewFamily,
|
||||
[&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state2, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
scrollViewFamily, [&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state2});
|
||||
});
|
||||
|
||||
EXPECT_EQ(
|
||||
findDescendantNode(*initialRootShadowNode, scrollViewFamily)->getState(),
|
||||
@@ -190,11 +161,9 @@ TEST_P(StateReconciliationTest, testStateReconciliation) {
|
||||
scrollViewFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto rootShadowNodeState3 = rootShadowNodeState2->cloneTree(
|
||||
scrollViewFamily,
|
||||
[&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state3, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
scrollViewFamily, [&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state3});
|
||||
});
|
||||
|
||||
EXPECT_EQ(
|
||||
findDescendantNode(*rootShadowNodeState3, scrollViewFamily)->getState(),
|
||||
@@ -232,7 +201,7 @@ TEST_P(StateReconciliationTest, testStateReconciliation) {
|
||||
state3->getRevision());
|
||||
}
|
||||
|
||||
TEST_P(StateReconciliationTest, testCloneslessStateReconciliationDoesntClone) {
|
||||
TEST_F(StateReconciliationTest, testCloneslessStateReconciliationDoesntClone) {
|
||||
// ==== SETUP ====
|
||||
/*
|
||||
<Root>
|
||||
@@ -286,15 +255,10 @@ TEST_P(StateReconciliationTest, testCloneslessStateReconciliationDoesntClone) {
|
||||
auto state2 = scrollViewComponentDescriptor.createState(
|
||||
scrollViewFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto rootShadowNode2 = rootShadowNode1->cloneTree(
|
||||
scrollViewFamily,
|
||||
[&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state2, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
scrollViewFamily, [&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state2});
|
||||
});
|
||||
|
||||
EXPECT_EQ(
|
||||
findDescendantNode(*rootShadowNode2, scrollViewFamily)->getState(),
|
||||
@@ -324,11 +288,9 @@ TEST_P(StateReconciliationTest, testCloneslessStateReconciliationDoesntClone) {
|
||||
scrollViewFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto rootShadowNodeClonedFromStateUpdate = rootShadowNode2->cloneTree(
|
||||
scrollViewFamily,
|
||||
[&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state3, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
scrollViewFamily, [&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state3});
|
||||
});
|
||||
|
||||
// ==== State update ====
|
||||
|
||||
@@ -351,15 +313,9 @@ TEST_P(StateReconciliationTest, testCloneslessStateReconciliationDoesntClone) {
|
||||
auto scrollViewShadowNode = findDescendantNode(shadowTree, scrollViewFamily);
|
||||
|
||||
EXPECT_EQ(scrollViewShadowNode->getState(), state3);
|
||||
|
||||
if (GetParam()) {
|
||||
// Checking that newlyClonedShadowNode was not cloned unnecessarly by state
|
||||
// progression. This fails with the old algorithm.
|
||||
EXPECT_EQ(scrollViewShadowNode, newlyClonedShadowNode.get());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(StateReconciliationTest, testStateReconciliationScrollViewChildUpdate) {
|
||||
TEST_F(StateReconciliationTest, testStateReconciliationScrollViewChildUpdate) {
|
||||
// ==== SETUP ====
|
||||
/*
|
||||
<Root>
|
||||
@@ -431,15 +387,10 @@ TEST_P(StateReconciliationTest, testStateReconciliationScrollViewChildUpdate) {
|
||||
auto state2 = scrollViewComponentDescriptor.createState(
|
||||
scrollViewFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto rootShadowNode2 = initialRootShadowNode->cloneTree(
|
||||
scrollViewFamily,
|
||||
[&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state2, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
scrollViewFamily, [&](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = state2});
|
||||
});
|
||||
|
||||
shadowTree.commit(
|
||||
[&](const RootShadowNode& /*oldRootShadowNode*/) {
|
||||
@@ -464,7 +415,7 @@ TEST_P(StateReconciliationTest, testStateReconciliationScrollViewChildUpdate) {
|
||||
newlyClonedViewShadowNode.get());
|
||||
}
|
||||
|
||||
TEST_P(StateReconciliationTest, testScrollViewWithChildrenDeletion) {
|
||||
TEST_F(StateReconciliationTest, testScrollViewWithChildrenDeletion) {
|
||||
// ==== SETUP ====
|
||||
|
||||
/*
|
||||
@@ -539,18 +490,13 @@ TEST_P(StateReconciliationTest, testScrollViewWithChildrenDeletion) {
|
||||
|
||||
// ==== State update ====
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto newState = scrollViewComponentDescriptor.createState(
|
||||
childBFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto rootShadowNodeClonedFromStateUpdate = rootNode->cloneTree(
|
||||
childBFamily,
|
||||
[&newState, newTraits](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
childBFamily, [&newState](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState});
|
||||
});
|
||||
|
||||
shadowTree.commit(
|
||||
[&rootShadowNodeClonedFromStateUpdate](
|
||||
@@ -578,7 +524,7 @@ TEST_P(StateReconciliationTest, testScrollViewWithChildrenDeletion) {
|
||||
newState);
|
||||
}
|
||||
|
||||
TEST_P(StateReconciliationTest, testScrollViewWithComplexChildrenReorder) {
|
||||
TEST_F(StateReconciliationTest, testScrollViewWithComplexChildrenReorder) {
|
||||
// ==== SETUP ====
|
||||
|
||||
/*
|
||||
@@ -660,18 +606,13 @@ TEST_P(StateReconciliationTest, testScrollViewWithComplexChildrenReorder) {
|
||||
|
||||
// ==== State update ====
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto newState = scrollViewComponentDescriptor.createState(
|
||||
childAFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto rootShadowNodeClonedFromStateUpdate = rootNode->cloneTree(
|
||||
childAFamily,
|
||||
[&newState, newTraits](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
childAFamily, [&newState](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState});
|
||||
});
|
||||
|
||||
shadowTree.commit(
|
||||
[&rootShadowNodeClonedFromStateUpdate](
|
||||
@@ -697,7 +638,7 @@ TEST_P(StateReconciliationTest, testScrollViewWithComplexChildrenReorder) {
|
||||
EXPECT_EQ(findDescendantNode(shadowTree, childAFamily)->getState(), newState);
|
||||
}
|
||||
|
||||
TEST_P(StateReconciliationTest, testScrollViewWithChildrenReorder) {
|
||||
TEST_F(StateReconciliationTest, testScrollViewWithChildrenReorder) {
|
||||
// ==== SETUP ====
|
||||
|
||||
/*
|
||||
@@ -766,18 +707,13 @@ TEST_P(StateReconciliationTest, testScrollViewWithChildrenReorder) {
|
||||
|
||||
// ==== State update ====
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto newState = scrollViewComponentDescriptor.createState(
|
||||
childAFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto rootShadowNodeClonedFromStateUpdate = rootNode->cloneTree(
|
||||
childAFamily,
|
||||
[&newState, newTraits](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
childAFamily, [&newState](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState});
|
||||
});
|
||||
|
||||
shadowTree.commit(
|
||||
[&rootShadowNodeClonedFromStateUpdate](
|
||||
@@ -803,7 +739,7 @@ TEST_P(StateReconciliationTest, testScrollViewWithChildrenReorder) {
|
||||
EXPECT_EQ(findDescendantNode(shadowTree, childAFamily)->getState(), newState);
|
||||
}
|
||||
|
||||
TEST_P(StateReconciliationTest, testScrollViewWithChildrenAddition) {
|
||||
TEST_F(StateReconciliationTest, testScrollViewWithChildrenAddition) {
|
||||
// ==== SETUP ====
|
||||
|
||||
/*
|
||||
@@ -856,18 +792,13 @@ TEST_P(StateReconciliationTest, testScrollViewWithChildrenAddition) {
|
||||
|
||||
// ==== State update ====
|
||||
|
||||
auto newTraits = ShadowNodeTraits();
|
||||
newTraits.set(ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
auto newState = scrollViewComponentDescriptor.createState(
|
||||
scrollViewFamily, std::make_shared<const ScrollViewState>());
|
||||
|
||||
auto rootShadowNodeClonedFromStateUpdate = rootNode->cloneTree(
|
||||
scrollViewFamily,
|
||||
[&newState, newTraits](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState, .traits = newTraits});
|
||||
},
|
||||
newTraits);
|
||||
scrollViewFamily, [&newState](const ShadowNode& oldShadowNode) {
|
||||
return oldShadowNode.clone({.state = newState});
|
||||
});
|
||||
|
||||
// ==== Tree with new child ====
|
||||
|
||||
@@ -922,8 +853,3 @@ TEST_P(StateReconciliationTest, testScrollViewWithChildrenAddition) {
|
||||
findDescendantNode(shadowTree, childB->getFamily())->getState(),
|
||||
newState);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
StateReconciliationTestInstantiation,
|
||||
StateReconciliationTest,
|
||||
testing::Values(false, true));
|
||||
|
||||
@@ -361,9 +361,6 @@ void UIManager::updateState(const StateUpdate& stateUpdate) const {
|
||||
auto& callback = stateUpdate.callback;
|
||||
auto& family = stateUpdate.family;
|
||||
auto& componentDescriptor = family->getComponentDescriptor();
|
||||
auto clonedByNativeStateTraits = ShadowNodeTraits();
|
||||
clonedByNativeStateTraits.set(
|
||||
ShadowNodeTraits::Trait::ClonedByNativeStateUpdate);
|
||||
|
||||
shadowTreeRegistry_.visit(
|
||||
family->getSurfaceId(), [&](const ShadowTree& shadowTree) {
|
||||
@@ -372,8 +369,7 @@ void UIManager::updateState(const StateUpdate& stateUpdate) const {
|
||||
auto isValid = true;
|
||||
|
||||
auto rootNode = oldRootShadowNode.cloneTree(
|
||||
*family,
|
||||
[&](const ShadowNode& oldShadowNode) {
|
||||
*family, [&](const ShadowNode& oldShadowNode) {
|
||||
auto newData =
|
||||
callback(oldShadowNode.getState()->getDataPointer());
|
||||
|
||||
@@ -389,10 +385,8 @@ void UIManager::updateState(const StateUpdate& stateUpdate) const {
|
||||
return oldShadowNode.clone(
|
||||
{.props = ShadowNodeFragment::propsPlaceholder(),
|
||||
.children = ShadowNodeFragment::childrenPlaceholder(),
|
||||
.state = newState,
|
||||
.traits = clonedByNativeStateTraits});
|
||||
},
|
||||
clonedByNativeStateTraits);
|
||||
.state = newState});
|
||||
});
|
||||
|
||||
return isValid
|
||||
? std::static_pointer_cast<RootShadowNode>(rootNode)
|
||||
|
||||
@@ -467,15 +467,6 @@ const definitions: FeatureFlagDefinitions = {
|
||||
purpose: 'experimentation',
|
||||
},
|
||||
},
|
||||
useStateAlignmentMechanism: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
dateAdded: '2024-04-12',
|
||||
description:
|
||||
'When enabled, it uses optimised state reconciliation algorithm.',
|
||||
purpose: 'experimentation',
|
||||
},
|
||||
},
|
||||
useTurboModuleInterop: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
|
||||
@@ -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<<1bf690e95da1924a4cae50ec639a95df>>
|
||||
* @generated SignedSource<<e161b67cb919ad7e2e67ddcb3c501adb>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -99,7 +99,6 @@ export type ReactNativeFeatureFlags = {
|
||||
useOptimizedEventBatchingOnAndroid: Getter<boolean>,
|
||||
useRuntimeShadowNodeReferenceUpdate: Getter<boolean>,
|
||||
useRuntimeShadowNodeReferenceUpdateOnLayout: Getter<boolean>,
|
||||
useStateAlignmentMechanism: Getter<boolean>,
|
||||
useTurboModuleInterop: Getter<boolean>,
|
||||
useTurboModules: Getter<boolean>,
|
||||
}
|
||||
@@ -384,10 +383,6 @@ export const useRuntimeShadowNodeReferenceUpdate: Getter<boolean> = createNative
|
||||
* When enabled, cloning shadow nodes during layout will update the reference held by the current JS fiber tree.
|
||||
*/
|
||||
export const useRuntimeShadowNodeReferenceUpdateOnLayout: Getter<boolean> = createNativeFlagGetter('useRuntimeShadowNodeReferenceUpdateOnLayout', false);
|
||||
/**
|
||||
* When enabled, it uses optimised state reconciliation algorithm.
|
||||
*/
|
||||
export const useStateAlignmentMechanism: Getter<boolean> = createNativeFlagGetter('useStateAlignmentMechanism', false);
|
||||
/**
|
||||
* In Bridgeless mode, should legacy NativeModules use the TurboModule system?
|
||||
*/
|
||||
|
||||
+1
-2
@@ -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<<de64240cb68a53f5dc2f97b7ec967eeb>>
|
||||
* @generated SignedSource<<cd4a2a047e3a6fdb4205efb518906462>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -73,7 +73,6 @@ export interface Spec extends TurboModule {
|
||||
+useOptimizedEventBatchingOnAndroid?: () => boolean;
|
||||
+useRuntimeShadowNodeReferenceUpdate?: () => boolean;
|
||||
+useRuntimeShadowNodeReferenceUpdateOnLayout?: () => boolean;
|
||||
+useStateAlignmentMechanism?: () => boolean;
|
||||
+useTurboModuleInterop?: () => boolean;
|
||||
+useTurboModules?: () => boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user