mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Use modern Differentiator "sliceChildShadowNodeViewPairs" in tests (#44131)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44131 Stub tree creation is using an old differentiator path we aren't shipping today. This removes that path, so that we can unit test the new one 1. Remove `ForTesting`/`Legacy` functions 3. Update stub view tree code for API/behavior difference of new differentiator functions including unflattened views. Don't create view instructions for those, and use `mountIndex` instead of pair index 4. Remove `V2` suffix, since the old path is deleted 5. Move mounting stub test utils out of the production library Changelog: [Internal] Reviewed By: joevilches Differential Revision: D56227426 fbshipit-source-id: 0f525097cfb576e0228c9ca20a770fa41ddf1e0d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
739a8dfcf4
commit
ed6abc4e83
@@ -208,7 +208,7 @@ static inline bool shadowNodeIsConcrete(const ShadowNode& shadowNode) {
|
||||
return shadowNode.getTraits().check(ShadowNodeTraits::Trait::FormsView);
|
||||
}
|
||||
|
||||
static void sliceChildShadowNodeViewPairsRecursivelyV2(
|
||||
static void sliceChildShadowNodeViewPairsRecursively(
|
||||
ShadowViewNodePair::NonOwningList& pairList,
|
||||
size_t& startOfStaticIndex,
|
||||
ViewNodePairScope& scope,
|
||||
@@ -255,21 +255,21 @@ static void sliceChildShadowNodeViewPairsRecursivelyV2(
|
||||
pairList.insert(it, &scope.back());
|
||||
startOfStaticIndex++;
|
||||
if (areChildrenFlattened) {
|
||||
sliceChildShadowNodeViewPairsRecursivelyV2(
|
||||
sliceChildShadowNodeViewPairsRecursively(
|
||||
pairList, startOfStaticIndex, scope, origin, childShadowNode);
|
||||
}
|
||||
} else {
|
||||
pairList.push_back(&scope.back());
|
||||
if (areChildrenFlattened) {
|
||||
size_t pairListSize = pairList.size();
|
||||
sliceChildShadowNodeViewPairsRecursivelyV2(
|
||||
sliceChildShadowNodeViewPairsRecursively(
|
||||
pairList, pairListSize, scope, origin, childShadowNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairsV2(
|
||||
ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairs(
|
||||
const ShadowNode& shadowNode,
|
||||
ViewNodePairScope& scope,
|
||||
bool allowFlattened,
|
||||
@@ -284,7 +284,7 @@ ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairsV2(
|
||||
}
|
||||
|
||||
size_t startOfStaticIndex = 0;
|
||||
sliceChildShadowNodeViewPairsRecursivelyV2(
|
||||
sliceChildShadowNodeViewPairsRecursively(
|
||||
pairList, startOfStaticIndex, scope, layoutOffset, shadowNode);
|
||||
|
||||
// Sorting pairs based on `orderIndex` if needed.
|
||||
@@ -300,7 +300,7 @@ ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairsV2(
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer calling this over `sliceChildShadowNodeViewPairsV2` directly, when
|
||||
* Prefer calling this over `sliceChildShadowNodeViewPairs` directly, when
|
||||
* possible. This can account for adding parent LayoutMetrics that are
|
||||
* important to take into account, but tricky, in (un)flattening cases.
|
||||
*/
|
||||
@@ -309,7 +309,7 @@ sliceChildShadowNodeViewPairsFromViewNodePair(
|
||||
const ShadowViewNodePair& shadowViewNodePair,
|
||||
ViewNodePairScope& scope,
|
||||
bool allowFlattened = false) {
|
||||
return sliceChildShadowNodeViewPairsV2(
|
||||
return sliceChildShadowNodeViewPairs(
|
||||
*shadowViewNodePair.shadowNode,
|
||||
scope,
|
||||
allowFlattened,
|
||||
@@ -346,7 +346,7 @@ static_assert(
|
||||
std::is_move_assignable<ShadowViewNodePair::NonOwningList>::value,
|
||||
"`ShadowViewNodePair::NonOwningList` must be `move assignable`.");
|
||||
|
||||
static void calculateShadowViewMutationsV2(
|
||||
static void calculateShadowViewMutations(
|
||||
ViewNodePairScope& scope,
|
||||
ShadowViewMutation::List& mutations,
|
||||
const ShadowView& parentShadowView,
|
||||
@@ -499,7 +499,7 @@ static void updateMatchedPairSubtrees(
|
||||
auto newGrandChildPairs =
|
||||
sliceChildShadowNodeViewPairsFromViewNodePair(newPair, innerScope);
|
||||
const size_t newGrandChildPairsSize = newGrandChildPairs.size();
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
*(newGrandChildPairsSize != 0u
|
||||
? &mutationContainer.downwardMutations
|
||||
@@ -834,7 +834,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
if (!oldTreeNodePair.flattened && !newTreeNodePair.flattened) {
|
||||
if (oldTreeNodePair.shadowNode != newTreeNodePair.shadowNode) {
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.downwardMutations,
|
||||
newTreeNodePair.shadowView,
|
||||
@@ -1010,7 +1010,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
|
||||
if (!treeChildPair.flattened) {
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.destructiveDownwardMutations,
|
||||
treeChildPair.shadowView,
|
||||
@@ -1024,7 +1024,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
|
||||
if (!treeChildPair.flattened) {
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.downwardMutations,
|
||||
treeChildPair.shadowView,
|
||||
@@ -1036,7 +1036,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
}
|
||||
}
|
||||
|
||||
static void calculateShadowViewMutationsV2(
|
||||
static void calculateShadowViewMutations(
|
||||
ViewNodePairScope& scope,
|
||||
ShadowViewMutation::List& mutations,
|
||||
const ShadowView& parentShadowView,
|
||||
@@ -1131,7 +1131,7 @@ static void calculateShadowViewMutationsV2(
|
||||
auto newGrandChildPairs = sliceChildShadowNodeViewPairsFromViewNodePair(
|
||||
newChildPair, innerScope);
|
||||
const size_t newGrandChildPairsSize = newGrandChildPairs.size();
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
*(newGrandChildPairsSize != 0u
|
||||
? &mutationContainer.downwardMutations
|
||||
@@ -1197,7 +1197,7 @@ static void calculateShadowViewMutationsV2(
|
||||
// We also have to call the algorithm recursively to clean up the entire
|
||||
// subtree starting from the removed view.
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.destructiveDownwardMutations,
|
||||
oldChildPair.shadowView,
|
||||
@@ -1231,7 +1231,7 @@ static void calculateShadowViewMutationsV2(
|
||||
ShadowViewMutation::CreateMutation(newChildPair.shadowView));
|
||||
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.downwardMutations,
|
||||
newChildPair.shadowView,
|
||||
@@ -1468,7 +1468,7 @@ static void calculateShadowViewMutationsV2(
|
||||
// We also have to call the algorithm recursively to clean up the
|
||||
// entire subtree starting from the removed view.
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.destructiveDownwardMutations,
|
||||
oldChildPair.shadowView,
|
||||
@@ -1512,7 +1512,7 @@ static void calculateShadowViewMutationsV2(
|
||||
ShadowViewMutation::CreateMutation(newChildPair.shadowView));
|
||||
|
||||
ViewNodePairScope innerScope{};
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerScope,
|
||||
mutationContainer.downwardMutations,
|
||||
newChildPair.shadowView,
|
||||
@@ -1553,65 +1553,6 @@ static void calculateShadowViewMutationsV2(
|
||||
std::back_inserter(mutations));
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used by unit tests currently.
|
||||
*/
|
||||
static void sliceChildShadowNodeViewPairsRecursivelyForTesting(
|
||||
ShadowViewNodePair::OwningList& pairList,
|
||||
Point layoutOffset,
|
||||
const ShadowNode& shadowNode) {
|
||||
for (const auto& sharedChildShadowNode : shadowNode.getChildren()) {
|
||||
auto& childShadowNode = *sharedChildShadowNode;
|
||||
|
||||
#ifndef ANDROID
|
||||
// Temporary disabled on Android because the mounting infrastructure
|
||||
// is not fully ready yet.
|
||||
if (childShadowNode.getTraits().check(ShadowNodeTraits::Trait::Hidden)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto shadowView = ShadowView(childShadowNode);
|
||||
auto origin = layoutOffset;
|
||||
if (shadowView.layoutMetrics != EmptyLayoutMetrics) {
|
||||
origin += shadowView.layoutMetrics.frame.origin;
|
||||
shadowView.layoutMetrics.frame.origin += layoutOffset;
|
||||
}
|
||||
|
||||
if (childShadowNode.getTraits().check(
|
||||
ShadowNodeTraits::Trait::FormsStackingContext)) {
|
||||
pairList.push_back({shadowView, &childShadowNode});
|
||||
} else {
|
||||
if (childShadowNode.getTraits().check(
|
||||
ShadowNodeTraits::Trait::FormsView)) {
|
||||
pairList.push_back({shadowView, &childShadowNode});
|
||||
}
|
||||
|
||||
sliceChildShadowNodeViewPairsRecursivelyForTesting(
|
||||
pairList, origin, childShadowNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used by unit tests currently.
|
||||
*/
|
||||
ShadowViewNodePair::OwningList sliceChildShadowNodeViewPairsForTesting(
|
||||
const ShadowNode& shadowNode) {
|
||||
auto pairList = ShadowViewNodePair::OwningList{};
|
||||
|
||||
if (!shadowNode.getTraits().check(
|
||||
ShadowNodeTraits::Trait::FormsStackingContext) &&
|
||||
shadowNode.getTraits().check(ShadowNodeTraits::Trait::FormsView)) {
|
||||
return pairList;
|
||||
}
|
||||
|
||||
sliceChildShadowNodeViewPairsRecursivelyForTesting(
|
||||
pairList, {0, 0}, shadowNode);
|
||||
|
||||
return pairList;
|
||||
}
|
||||
|
||||
ShadowViewMutation::List calculateShadowViewMutations(
|
||||
const ShadowNode& oldRootShadowNode,
|
||||
const ShadowNode& newRootShadowNode) {
|
||||
@@ -1636,12 +1577,12 @@ ShadowViewMutation::List calculateShadowViewMutations(
|
||||
oldRootShadowView, newRootShadowView, {}));
|
||||
}
|
||||
|
||||
calculateShadowViewMutationsV2(
|
||||
calculateShadowViewMutations(
|
||||
innerViewNodePairScope,
|
||||
mutations,
|
||||
ShadowView(oldRootShadowNode),
|
||||
sliceChildShadowNodeViewPairsV2(oldRootShadowNode, viewNodePairScope),
|
||||
sliceChildShadowNodeViewPairsV2(newRootShadowNode, viewNodePairScope));
|
||||
sliceChildShadowNodeViewPairs(oldRootShadowNode, viewNodePairScope),
|
||||
sliceChildShadowNodeViewPairs(newRootShadowNode, viewNodePairScope));
|
||||
|
||||
return mutations;
|
||||
}
|
||||
|
||||
@@ -53,17 +53,10 @@ ShadowViewMutation::List calculateShadowViewMutations(
|
||||
* flattened view hierarchy. The V2 version preserves nodes even if they do
|
||||
* not form views and their children are flattened.
|
||||
*/
|
||||
ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairsV2(
|
||||
ShadowViewNodePair::NonOwningList sliceChildShadowNodeViewPairs(
|
||||
const ShadowNode& shadowNode,
|
||||
ViewNodePairScope& viewNodePairScope,
|
||||
bool allowFlattened = false,
|
||||
Point layoutOffset = {0, 0});
|
||||
|
||||
/*
|
||||
* Generates a list of `ShadowViewNodePair`s that represents a layer of a
|
||||
* flattened view hierarchy. This is *only* used by unit tests currently.
|
||||
*/
|
||||
ShadowViewNodePair::OwningList sliceChildShadowNodeViewPairsForTesting(
|
||||
const ShadowNode& shadowNode);
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -85,14 +85,4 @@ bool ShadowViewNodePair::operator!=(const ShadowViewNodePair& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool ShadowViewNodePairLegacy::operator==(
|
||||
const ShadowViewNodePairLegacy& rhs) const {
|
||||
return this->shadowNode == rhs.shadowNode;
|
||||
}
|
||||
|
||||
bool ShadowViewNodePairLegacy::operator!=(
|
||||
const ShadowViewNodePairLegacy& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -64,7 +64,6 @@ std::vector<DebugStringConvertibleObject> getDebugProps(
|
||||
*/
|
||||
struct ShadowViewNodePair final {
|
||||
using NonOwningList = std::vector<ShadowViewNodePair*>;
|
||||
using OwningList = std::vector<ShadowViewNodePair>;
|
||||
|
||||
ShadowView shadowView;
|
||||
const ShadowNode* shadowNode;
|
||||
@@ -93,30 +92,6 @@ struct ShadowViewNodePair final {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Describes pair of a `ShadowView` and a `ShadowNode`.
|
||||
* This is not exposed to the mounting layer.
|
||||
*
|
||||
*/
|
||||
struct ShadowViewNodePairLegacy final {
|
||||
using OwningList = std::vector<ShadowViewNodePairLegacy>;
|
||||
|
||||
ShadowView shadowView;
|
||||
const ShadowNode* shadowNode;
|
||||
bool flattened{false};
|
||||
bool isConcreteView{true};
|
||||
|
||||
size_t mountIndex{0};
|
||||
|
||||
bool inOtherTree{false};
|
||||
|
||||
/*
|
||||
* The stored pointer to `ShadowNode` represents an identity of the pair.
|
||||
*/
|
||||
bool operator==(const ShadowViewNodePairLegacy& rhs) const;
|
||||
bool operator!=(const ShadowViewNodePairLegacy& rhs) const;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
namespace std {
|
||||
|
||||
+19
-12
@@ -17,16 +17,16 @@ namespace facebook::react {
|
||||
* Sorting comparator for `reorderInPlaceIfNeeded`.
|
||||
*/
|
||||
static bool shouldFirstPairComesBeforeSecondOne(
|
||||
const ShadowViewNodePair& lhs,
|
||||
const ShadowViewNodePair& rhs) noexcept {
|
||||
return lhs.shadowNode->getOrderIndex() < rhs.shadowNode->getOrderIndex();
|
||||
const ShadowViewNodePair* lhs,
|
||||
const ShadowViewNodePair* rhs) noexcept {
|
||||
return lhs->shadowNode->getOrderIndex() < rhs->shadowNode->getOrderIndex();
|
||||
}
|
||||
|
||||
/*
|
||||
* Reorders pairs in-place based on `orderIndex` using a stable sort algorithm.
|
||||
*/
|
||||
static void reorderInPlaceIfNeeded(
|
||||
ShadowViewNodePair::OwningList& pairs) noexcept {
|
||||
std::vector<ShadowViewNodePair*>& pairs) noexcept {
|
||||
// This is a simplified version of the function intentionally copied from
|
||||
// `Differentiator.cpp`.
|
||||
std::stable_sort(
|
||||
@@ -41,24 +41,29 @@ static void reorderInPlaceIfNeeded(
|
||||
*/
|
||||
static void calculateShadowViewMutationsForNewTree(
|
||||
ShadowViewMutation::List& mutations,
|
||||
ViewNodePairScope& scope,
|
||||
const ShadowView& parentShadowView,
|
||||
ShadowViewNodePair::OwningList newChildPairs) {
|
||||
std::vector<ShadowViewNodePair*> newChildPairs) {
|
||||
// Sorting pairs based on `orderIndex` if needed.
|
||||
reorderInPlaceIfNeeded(newChildPairs);
|
||||
|
||||
for (size_t index = 0; index < newChildPairs.size(); index++) {
|
||||
const auto& newChildPair = newChildPairs[index];
|
||||
for (auto newChildPair : newChildPairs) {
|
||||
if (!newChildPair->isConcreteView) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mutations.push_back(
|
||||
ShadowViewMutation::CreateMutation(newChildPair.shadowView));
|
||||
ShadowViewMutation::CreateMutation(newChildPair->shadowView));
|
||||
mutations.push_back(ShadowViewMutation::InsertMutation(
|
||||
parentShadowView, newChildPair.shadowView, static_cast<int>(index)));
|
||||
parentShadowView,
|
||||
newChildPair->shadowView,
|
||||
static_cast<int>(newChildPair->mountIndex)));
|
||||
|
||||
auto newGrandChildPairs =
|
||||
sliceChildShadowNodeViewPairsForTesting(*newChildPair.shadowNode);
|
||||
sliceChildShadowNodeViewPairs(*newChildPair->shadowNode, scope);
|
||||
|
||||
calculateShadowViewMutationsForNewTree(
|
||||
mutations, newChildPair.shadowView, newGrandChildPairs);
|
||||
mutations, scope, newChildPair->shadowView, newGrandChildPairs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,10 +72,12 @@ StubViewTree buildStubViewTreeWithoutUsingDifferentiator(
|
||||
auto mutations = ShadowViewMutation::List{};
|
||||
mutations.reserve(256);
|
||||
|
||||
ViewNodePairScope scope;
|
||||
calculateShadowViewMutationsForNewTree(
|
||||
mutations,
|
||||
scope,
|
||||
ShadowView(rootShadowNode),
|
||||
sliceChildShadowNodeViewPairsForTesting(rootShadowNode));
|
||||
sliceChildShadowNodeViewPairs(rootShadowNode, scope));
|
||||
|
||||
auto emptyRootShadowNode = rootShadowNode.clone(ShadowNodeFragment{
|
||||
ShadowNodeFragment::propsPlaceholder(),
|
||||
Reference in New Issue
Block a user