Skip to content

Commit 1aab70d

Browse files
sherginfacebook-github-bot
authored andcommitted
Fabric: RootShadowNode::clone was renamed/moved to ShadowNode::cloneTree
Summary: Cloning subtrees is not something specific to a RootNode, so it makes sense to have it in ShadowNode. Soon we will use that to clone subtrees inside Paragraph component to implement Inline Views. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D20090666 fbshipit-source-id: 0a64ef9bda438cd55d5fd21d3ad83b36221fa89e
1 parent 011b470 commit 1aab70d

File tree

7 files changed

+122
-113
lines changed

7 files changed

+122
-113
lines changed

ReactCommon/fabric/components/root/RootShadowNode.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,40 +46,5 @@ RootShadowNode::Unshared RootShadowNode::clone(
4646
return newRootShadowNode;
4747
}
4848

49-
RootShadowNode::Unshared RootShadowNode::clone(
50-
ShadowNodeFamily const &shadowNodeFamily,
51-
std::function<ShadowNode::Unshared(ShadowNode const &oldShadowNode)>
52-
callback) const {
53-
auto ancestors = shadowNodeFamily.getAncestors(*this);
54-
55-
if (ancestors.size() == 0) {
56-
return RootShadowNode::Unshared{nullptr};
57-
}
58-
59-
auto &parent = ancestors.back();
60-
auto &oldShadowNode = parent.first.get().getChildren().at(parent.second);
61-
62-
auto newShadowNode = callback(*oldShadowNode);
63-
64-
auto childNode = newShadowNode;
65-
66-
for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) {
67-
auto &parentNode = it->first.get();
68-
auto childIndex = it->second;
69-
70-
auto children = parentNode.getChildren();
71-
assert(ShadowNode::sameFamily(*children.at(childIndex), *childNode));
72-
children[childIndex] = childNode;
73-
74-
childNode = parentNode.clone({
75-
ShadowNodeFragment::propsPlaceholder(),
76-
std::make_shared<SharedShadowNodeList>(children),
77-
});
78-
}
79-
80-
return std::const_pointer_cast<RootShadowNode>(
81-
std::static_pointer_cast<RootShadowNode const>(childNode));
82-
}
83-
8449
} // namespace react
8550
} // namespace facebook

ReactCommon/fabric/components/root/RootShadowNode.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,6 @@ class RootShadowNode final
4747
RootShadowNode::Unshared clone(
4848
LayoutConstraints const &layoutConstraints,
4949
LayoutContext const &layoutContext) const;
50-
51-
/*
52-
* Clones the node (and partially the tree starting from the node) by
53-
* replacing a `oldShadowNode` (which corresponds to a given `shadowNode`)
54-
* with a node that `callback` returns. `oldShadowNode` might not be the same
55-
* as `shadowNode` but they must share the same family.
56-
*
57-
* Returns `nullptr` if the operation cannot be performed successfully.
58-
*/
59-
RootShadowNode::Unshared clone(
60-
ShadowNodeFamily const &shadowNodeFamily,
61-
std::function<ShadowNode::Unshared(ShadowNode const &oldShadowNode)>
62-
callback) const;
6350
};
6451

6552
} // namespace react

ReactCommon/fabric/components/view/tests/ViewTest.cpp

Lines changed: 60 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,15 @@ TEST(ElementTest, testYogaDirtyFlag) {
7878
/*
7979
* Cloning props without changing them must *not* dirty Yoga nodes.
8080
*/
81-
auto newRootShadowNode = rootShadowNode->clone(
82-
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
83-
auto &componentDescriptor = oldShadowNode.getComponentDescriptor();
84-
auto props = componentDescriptor.cloneProps(
85-
oldShadowNode.getProps(), RawProps());
86-
return oldShadowNode.clone(ShadowNodeFragment{props});
87-
});
81+
auto newRootShadowNode =
82+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
83+
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
84+
auto &componentDescriptor =
85+
oldShadowNode.getComponentDescriptor();
86+
auto props = componentDescriptor.cloneProps(
87+
oldShadowNode.getProps(), RawProps());
88+
return oldShadowNode.clone(ShadowNodeFragment{props});
89+
}));
8890

8991
EXPECT_FALSE(newRootShadowNode->layoutIfNeeded());
9092
}
@@ -93,21 +95,22 @@ TEST(ElementTest, testYogaDirtyFlag) {
9395
/*
9496
* Changing *non-layout* sub-props must *not* dirty Yoga nodes.
9597
*/
96-
auto newRootShadowNode = rootShadowNode->clone(
97-
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
98-
auto viewProps = std::make_shared<ViewProps>();
99-
auto &props = *viewProps;
100-
101-
props.nativeId = "some new native Id";
102-
props.foregroundColor = whiteColor();
103-
props.backgroundColor = blackColor();
104-
props.opacity = props.opacity + 0.042;
105-
props.zIndex = props.zIndex + 42;
106-
props.shouldRasterize = !props.shouldRasterize;
107-
props.collapsable = !props.collapsable;
108-
109-
return oldShadowNode.clone(ShadowNodeFragment{viewProps});
110-
});
98+
auto newRootShadowNode =
99+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
100+
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
101+
auto viewProps = std::make_shared<ViewProps>();
102+
auto &props = *viewProps;
103+
104+
props.nativeId = "some new native Id";
105+
props.foregroundColor = whiteColor();
106+
props.backgroundColor = blackColor();
107+
props.opacity = props.opacity + 0.042;
108+
props.zIndex = props.zIndex + 42;
109+
props.shouldRasterize = !props.shouldRasterize;
110+
props.collapsable = !props.collapsable;
111+
112+
return oldShadowNode.clone(ShadowNodeFragment{viewProps});
113+
}));
111114

112115
EXPECT_FALSE(newRootShadowNode->layoutIfNeeded());
113116
}
@@ -116,16 +119,17 @@ TEST(ElementTest, testYogaDirtyFlag) {
116119
/*
117120
* Changing *layout* sub-props *must* dirty Yoga nodes.
118121
*/
119-
auto newRootShadowNode = rootShadowNode->clone(
120-
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
121-
auto viewProps = std::make_shared<ViewProps>();
122-
auto &props = *viewProps;
122+
auto newRootShadowNode =
123+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
124+
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
125+
auto viewProps = std::make_shared<ViewProps>();
126+
auto &props = *viewProps;
123127

124-
props.yogaStyle.alignContent() = YGAlignBaseline;
125-
props.yogaStyle.display() = YGDisplayNone;
128+
props.yogaStyle.alignContent() = YGAlignBaseline;
129+
props.yogaStyle.display() = YGDisplayNone;
126130

127-
return oldShadowNode.clone(ShadowNodeFragment{viewProps});
128-
});
131+
return oldShadowNode.clone(ShadowNodeFragment{viewProps});
132+
}));
129133

130134
EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
131135
}
@@ -134,12 +138,13 @@ TEST(ElementTest, testYogaDirtyFlag) {
134138
/*
135139
* Removing all children *must* dirty Yoga nodes.
136140
*/
137-
auto newRootShadowNode = rootShadowNode->clone(
138-
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
139-
return oldShadowNode.clone(
140-
{ShadowNodeFragment::propsPlaceholder(),
141-
ShadowNode::emptySharedShadowNodeSharedList()});
142-
});
141+
auto newRootShadowNode =
142+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
143+
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
144+
return oldShadowNode.clone(
145+
{ShadowNodeFragment::propsPlaceholder(),
146+
ShadowNode::emptySharedShadowNodeSharedList()});
147+
}));
143148

144149
EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
145150
}
@@ -148,17 +153,18 @@ TEST(ElementTest, testYogaDirtyFlag) {
148153
/*
149154
* Removing the last child *must* dirty Yoga nodes.
150155
*/
151-
auto newRootShadowNode = rootShadowNode->clone(
152-
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
153-
auto children = oldShadowNode.getChildren();
154-
children.pop_back();
156+
auto newRootShadowNode =
157+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
158+
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
159+
auto children = oldShadowNode.getChildren();
160+
children.pop_back();
155161

156-
std::reverse(children.begin(), children.end());
162+
std::reverse(children.begin(), children.end());
157163

158-
return oldShadowNode.clone(
159-
{ShadowNodeFragment::propsPlaceholder(),
160-
std::make_shared<ShadowNode::ListOfShared const>(children)});
161-
});
164+
return oldShadowNode.clone(
165+
{ShadowNodeFragment::propsPlaceholder(),
166+
std::make_shared<ShadowNode::ListOfShared const>(children)});
167+
}));
162168

163169
EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
164170
}
@@ -167,16 +173,17 @@ TEST(ElementTest, testYogaDirtyFlag) {
167173
/*
168174
* Reversing a list of children *must* dirty Yoga nodes.
169175
*/
170-
auto newRootShadowNode = rootShadowNode->clone(
171-
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
172-
auto children = oldShadowNode.getChildren();
176+
auto newRootShadowNode =
177+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
178+
innerShadowNode->getFamily(), [](ShadowNode const &oldShadowNode) {
179+
auto children = oldShadowNode.getChildren();
173180

174-
std::reverse(children.begin(), children.end());
181+
std::reverse(children.begin(), children.end());
175182

176-
return oldShadowNode.clone(
177-
{ShadowNodeFragment::propsPlaceholder(),
178-
std::make_shared<ShadowNode::ListOfShared const>(children)});
179-
});
183+
return oldShadowNode.clone(
184+
{ShadowNodeFragment::propsPlaceholder(),
185+
std::make_shared<ShadowNode::ListOfShared const>(children)});
186+
}));
180187

181188
EXPECT_TRUE(newRootShadowNode->layoutIfNeeded());
182189
}

ReactCommon/fabric/core/shadownode/ShadowNode.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,40 @@ int ShadowNode::getStateRevision() const {
242242
return stateRevision_;
243243
}
244244

245+
ShadowNode::Unshared ShadowNode::cloneTree(
246+
ShadowNodeFamily const &shadowNodeFamily,
247+
std::function<ShadowNode::Unshared(ShadowNode const &oldShadowNode)>
248+
callback) const {
249+
auto ancestors = shadowNodeFamily.getAncestors(*this);
250+
251+
if (ancestors.size() == 0) {
252+
return ShadowNode::Unshared{nullptr};
253+
}
254+
255+
auto &parent = ancestors.back();
256+
auto &oldShadowNode = parent.first.get().getChildren().at(parent.second);
257+
258+
auto newShadowNode = callback(*oldShadowNode);
259+
260+
auto childNode = newShadowNode;
261+
262+
for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) {
263+
auto &parentNode = it->first.get();
264+
auto childIndex = it->second;
265+
266+
auto children = parentNode.getChildren();
267+
assert(ShadowNode::sameFamily(*children.at(childIndex), *childNode));
268+
children[childIndex] = childNode;
269+
270+
childNode = parentNode.clone({
271+
ShadowNodeFragment::propsPlaceholder(),
272+
std::make_shared<SharedShadowNodeList>(children),
273+
});
274+
}
275+
276+
return std::const_pointer_cast<ShadowNode>(childNode);
277+
}
278+
245279
#pragma mark - DebugStringConvertible
246280

247281
#if RN_DEBUG_STRING_CONVERTIBLE

ReactCommon/fabric/core/shadownode/ShadowNode.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,18 @@ class ShadowNode : public Sealable, public DebugStringConvertible {
9797
*/
9898
UnsharedShadowNode clone(const ShadowNodeFragment &fragment) const;
9999

100+
/*
101+
* Clones the node (and partially the tree starting from the node) by
102+
* replacing a `oldShadowNode` (which corresponds to a given
103+
* `shadowNodeFamily`) with a node that `callback` returns.
104+
*
105+
* Returns `nullptr` if the operation cannot be performed successfully.
106+
*/
107+
ShadowNode::Unshared cloneTree(
108+
ShadowNodeFamily const &shadowNodeFamily,
109+
std::function<ShadowNode::Unshared(ShadowNode const &oldShadowNode)>
110+
callback) const;
111+
100112
#pragma mark - Getters
101113

102114
ComponentName getComponentName() const;

ReactCommon/fabric/mounting/tests/shadowTreeGeneration.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,11 @@ static void alterShadowTree(
171171
ShadowNodeAlteration alteration) {
172172
auto edge = findRandomShadowNode(entropy, rootShadowNode);
173173

174-
rootShadowNode = rootShadowNode->clone(
175-
edge.shadowNode->getFamily(), [&](ShadowNode const &oldShadowNode) {
176-
return alteration(entropy, oldShadowNode);
177-
});
174+
rootShadowNode =
175+
std::static_pointer_cast<RootShadowNode>(rootShadowNode->cloneTree(
176+
edge.shadowNode->getFamily(), [&](ShadowNode const &oldShadowNode) {
177+
return alteration(entropy, oldShadowNode);
178+
}));
178179
}
179180

180181
static void alterShadowTree(

ReactCommon/fabric/uimanager/UIManager.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,14 @@ void UIManager::setNativeProps(
146146
shadowNode.getSurfaceId(), [&](ShadowTree const &shadowTree) {
147147
shadowTree.tryCommit(
148148
[&](RootShadowNode::Shared const &oldRootShadowNode) {
149-
return oldRootShadowNode->clone(
150-
shadowNode.getFamily(), [&](ShadowNode const &oldShadowNode) {
151-
return oldShadowNode.clone({
152-
/* .props = */ props,
153-
});
154-
});
149+
return std::static_pointer_cast<RootShadowNode>(
150+
oldRootShadowNode->cloneTree(
151+
shadowNode.getFamily(),
152+
[&](ShadowNode const &oldShadowNode) {
153+
return oldShadowNode.clone({
154+
/* .props = */ props,
155+
});
156+
}));
155157
},
156158
true && stateReconciliationEnabled_);
157159
});
@@ -197,7 +199,8 @@ void UIManager::updateState(StateUpdate const &stateUpdate) const {
197199
family->getSurfaceId(), [&](ShadowTree const &shadowTree) {
198200
shadowTree.tryCommit([&](RootShadowNode::Shared const
199201
&oldRootShadowNode) {
200-
return oldRootShadowNode->clone(
202+
return std::static_pointer_cast<
203+
RootShadowNode>(oldRootShadowNode->cloneTree(
201204
*family, [&](ShadowNode const &oldShadowNode) {
202205
auto newData =
203206
callback(oldShadowNode.getState()->getDataPointer());
@@ -209,7 +212,7 @@ void UIManager::updateState(StateUpdate const &stateUpdate) const {
209212
/* .children = */ ShadowNodeFragment::childrenPlaceholder(),
210213
/* .state = */ newState,
211214
});
212-
});
215+
}));
213216
});
214217
});
215218
}

0 commit comments

Comments
 (0)