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;
|
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) {
|
void YGNode::insertChild(YGNodeRef child, uint32_t index) {
|
||||||
children_.insert(children_.begin() + index, child);
|
children_.insert(children_.begin() + index, child);
|
||||||
}
|
}
|
||||||
|
@ -375,21 +379,33 @@ YGNode::~YGNode() {
|
||||||
// deallocate here
|
// deallocate here
|
||||||
}
|
}
|
||||||
|
|
||||||
const YGNode& YGNode::defaultValue() {
|
void YGNode::cloneChildrenIfNeeded() {
|
||||||
static const YGNode n = {nullptr,
|
// YGNodeRemoveChild in yoga.cpp has a forked variant of this algorithm
|
||||||
nullptr,
|
// optimized for deletions.
|
||||||
true,
|
|
||||||
YGNodeTypeDefault,
|
const uint32_t childCount = children_.size();
|
||||||
nullptr,
|
if (childCount == 0) {
|
||||||
nullptr,
|
// This is an empty set. Nothing to clone.
|
||||||
gYGNodeStyleDefaults,
|
return;
|
||||||
gYGNodeLayoutDefaults,
|
}
|
||||||
0,
|
|
||||||
nullptr,
|
const YGNodeRef firstChild = children_.front();
|
||||||
YGVector(),
|
if (firstChild->getParent() == this) {
|
||||||
nullptr,
|
// If the first child has this node as its parent, we assume that it is
|
||||||
nullptr,
|
// already unique. We can do this because if we have it has a child, that
|
||||||
false,
|
// means that its parent was at some point cloned which made that subtree
|
||||||
{{YGValueUndefined, YGValueUndefined}}};
|
// immutable. We also assume that all its sibling are cloned as well.
|
||||||
return n;
|
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;
|
YGValue resolveFlexBasisPtr() const;
|
||||||
void resolveDimension();
|
void resolveDimension();
|
||||||
void clearChildren();
|
void clearChildren();
|
||||||
|
/// Replaces the occurrences of oldChild with newChild
|
||||||
|
void replaceChild(YGNodeRef oldChild, YGNodeRef newChild);
|
||||||
void replaceChild(YGNodeRef child, uint32_t index);
|
void replaceChild(YGNodeRef child, uint32_t index);
|
||||||
void insertChild(YGNodeRef child, uint32_t index);
|
void insertChild(YGNodeRef child, uint32_t index);
|
||||||
/// Removes the first occurrence of child
|
/// Removes the first occurrence of child
|
||||||
|
@ -117,6 +119,6 @@ struct YGNode {
|
||||||
void setLayoutPadding(float padding, int index);
|
void setLayoutPadding(float padding, int index);
|
||||||
void setLayoutPosition(float position, int index);
|
void setLayoutPosition(float position, int index);
|
||||||
|
|
||||||
// Static methods
|
// Other methods
|
||||||
static const YGNode& defaultValue();
|
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) {
|
void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) {
|
||||||
YGAssertWithNode(
|
YGAssertWithNode(
|
||||||
node,
|
node,
|
||||||
|
@ -388,14 +358,15 @@ void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32
|
||||||
node->getMeasure() == nullptr,
|
node->getMeasure() == nullptr,
|
||||||
"Cannot add child: Nodes with measure functions cannot have children.");
|
"Cannot add child: Nodes with measure functions cannot have children.");
|
||||||
|
|
||||||
YGCloneChildrenIfNeeded(node);
|
node->cloneChildrenIfNeeded();
|
||||||
node->insertChild(child, index);
|
node->insertChild(child, index);
|
||||||
child->setParent(node);
|
child->setParent(node);
|
||||||
YGNodeMarkDirtyInternal(node);
|
YGNodeMarkDirtyInternal(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void YGNodeRemoveChild(const YGNodeRef parent, const YGNodeRef excludedChild) {
|
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);
|
const uint32_t childCount = YGNodeGetChildCount(parent);
|
||||||
|
|
||||||
if (childCount == 0) {
|
if (childCount == 0) {
|
||||||
|
@ -1805,7 +1776,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node,
|
||||||
static void YGZeroOutLayoutRecursivly(const YGNodeRef node) {
|
static void YGZeroOutLayoutRecursivly(const YGNodeRef node) {
|
||||||
memset(&(node->getLayout()), 0, sizeof(YGLayout));
|
memset(&(node->getLayout()), 0, sizeof(YGLayout));
|
||||||
node->setHasNewLayout(true);
|
node->setHasNewLayout(true);
|
||||||
YGCloneChildrenIfNeeded(node);
|
node->cloneChildrenIfNeeded();
|
||||||
const uint32_t childCount = YGNodeGetChildCount(node);
|
const uint32_t childCount = YGNodeGetChildCount(node);
|
||||||
for (uint32_t i = 0; i < childCount; i++) {
|
for (uint32_t i = 0; i < childCount; i++) {
|
||||||
const YGNodeRef child = node->getChild(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.
|
// 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.
|
// Reset layout flags, as they could have changed.
|
||||||
node->setLayoutHadOverflow(false);
|
node->setLayoutHadOverflow(false);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue