Move YGCloneChildrenIfNeeded as a method on `YGNode`
Reviewed By: emilsjolander Differential Revision: D6611155 fbshipit-source-id: 463723a363e0fbd2c7686f65226eca73236bd07e
This commit is contained in:
parent
654d7595fe
commit
28968e2c0b
|
@ -155,6 +155,10 @@ void YGNode::replaceChild(YGNodeRef child, uint32_t index) {
|
|||
children_[index] = child;
|
||||
}
|
||||
|
||||
void YGNode::replaceChild(YGNodeRef oldChild, YGNodeRef newChild) {
|
||||
std::replace(children_.begin(), children_.end(), oldChild, newChild);
|
||||
}
|
||||
|
||||
void YGNode::insertChild(YGNodeRef child, uint32_t index) {
|
||||
children_.insert(children_.begin() + index, child);
|
||||
}
|
||||
|
@ -375,21 +379,33 @@ YGNode::~YGNode() {
|
|||
// deallocate here
|
||||
}
|
||||
|
||||
const YGNode& YGNode::defaultValue() {
|
||||
static const YGNode n = {nullptr,
|
||||
nullptr,
|
||||
true,
|
||||
YGNodeTypeDefault,
|
||||
nullptr,
|
||||
nullptr,
|
||||
gYGNodeStyleDefaults,
|
||||
gYGNodeLayoutDefaults,
|
||||
0,
|
||||
nullptr,
|
||||
YGVector(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
false,
|
||||
{{YGValueUndefined, YGValueUndefined}}};
|
||||
return n;
|
||||
void YGNode::cloneChildrenIfNeeded() {
|
||||
// YGNodeRemoveChild in yoga.cpp has a forked variant of this algorithm
|
||||
// optimized for deletions.
|
||||
|
||||
const uint32_t childCount = children_.size();
|
||||
if (childCount == 0) {
|
||||
// This is an empty set. Nothing to clone.
|
||||
return;
|
||||
}
|
||||
|
||||
const YGNodeRef firstChild = children_.front();
|
||||
if (firstChild->getParent() == this) {
|
||||
// If the first child has this node as its parent, we assume that it is
|
||||
// already unique. We can do this because if we have it has a child, that
|
||||
// means that its parent was at some point cloned which made that subtree
|
||||
// immutable. We also assume that all its sibling are cloned as well.
|
||||
return;
|
||||
}
|
||||
|
||||
const YGNodeClonedFunc cloneNodeCallback = config_->cloneNodeCallback;
|
||||
for (uint32_t i = 0; i < childCount; ++i) {
|
||||
const YGNodeRef oldChild = children_[i];
|
||||
const YGNodeRef newChild = YGNodeClone(oldChild);
|
||||
replaceChild(newChild, i);
|
||||
newChild->setParent(this);
|
||||
if (cloneNodeCallback) {
|
||||
cloneNodeCallback(oldChild, newChild, this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,8 @@ struct YGNode {
|
|||
YGValue resolveFlexBasisPtr() const;
|
||||
void resolveDimension();
|
||||
void clearChildren();
|
||||
/// Replaces the occurrences of oldChild with newChild
|
||||
void replaceChild(YGNodeRef oldChild, YGNodeRef newChild);
|
||||
void replaceChild(YGNodeRef child, uint32_t index);
|
||||
void insertChild(YGNodeRef child, uint32_t index);
|
||||
/// Removes the first occurrence of child
|
||||
|
@ -117,6 +119,6 @@ struct YGNode {
|
|||
void setLayoutPadding(float padding, int index);
|
||||
void setLayoutPosition(float position, int index);
|
||||
|
||||
// Static methods
|
||||
static const YGNode& defaultValue();
|
||||
// Other methods
|
||||
void cloneChildrenIfNeeded();
|
||||
};
|
||||
|
|
|
@ -348,36 +348,6 @@ static void YGNodeMarkDirtyInternal(const YGNodeRef node) {
|
|||
}
|
||||
}
|
||||
|
||||
static void YGCloneChildrenIfNeeded(const YGNodeRef parent) {
|
||||
// YGNodeRemoveChild has a forked variant of this algorithm optimized for deletions.
|
||||
const uint32_t childCount = YGNodeGetChildCount(parent);
|
||||
if (childCount == 0) {
|
||||
// This is an empty set. Nothing to clone.
|
||||
return;
|
||||
}
|
||||
|
||||
const YGNodeRef firstChild = YGNodeGetChild(parent, 0);
|
||||
if (firstChild->getParent() == parent) {
|
||||
// If the first child has this node as its parent, we assume that it is already unique.
|
||||
// We can do this because if we have it has a child, that means that its parent was at some
|
||||
// point cloned which made that subtree immutable.
|
||||
// We also assume that all its sibling are cloned as well.
|
||||
return;
|
||||
}
|
||||
|
||||
const YGNodeClonedFunc cloneNodeCallback =
|
||||
parent->getConfig()->cloneNodeCallback;
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef oldChild = parent->getChild(i);
|
||||
const YGNodeRef newChild = YGNodeClone(oldChild);
|
||||
parent->replaceChild(newChild, i);
|
||||
newChild->setParent(parent);
|
||||
if (cloneNodeCallback) {
|
||||
cloneNodeCallback(oldChild, newChild, parent, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
||||
YGAssertWithNode(
|
||||
node,
|
||||
|
@ -388,14 +358,15 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32
|
|||
node->getMeasure() == nullptr,
|
||||
"Cannot add child: Nodes with measure functions cannot have children.");
|
||||
|
||||
YGCloneChildrenIfNeeded(node);
|
||||
node->cloneChildrenIfNeeded();
|
||||
node->insertChild(child, index);
|
||||
child->setParent(node);
|
||||
YGNodeMarkDirtyInternal(node);
|
||||
}
|
||||
|
||||
void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) {
|
||||
// This algorithm is a forked variant from YGCloneChildrenIfNeeded that excludes a child.
|
||||
// This algorithm is a forked variant from cloneChildrenIfNeeded in YGNode
|
||||
// that excludes a child.
|
||||
const uint32_t childCount = YGNodeGetChildCount(parent);
|
||||
|
||||
if (childCount == 0) {
|
||||
|
@ -1805,7 +1776,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node,
|
|||
static void YGZeroOutLayoutRecursivly(const YGNodeRef node) {
|
||||
memset(&(node->getLayout()), 0, sizeof(YGLayout));
|
||||
node->setHasNewLayout(true);
|
||||
YGCloneChildrenIfNeeded(node);
|
||||
node->cloneChildrenIfNeeded();
|
||||
const uint32_t childCount = YGNodeGetChildCount(node);
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
const YGNodeRef child = node->getChild(i);
|
||||
|
@ -1993,8 +1964,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||
}
|
||||
|
||||
// At this point we know we're going to perform work. Ensure that each child has a mutable copy.
|
||||
YGCloneChildrenIfNeeded(node);
|
||||
|
||||
node->cloneChildrenIfNeeded();
|
||||
// Reset layout flags, as they could have changed.
|
||||
node->setLayoutHadOverflow(false);
|
||||
|
||||
|
|
Loading…
Reference in New Issue