Use vector instead of linked list

Reviewed By: emilsjolander

Differential Revision: D6722959

fbshipit-source-id: 4e81176802b9a9319bc5f385c824a06be14a83a2
This commit is contained in:
Pritesh Nandgaonkar 2018-01-16 09:31:21 -08:00 committed by Facebook Github Bot
parent b3a306a667
commit d0f7d4d107

View File

@ -1782,9 +1782,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
const float mainAxisParentSize = isMainAxisRow ? parentWidth : parentHeight; const float mainAxisParentSize = isMainAxisRow ? parentWidth : parentHeight;
const float crossAxisParentSize = isMainAxisRow ? parentHeight : parentWidth; const float crossAxisParentSize = isMainAxisRow ? parentHeight : parentWidth;
YGNodeRef firstAbsoluteChild = nullptr;
YGNodeRef currentAbsoluteChild = nullptr;
const float leadingPaddingAndBorderMain = const float leadingPaddingAndBorderMain =
node->getLeadingPaddingAndBorder(mainAxis, parentWidth); node->getLeadingPaddingAndBorder(mainAxis, parentWidth);
const float trailingPaddingAndBorderMain = const float trailingPaddingAndBorderMain =
@ -1822,27 +1819,10 @@ static void YGNodelayoutImpl(const YGNodeRef node,
YGResolveValue( YGResolveValue(
node->getStyle().maxDimensions[YGDimensionHeight], parentHeight) - node->getStyle().maxDimensions[YGDimensionHeight], parentHeight) -
paddingAndBorderAxisColumn; paddingAndBorderAxisColumn;
const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight; const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight;
const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight; const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight;
// Make a private linkedlist of absolutely positioned child
for (auto child : node->getChildren()) {
// Absolute-positioned children don't participate in flex layout. Add them
// to a list that we can process later.
if (child->getStyle().positionType == YGPositionTypeAbsolute) {
// Store a private linked list of absolutely positioned children
// so that we can efficiently traverse them later.
if (firstAbsoluteChild == nullptr) {
firstAbsoluteChild = child;
}
if (currentAbsoluteChild != nullptr) {
currentAbsoluteChild->setNextChild(child);
}
currentAbsoluteChild = child;
child->setNextChild(nullptr);
}
}
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
float availableInnerWidth = YGNodeCalculateAvailableInnerDim( float availableInnerWidth = YGNodeCalculateAvailableInnerDim(
@ -1909,37 +1889,32 @@ static void YGNodelayoutImpl(const YGNodeRef node,
float totalFlexGrowFactors = 0; float totalFlexGrowFactors = 0;
float totalFlexShrinkScaledFactors = 0; float totalFlexShrinkScaledFactors = 0;
// Maintain a linked list of the child nodes that can shrink and/or grow. // Maintain a vector of the child nodes that can shrink and/or grow.
YGNodeRef firstRelativeChild = nullptr; std::vector<YGNodeRef> relativeChildren;
YGNodeRef currentRelativeChild = nullptr;
// Add items to the current line until it's full or we run out of items. // Add items to the current line until it's full or we run out of items.
for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) { for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) {
const YGNodeRef child = node->getChild(i); const YGNodeRef child = node->getChild(i);
if (child->getStyle().display == YGDisplayNone) { if (child->getStyle().display == YGDisplayNone ||
child->getStyle().positionType == YGPositionTypeAbsolute) {
continue; continue;
} }
child->setLineIndex(lineCount); child->setLineIndex(lineCount);
const float childMarginMainAxis =
if (child->getStyle().positionType != YGPositionTypeAbsolute) { YGNodeMarginForAxis(child, mainAxis, availableInnerWidth);
const float childMarginMainAxis = YGNodeMarginForAxis(child, mainAxis, availableInnerWidth); const float flexBasisWithMinAndMaxConstraints =
const float flexBasisWithMaxConstraints = fminf( YGNodeBoundAxisWithinMinAndMax(
YGResolveValue( child,
child->getStyle().maxDimensions[dim[mainAxis]], mainAxis,
mainAxisParentSize), child->getLayout().computedFlexBasis,
child->getLayout().computedFlexBasis); mainAxisParentSize);
const float flexBasisWithMinAndMaxConstraints = fmaxf(
YGResolveValue(
child->getStyle().minDimensions[dim[mainAxis]],
mainAxisParentSize),
flexBasisWithMaxConstraints);
// If this is a multi-line flow and this item pushes us over the // If this is a multi-line flow and this item pushes us over the
// available size, we've // available size, we've
// hit the end of the current line. Break out of the loop and lay out // hit the end of the current line. Break out of the loop and lay out
// the current line. // the current line.
if (sizeConsumedOnCurrentLineIncludingMinConstraint + flexBasisWithMinAndMaxConstraints + if (sizeConsumedOnCurrentLineIncludingMinConstraint +
childMarginMainAxis > flexBasisWithMinAndMaxConstraints + childMarginMainAxis >
availableInnerMainDim && availableInnerMainDim &&
isNodeFlexWrap && itemsOnLine > 0) { isNodeFlexWrap && itemsOnLine > 0) {
break; break;
@ -1947,27 +1922,21 @@ static void YGNodelayoutImpl(const YGNodeRef node,
sizeConsumedOnCurrentLineIncludingMinConstraint += sizeConsumedOnCurrentLineIncludingMinConstraint +=
flexBasisWithMinAndMaxConstraints + childMarginMainAxis; flexBasisWithMinAndMaxConstraints + childMarginMainAxis;
sizeConsumedOnCurrentLine += flexBasisWithMinAndMaxConstraints + childMarginMainAxis; sizeConsumedOnCurrentLine +=
flexBasisWithMinAndMaxConstraints + childMarginMainAxis;
itemsOnLine++; itemsOnLine++;
if (child->isNodeFlexible()) { if (child->isNodeFlexible()) {
totalFlexGrowFactors += child->resolveFlexGrow(); totalFlexGrowFactors += child->resolveFlexGrow();
// Unlike the grow factor, the shrink factor is scaled relative to the child dimension. // Unlike the grow factor, the shrink factor is scaled relative to the
totalFlexShrinkScaledFactors += -child->resolveFlexShrink() * // child dimension.
child->getLayout().computedFlexBasis; totalFlexShrinkScaledFactors +=
-child->resolveFlexShrink() * child->getLayout().computedFlexBasis;
} }
// Store a private linked list of children that need to be layed out. // Store a private linked list of children that need to be layed out.
if (firstRelativeChild == nullptr) { relativeChildren.push_back(child);
firstRelativeChild = child;
}
if (currentRelativeChild != nullptr) {
currentRelativeChild->setNextChild(child);
}
currentRelativeChild = child;
child->setNextChild(nullptr);
}
} }
// The total flex factor needs to be floored to 1. // The total flex factor needs to be floored to 1.
@ -2060,18 +2029,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// First pass: detect the flex items whose min/max constraints trigger // First pass: detect the flex items whose min/max constraints trigger
float deltaFlexShrinkScaledFactors = 0; float deltaFlexShrinkScaledFactors = 0;
float deltaFlexGrowFactors = 0; float deltaFlexGrowFactors = 0;
currentRelativeChild = firstRelativeChild;
while (currentRelativeChild != nullptr) { for (auto currentRelativeChild : relativeChildren) {
childFlexBasis = fminf( childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
YGResolveValue( currentRelativeChild,
currentRelativeChild->getStyle().maxDimensions[dim[mainAxis]], mainAxis,
mainAxisParentSize), currentRelativeChild->getLayout().computedFlexBasis,
fmaxf( mainAxisParentSize);
YGResolveValue(
currentRelativeChild->getStyle()
.minDimensions[dim[mainAxis]],
mainAxisParentSize),
currentRelativeChild->getLayout().computedFlexBasis));
if (remainingFreeSpace < 0) { if (remainingFreeSpace < 0) {
flexShrinkScaledFactor = flexShrinkScaledFactor =
@ -2079,10 +2043,11 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Is this child able to shrink? // Is this child able to shrink?
if (flexShrinkScaledFactor != 0) { if (flexShrinkScaledFactor != 0) {
baseMainSize = baseMainSize = childFlexBasis +
childFlexBasis + remainingFreeSpace / totalFlexShrinkScaledFactors *
remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; flexShrinkScaledFactor;
boundMainSize = YGNodeBoundAxis(currentRelativeChild, boundMainSize = YGNodeBoundAxis(
currentRelativeChild,
mainAxis, mainAxis,
baseMainSize, baseMainSize,
availableInnerMainDim, availableInnerMainDim,
@ -2103,9 +2068,10 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Is this child able to grow? // Is this child able to grow?
if (flexGrowFactor != 0) { if (flexGrowFactor != 0) {
baseMainSize = baseMainSize = childFlexBasis +
childFlexBasis + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor;
boundMainSize = YGNodeBoundAxis(currentRelativeChild, boundMainSize = YGNodeBoundAxis(
currentRelativeChild,
mainAxis, mainAxis,
baseMainSize, baseMainSize,
availableInnerMainDim, availableInnerMainDim,
@ -2133,18 +2099,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Second pass: resolve the sizes of the flexible items // Second pass: resolve the sizes of the flexible items
deltaFreeSpace = 0; deltaFreeSpace = 0;
currentRelativeChild = firstRelativeChild; for (auto currentRelativeChild : relativeChildren) {
while (currentRelativeChild != nullptr) { childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
childFlexBasis = fminf( currentRelativeChild,
YGResolveValue( mainAxis,
currentRelativeChild->getStyle().maxDimensions[dim[mainAxis]], currentRelativeChild->getLayout().computedFlexBasis,
mainAxisParentSize), mainAxisParentSize);
fmaxf(
YGResolveValue(
currentRelativeChild->getStyle()
.minDimensions[dim[mainAxis]],
mainAxisParentSize),
currentRelativeChild->getLayout().computedFlexBasis));
float updatedMainSize = childFlexBasis; float updatedMainSize = childFlexBasis;
if (remainingFreeSpace < 0) { if (remainingFreeSpace < 0) {
@ -2157,12 +2117,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (totalFlexShrinkScaledFactors == 0) { if (totalFlexShrinkScaledFactors == 0) {
childSize = childFlexBasis + flexShrinkScaledFactor; childSize = childFlexBasis + flexShrinkScaledFactor;
} else { } else {
childSize = childSize = childFlexBasis +
childFlexBasis + (remainingFreeSpace / totalFlexShrinkScaledFactors) *
(remainingFreeSpace / totalFlexShrinkScaledFactors) * flexShrinkScaledFactor; flexShrinkScaledFactor;
} }
updatedMainSize = YGNodeBoundAxis(currentRelativeChild, updatedMainSize = YGNodeBoundAxis(
currentRelativeChild,
mainAxis, mainAxis,
childSize, childSize,
availableInnerMainDim, availableInnerMainDim,
@ -2173,8 +2134,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Is this child able to grow? // Is this child able to grow?
if (flexGrowFactor != 0) { if (flexGrowFactor != 0) {
updatedMainSize = updatedMainSize = YGNodeBoundAxis(
YGNodeBoundAxis(currentRelativeChild, currentRelativeChild,
mainAxis, mainAxis,
childFlexBasis + childFlexBasis +
remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor, remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor,
@ -2185,10 +2146,10 @@ static void YGNodelayoutImpl(const YGNodeRef node,
deltaFreeSpace -= updatedMainSize - childFlexBasis; deltaFreeSpace -= updatedMainSize - childFlexBasis;
const float marginMain = const float marginMain = YGNodeMarginForAxis(
YGNodeMarginForAxis(currentRelativeChild, mainAxis, availableInnerWidth); currentRelativeChild, mainAxis, availableInnerWidth);
const float marginCross = const float marginCross = YGNodeMarginForAxis(
YGNodeMarginForAxis(currentRelativeChild, crossAxis, availableInnerWidth); currentRelativeChild, crossAxis, availableInnerWidth);
float childCrossSize; float childCrossSize;
float childMainSize = updatedMainSize + marginMain; float childMainSize = updatedMainSize + marginMain;
@ -2216,12 +2177,14 @@ static void YGNodelayoutImpl(const YGNodeRef node,
YGUnitAuto) { YGUnitAuto) {
childCrossSize = availableInnerCrossDim; childCrossSize = availableInnerCrossDim;
childCrossMeasureMode = YGMeasureModeExactly; childCrossMeasureMode = YGMeasureModeExactly;
} else if (!YGNodeIsStyleDimDefined(currentRelativeChild, } else if (!YGNodeIsStyleDimDefined(
currentRelativeChild,
crossAxis, crossAxis,
availableInnerCrossDim)) { availableInnerCrossDim)) {
childCrossSize = availableInnerCrossDim; childCrossSize = availableInnerCrossDim;
childCrossMeasureMode = childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
YGFloatIsUndefined(childCrossSize) ? YGMeasureModeUndefined : YGMeasureModeAtMost; ? YGMeasureModeUndefined
: YGMeasureModeAtMost;
} else { } else {
childCrossSize = childCrossSize =
YGResolveValue( YGResolveValue(
@ -2263,7 +2226,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
YGUnitAuto; YGUnitAuto;
const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; const float childHeight =
!isMainAxisRow ? childMainSize : childCrossSize;
const YGMeasureMode childWidthMeasureMode = const YGMeasureMode childWidthMeasureMode =
isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode; isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
@ -2272,7 +2236,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Recursively call the layout algorithm for this child with the updated // Recursively call the layout algorithm for this child with the updated
// main size. // main size.
YGLayoutNodeInternal(currentRelativeChild, YGLayoutNodeInternal(
currentRelativeChild,
childWidth, childWidth,
childHeight, childHeight,
direction, direction,
@ -2866,11 +2831,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (performLayout) { if (performLayout) {
// STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN
for (currentAbsoluteChild = firstAbsoluteChild; for (auto child : node->getChildren()) {
currentAbsoluteChild != nullptr; if (child->getStyle().positionType != YGPositionTypeAbsolute) {
currentAbsoluteChild = currentAbsoluteChild->getNextChild()) { continue;
YGNodeAbsoluteLayoutChild(node, }
currentAbsoluteChild, YGNodeAbsoluteLayoutChild(
node,
child,
availableInnerWidth, availableInnerWidth,
isMainAxisRow ? measureModeMainDim : measureModeCrossDim, isMainAxisRow ? measureModeMainDim : measureModeCrossDim,
availableInnerHeight, availableInnerHeight,