Skip to content

Commit 28968e2

Browse files
priteshrnandgaonkarfacebook-github-bot
authored andcommittedJan 8, 2018
Move YGCloneChildrenIfNeeded as a method on YGNode
Reviewed By: emilsjolander Differential Revision: D6611155 fbshipit-source-id: 463723a363e0fbd2c7686f65226eca73236bd07e
1 parent 654d759 commit 28968e2

File tree

3 files changed

+42
-54
lines changed

3 files changed

+42
-54
lines changed
 

‎ReactCommon/yoga/yoga/YGNode.cpp

+33-17
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ void YGNode::replaceChild(YGNodeRef child, uint32_t index) {
155155
children_[index] = child;
156156
}
157157

158+
void YGNode::replaceChild(YGNodeRef oldChild, YGNodeRef newChild) {
159+
std::replace(children_.begin(), children_.end(), oldChild, newChild);
160+
}
161+
158162
void YGNode::insertChild(YGNodeRef child, uint32_t index) {
159163
children_.insert(children_.begin() + index, child);
160164
}
@@ -375,21 +379,33 @@ YGNode::~YGNode() {
375379
// deallocate here
376380
}
377381

378-
const YGNode& YGNode::defaultValue() {
379-
static const YGNode n = {nullptr,
380-
nullptr,
381-
true,
382-
YGNodeTypeDefault,
383-
nullptr,
384-
nullptr,
385-
gYGNodeStyleDefaults,
386-
gYGNodeLayoutDefaults,
387-
0,
388-
nullptr,
389-
YGVector(),
390-
nullptr,
391-
nullptr,
392-
false,
393-
{{YGValueUndefined, YGValueUndefined}}};
394-
return n;
382+
void YGNode::cloneChildrenIfNeeded() {
383+
// YGNodeRemoveChild in yoga.cpp has a forked variant of this algorithm
384+
// optimized for deletions.
385+
386+
const uint32_t childCount = children_.size();
387+
if (childCount == 0) {
388+
// This is an empty set. Nothing to clone.
389+
return;
390+
}
391+
392+
const YGNodeRef firstChild = children_.front();
393+
if (firstChild->getParent() == this) {
394+
// If the first child has this node as its parent, we assume that it is
395+
// already unique. We can do this because if we have it has a child, that
396+
// means that its parent was at some point cloned which made that subtree
397+
// immutable. We also assume that all its sibling are cloned as well.
398+
return;
399+
}
400+
401+
const YGNodeClonedFunc cloneNodeCallback = config_->cloneNodeCallback;
402+
for (uint32_t i = 0; i < childCount; ++i) {
403+
const YGNodeRef oldChild = children_[i];
404+
const YGNodeRef newChild = YGNodeClone(oldChild);
405+
replaceChild(newChild, i);
406+
newChild->setParent(this);
407+
if (cloneNodeCallback) {
408+
cloneNodeCallback(oldChild, newChild, this, i);
409+
}
410+
}
395411
}

‎ReactCommon/yoga/yoga/YGNode.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ struct YGNode {
106106
YGValue resolveFlexBasisPtr() const;
107107
void resolveDimension();
108108
void clearChildren();
109+
/// Replaces the occurrences of oldChild with newChild
110+
void replaceChild(YGNodeRef oldChild, YGNodeRef newChild);
109111
void replaceChild(YGNodeRef child, uint32_t index);
110112
void insertChild(YGNodeRef child, uint32_t index);
111113
/// Removes the first occurrence of child
@@ -117,6 +119,6 @@ struct YGNode {
117119
void setLayoutPadding(float padding, int index);
118120
void setLayoutPosition(float position, int index);
119121

120-
// Static methods
121-
static const YGNode& defaultValue();
122+
// Other methods
123+
void cloneChildrenIfNeeded();
122124
};

‎ReactCommon/yoga/yoga/Yoga.cpp

+5-35
Original file line numberDiff line numberDiff line change
@@ -348,36 +348,6 @@ static void YGNodeMarkDirtyInternal(const YGNodeRef node) {
348348
}
349349
}
350350

351-
static void YGCloneChildrenIfNeeded(const YGNodeRef parent) {
352-
// YGNodeRemoveChild has a forked variant of this algorithm optimized for deletions.
353-
const uint32_t childCount = YGNodeGetChildCount(parent);
354-
if (childCount == 0) {
355-
// This is an empty set. Nothing to clone.
356-
return;
357-
}
358-
359-
const YGNodeRef firstChild = YGNodeGetChild(parent, 0);
360-
if (firstChild->getParent() == parent) {
361-
// If the first child has this node as its parent, we assume that it is already unique.
362-
// We can do this because if we have it has a child, that means that its parent was at some
363-
// point cloned which made that subtree immutable.
364-
// We also assume that all its sibling are cloned as well.
365-
return;
366-
}
367-
368-
const YGNodeClonedFunc cloneNodeCallback =
369-
parent->getConfig()->cloneNodeCallback;
370-
for (uint32_t i = 0; i < childCount; i++) {
371-
const YGNodeRef oldChild = parent->getChild(i);
372-
const YGNodeRef newChild = YGNodeClone(oldChild);
373-
parent->replaceChild(newChild, i);
374-
newChild->setParent(parent);
375-
if (cloneNodeCallback) {
376-
cloneNodeCallback(oldChild, newChild, parent, i);
377-
}
378-
}
379-
}
380-
381351
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
382352
YGAssertWithNode(
383353
node,
@@ -388,14 +358,15 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32
388358
node->getMeasure() == nullptr,
389359
"Cannot add child: Nodes with measure functions cannot have children.");
390360

391-
YGCloneChildrenIfNeeded(node);
361+
node->cloneChildrenIfNeeded();
392362
node->insertChild(child, index);
393363
child->setParent(node);
394364
YGNodeMarkDirtyInternal(node);
395365
}
396366

397367
void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) {
398-
// This algorithm is a forked variant from YGCloneChildrenIfNeeded that excludes a child.
368+
// This algorithm is a forked variant from cloneChildrenIfNeeded in YGNode
369+
// that excludes a child.
399370
const uint32_t childCount = YGNodeGetChildCount(parent);
400371

401372
if (childCount == 0) {
@@ -1805,7 +1776,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node,
18051776
static void YGZeroOutLayoutRecursivly(const YGNodeRef node) {
18061777
memset(&(node->getLayout()), 0, sizeof(YGLayout));
18071778
node->setHasNewLayout(true);
1808-
YGCloneChildrenIfNeeded(node);
1779+
node->cloneChildrenIfNeeded();
18091780
const uint32_t childCount = YGNodeGetChildCount(node);
18101781
for (uint32_t i = 0; i < childCount; i++) {
18111782
const YGNodeRef child = node->getChild(i);
@@ -1993,8 +1964,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
19931964
}
19941965

19951966
// At this point we know we're going to perform work. Ensure that each child has a mutable copy.
1996-
YGCloneChildrenIfNeeded(node);
1997-
1967+
node->cloneChildrenIfNeeded();
19981968
// Reset layout flags, as they could have changed.
19991969
node->setLayoutHadOverflow(false);
20001970

0 commit comments

Comments
 (0)
Please sign in to comment.