Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions yoga/YGNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,17 @@ void YGNode::setNextChild(YGNodeRef nextChild) {

void YGNode::replaceChild(YGNodeRef child, uint32_t index) {
children_[index] = child;
setChildRoot(child);
}

void YGNode::replaceChild(YGNodeRef oldChild, YGNodeRef newChild) {
std::replace(children_.begin(), children_.end(), oldChild, newChild);
setChildRoot(newChild);
}

void YGNode::insertChild(YGNodeRef child, uint32_t index) {
children_.insert(children_.begin() + index, child);
setChildRoot(child);
}

void YGNode::setConfig(YGConfigRef config) {
Expand Down Expand Up @@ -770,3 +773,15 @@ bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const {
}
return isLayoutTreeEqual;
}

YGNodeRef YGNode::getRoot() {
if (pRoot == nullptr) pRoot = this;
return pRoot;
}

void YGNode::setChildRoot(YGNodeRef node) {
node->pRoot = getRoot();
for (auto child: node->children_) {
setChildRoot(child);
}
}
9 changes: 9 additions & 0 deletions yoga/YGNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,13 @@ struct YGNode {
bool isNodeFlexible();
bool didUseLegacyFlag();
bool isLayoutTreeEqualToNode(const YGNode& node) const;

private:
YGNodeRef pRoot = nullptr;

public:
uint32_t gCurrentGenerationCount = 0;
uint32_t gDepth = 0;
YGNodeRef getRoot();
void setChildRoot(YGNodeRef node);
};
40 changes: 19 additions & 21 deletions yoga/Yoga.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "YGNode.h"
#include "YGNodePrint.h"
#include "Yoga-internal.h"
#include <atomic>
#ifdef _MSC_VER
#include <float.h>

Expand Down Expand Up @@ -212,8 +213,8 @@ void YGNodeMarkDirtyAndPropogateToDescendants(const YGNodeRef node) {
return node->markDirtyAndPropogateDownwards();
}

int32_t gNodeInstanceCount = 0;
int32_t gConfigInstanceCount = 0;
std::atomic<int32_t> gNodeInstanceCount(0);
std::atomic<int32_t> gConfigInstanceCount(0);

WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
const YGNodeRef node = new YGNode();
Expand Down Expand Up @@ -244,6 +245,7 @@ YGNodeRef YGNodeClone(YGNodeRef oldNode) {
oldNode->getConfig(),
node != nullptr,
"Could not allocate memory for node");
oldNode->setChildRoot(node);
gNodeInstanceCount++;
node->setOwner(nullptr);
return node;
Expand Down Expand Up @@ -301,8 +303,8 @@ void YGNodeFree(const YGNodeRef node) {

static void YGConfigFreeRecursive(const YGNodeRef root) {
if (root->getConfig() != nullptr) {
gConfigInstanceCount--;
delete root->getConfig();
gConfigInstanceCount--;
}
// Delete configs recursively for childrens
for (uint32_t i = 0; i < root->getChildrenCount(); ++i) {
Expand Down Expand Up @@ -960,8 +962,6 @@ bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node) {
return node->getLayout().doesLegacyStretchFlagAffectsLayout;
}

uint32_t gCurrentGenerationCount = 0;

bool YGLayoutNodeInternal(const YGNodeRef node,
const float availableWidth,
const float availableHeight,
Expand Down Expand Up @@ -1220,8 +1220,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (child->getLayout().computedFlexBasis.isUndefined() ||
(YGConfigIsExperimentalFeatureEnabled(
child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
child->getLayout().computedFlexBasisGeneration !=
gCurrentGenerationCount)) {
child->getLayout().computedFlexBasisGeneration != node->getRoot()->gCurrentGenerationCount)) {
const YGFloatOptional& paddingAndBorder = YGFloatOptional(
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
child->setLayoutComputedFlexBasis(
Expand Down Expand Up @@ -1361,7 +1360,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
child->getLayout().measuredDimensions[dim[mainAxis]],
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth))));
}
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount);
child->setLayoutComputedFlexBasisGeneration(node->getRoot()->gCurrentGenerationCount);
}

static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
Expand Down Expand Up @@ -1827,7 +1826,7 @@ static void YGNodeComputeFlexBasisForChildren(
continue;
}
if (child == singleFlexChild) {
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount);
child->setLayoutComputedFlexBasisGeneration(node->getRoot()->gCurrentGenerationCount);
child->setLayoutComputedFlexBasis(YGFloatOptional(0));
} else {
YGNodeComputeFlexBasisForChild(
Expand Down Expand Up @@ -3344,7 +3343,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
}
}

uint32_t gDepth = 0;
bool gPrintTree = false;
bool gPrintChanges = false;
bool gPrintSkips = false;
Expand Down Expand Up @@ -3515,10 +3513,10 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
const YGConfigRef config) {
YGLayout* layout = &node->getLayout();

gDepth++;
node->getRoot()->gDepth++;

const bool needToVisitNode =
(node->isDirty() && layout->generationCount != gCurrentGenerationCount) ||
(node->isDirty() && layout->generationCount != node->getRoot()->gCurrentGenerationCount) ||
layout->lastOwnerDirection != ownerDirection;

if (needToVisitNode) {
Expand Down Expand Up @@ -3610,7 +3608,7 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
layout->measuredDimensions[YGDimensionHeight] = cachedResults->computedHeight;

if (gPrintChanges && gPrintSkips) {
YGLog(node, YGLogLevelVerbose, "%s%d.{[skipped] ", YGSpacer(gDepth), gDepth);
YGLog(node, YGLogLevelVerbose, "%s%d.{[skipped] ", YGSpacer(node->getRoot()->gDepth), node->getRoot()->gDepth);
if (node->getPrintFunc() != nullptr) {
node->getPrintFunc()(node);
}
Expand All @@ -3632,8 +3630,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
node,
YGLogLevelVerbose,
"%s%d.{%s",
YGSpacer(gDepth),
gDepth,
YGSpacer(node->getRoot()->gDepth),
node->getRoot()->gDepth,
needToVisitNode ? "*" : "");
if (node->getPrintFunc() != nullptr) {
node->getPrintFunc()(node);
Expand Down Expand Up @@ -3665,8 +3663,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
node,
YGLogLevelVerbose,
"%s%d.}%s",
YGSpacer(gDepth),
gDepth,
YGSpacer(node->getRoot()->gDepth),
node->getRoot()->gDepth,
needToVisitNode ? "*" : "");
if (node->getPrintFunc() != nullptr) {
node->getPrintFunc()(node);
Expand Down Expand Up @@ -3723,8 +3721,8 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
node->setDirty(false);
}

gDepth--;
layout->generationCount = gCurrentGenerationCount;
node->getRoot()->gDepth--;
layout->generationCount = node->getRoot()->gCurrentGenerationCount;
return (needToVisitNode || cachedResults == nullptr);
}

Expand Down Expand Up @@ -3820,7 +3818,7 @@ void YGNodeCalculateLayout(
// all dirty nodes at least once. Subsequent visits will be skipped if the
// input
// parameters don't change.
gCurrentGenerationCount++;
node->getRoot()->gCurrentGenerationCount++;
node->resolveDimension();
float width = YGUndefined;
YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
Expand Down Expand Up @@ -3900,7 +3898,7 @@ void YGNodeCalculateLayout(
originalNode->resolveDimension();
// Recursively mark nodes as dirty
originalNode->markDirtyAndPropogateDownwards();
gCurrentGenerationCount++;
node->getRoot()->gCurrentGenerationCount++;
// Rerun the layout, and calculate the diff
originalNode->setAndPropogateUseLegacyFlag(false);
if (YGLayoutNodeInternal(
Expand Down