Skip to content

Commit

Permalink
Modify private apis to set, store, and get intrinsic sizing keywords (f…
Browse files Browse the repository at this point in the history
…acebook#1721)

Summary:

X-link: facebook/react-native#46938

The private internals of how we store styles needed to change a bit to support 3 new keyword values. Right now the only other keyword that can be stored is `auto`. As a result there isn't much fancy logic to support storing this and its just stored as a specific type inside of `StyleValueHandle`. There are only 3 bits for types (8 values), so it is not sustainable to just stuff every keyword in there. So the change writes the keyword as a value with a new `keyword` `Type`. 

I chose not to put `auto` in there even though it is a keyword since it is a hot path, I did not want to regress perf when I did not need to.

I also make a new `StyleSizeValue` class to store size values - so values for `width`, `height`, etc. This way these new keywords are kept specific to sizes and we will not be able to create, for example, a margin: `max-content`.

Reviewed By: NickGerleman

Differential Revision: D63927512
  • Loading branch information
joevilches authored and facebook-github-bot committed Nov 1, 2024
1 parent 6fed4df commit cc5c803
Show file tree
Hide file tree
Showing 17 changed files with 317 additions and 54 deletions.
10 changes: 9 additions & 1 deletion enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@

ENUMS = {
"Direction": ["Inherit", "LTR", "RTL"],
"Unit": ["Undefined", "Point", "Percent", "Auto"],
"Unit": [
"Undefined",
"Point",
"Percent",
"Auto",
"MaxContent",
"FitContent",
"Stretch",
],
"FlexDirection": ["Column", "ColumnReverse", "Row", "RowReverse"],
"Justify": [
"FlexStart",
Expand Down
8 changes: 7 additions & 1 deletion java/com/facebook/yoga/YogaUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ public enum YogaUnit {
UNDEFINED(0),
POINT(1),
PERCENT(2),
AUTO(3);
AUTO(3),
MAX_CONTENT(4),
FIT_CONTENT(5),
STRETCH(6);

private final int mIntValue;

Expand All @@ -31,6 +34,9 @@ public static YogaUnit fromInt(int value) {
case 1: return POINT;
case 2: return PERCENT;
case 3: return AUTO;
case 4: return MAX_CONTENT;
case 5: return FIT_CONTENT;
case 6: return STRETCH;
default: throw new IllegalArgumentException("Unknown enum value: " + value);
}
}
Expand Down
6 changes: 6 additions & 0 deletions javascript/src/generated/YGEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ export enum Unit {
Point = 1,
Percent = 2,
Auto = 3,
MaxContent = 4,
FitContent = 5,
Stretch = 6,
}

export enum Wrap {
Expand Down Expand Up @@ -203,6 +206,9 @@ const constants = {
UNIT_POINT: Unit.Point,
UNIT_PERCENT: Unit.Percent,
UNIT_AUTO: Unit.Auto,
UNIT_MAX_CONTENT: Unit.MaxContent,
UNIT_FIT_CONTENT: Unit.FitContent,
UNIT_STRETCH: Unit.Stretch,
WRAP_NO_WRAP: Wrap.NoWrap,
WRAP_WRAP: Wrap.Wrap,
WRAP_WRAP_REVERSE: Wrap.WrapReverse,
Expand Down
15 changes: 15 additions & 0 deletions tests/StyleValuePoolTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,19 @@ TEST(StyleValuePool, store_undefined_after_large_int) {
EXPECT_EQ(pool.getLength(handle), StyleLength::undefined());
}

TEST(StyleValuePool, store_keywords) {
StyleValuePool pool;
StyleValueHandle handleMaxContent;
StyleValueHandle handleFitContent;
StyleValueHandle handleStretch;

pool.store(handleMaxContent, StyleSizeLength::ofMaxContent());
pool.store(handleFitContent, StyleSizeLength::ofFitContent());
pool.store(handleStretch, StyleSizeLength::ofStretch());

EXPECT_EQ(pool.getSize(handleMaxContent), StyleSizeLength::ofMaxContent());
EXPECT_EQ(pool.getSize(handleFitContent), StyleSizeLength::ofFitContent());
EXPECT_EQ(pool.getSize(handleStretch), StyleSizeLength::ofStretch());
}

} // namespace facebook::yoga
6 changes: 6 additions & 0 deletions yoga/YGEnums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,12 @@ const char* YGUnitToString(const YGUnit value) {
return "percent";
case YGUnitAuto:
return "auto";
case YGUnitMaxContent:
return "max-content";
case YGUnitFitContent:
return "fit-content";
case YGUnitStretch:
return "stretch";
}
return "unknown";
}
Expand Down
5 changes: 4 additions & 1 deletion yoga/YGEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ YG_ENUM_DECL(
YGUnitUndefined,
YGUnitPoint,
YGUnitPercent,
YGUnitAuto)
YGUnitAuto,
YGUnitMaxContent,
YGUnitFitContent,
YGUnitStretch)

YG_ENUM_DECL(
YGWrap,
Expand Down
34 changes: 17 additions & 17 deletions yoga/YGNodeStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,19 @@ float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) {

void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) {
updateStyle<&Style::flexBasis, &Style::setFlexBasis>(
node, StyleLength::points(flexBasis));
node, StyleSizeLength::points(flexBasis));
}

void YGNodeStyleSetFlexBasisPercent(
const YGNodeRef node,
const float flexBasisPercent) {
updateStyle<&Style::flexBasis, &Style::setFlexBasis>(
node, StyleLength::percent(flexBasisPercent));
node, StyleSizeLength::percent(flexBasisPercent));
}

void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) {
updateStyle<&Style::flexBasis, &Style::setFlexBasis>(
node, StyleLength::ofAuto());
node, StyleSizeLength::ofAuto());
}

YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) {
Expand Down Expand Up @@ -308,17 +308,17 @@ YGBoxSizing YGNodeStyleGetBoxSizing(const YGNodeConstRef node) {

void YGNodeStyleSetWidth(YGNodeRef node, float points) {
updateStyle<&Style::dimension, &Style::setDimension>(
node, Dimension::Width, StyleLength::points(points));
node, Dimension::Width, StyleSizeLength::points(points));
}

void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) {
updateStyle<&Style::dimension, &Style::setDimension>(
node, Dimension::Width, StyleLength::percent(percent));
node, Dimension::Width, StyleSizeLength::percent(percent));
}

void YGNodeStyleSetWidthAuto(YGNodeRef node) {
updateStyle<&Style::dimension, &Style::setDimension>(
node, Dimension::Width, StyleLength::ofAuto());
node, Dimension::Width, StyleSizeLength::ofAuto());
}

YGValue YGNodeStyleGetWidth(YGNodeConstRef node) {
Expand All @@ -327,17 +327,17 @@ YGValue YGNodeStyleGetWidth(YGNodeConstRef node) {

void YGNodeStyleSetHeight(YGNodeRef node, float points) {
updateStyle<&Style::dimension, &Style::setDimension>(
node, Dimension::Height, StyleLength::points(points));
node, Dimension::Height, StyleSizeLength::points(points));
}

void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) {
updateStyle<&Style::dimension, &Style::setDimension>(
node, Dimension::Height, StyleLength::percent(percent));
node, Dimension::Height, StyleSizeLength::percent(percent));
}

void YGNodeStyleSetHeightAuto(YGNodeRef node) {
updateStyle<&Style::dimension, &Style::setDimension>(
node, Dimension::Height, StyleLength::ofAuto());
node, Dimension::Height, StyleSizeLength::ofAuto());
}

YGValue YGNodeStyleGetHeight(YGNodeConstRef node) {
Expand All @@ -346,12 +346,12 @@ YGValue YGNodeStyleGetHeight(YGNodeConstRef node) {

void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) {
updateStyle<&Style::minDimension, &Style::setMinDimension>(
node, Dimension::Width, StyleLength::points(minWidth));
node, Dimension::Width, StyleSizeLength::points(minWidth));
}

void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) {
updateStyle<&Style::minDimension, &Style::setMinDimension>(
node, Dimension::Width, StyleLength::percent(minWidth));
node, Dimension::Width, StyleSizeLength::percent(minWidth));
}

YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) {
Expand All @@ -360,14 +360,14 @@ YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) {

void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) {
updateStyle<&Style::minDimension, &Style::setMinDimension>(
node, Dimension::Height, StyleLength::points(minHeight));
node, Dimension::Height, StyleSizeLength::points(minHeight));
}

void YGNodeStyleSetMinHeightPercent(
const YGNodeRef node,
const float minHeight) {
updateStyle<&Style::minDimension, &Style::setMinDimension>(
node, Dimension::Height, StyleLength::percent(minHeight));
node, Dimension::Height, StyleSizeLength::percent(minHeight));
}

YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) {
Expand All @@ -376,12 +376,12 @@ YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) {

void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) {
updateStyle<&Style::maxDimension, &Style::setMaxDimension>(
node, Dimension::Width, StyleLength::points(maxWidth));
node, Dimension::Width, StyleSizeLength::points(maxWidth));
}

void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) {
updateStyle<&Style::maxDimension, &Style::setMaxDimension>(
node, Dimension::Width, StyleLength::percent(maxWidth));
node, Dimension::Width, StyleSizeLength::percent(maxWidth));
}

YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) {
Expand All @@ -390,14 +390,14 @@ YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) {

void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) {
updateStyle<&Style::maxDimension, &Style::setMaxDimension>(
node, Dimension::Height, StyleLength::points(maxHeight));
node, Dimension::Height, StyleSizeLength::points(maxHeight));
}

void YGNodeStyleSetMaxHeightPercent(
const YGNodeRef node,
const float maxHeight) {
updateStyle<&Style::maxDimension, &Style::setMaxDimension>(
node, Dimension::Height, StyleLength::percent(maxHeight));
node, Dimension::Height, StyleSizeLength::percent(maxHeight));
}

YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) {
Expand Down
3 changes: 3 additions & 0 deletions yoga/YGValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ inline bool operator==(const YGValue& lhs, const YGValue& rhs) {
switch (lhs.unit) {
case YGUnitUndefined:
case YGUnitAuto:
case YGUnitFitContent:
case YGUnitMaxContent:
case YGUnitStretch:
return true;
case YGUnitPoint:
case YGUnitPercent:
Expand Down
2 changes: 1 addition & 1 deletion yoga/algorithm/CalculateLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ static float distributeFreeSpaceSecondPass(
marginCross;
const bool isLoosePercentageMeasurement =
currentLineChild->getProcessedDimension(dimension(crossAxis))
.unit() == Unit::Percent &&
.isPercent() &&
sizingModeCrossDim != SizingMode::StretchFit;
childCrossSizingMode =
yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement
Expand Down
5 changes: 4 additions & 1 deletion yoga/enums/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ enum class Unit : uint8_t {
Point = YGUnitPoint,
Percent = YGUnitPercent,
Auto = YGUnitAuto,
MaxContent = YGUnitMaxContent,
FitContent = YGUnitFitContent,
Stretch = YGUnitStretch,
};

template <>
constexpr int32_t ordinalCount<Unit>() {
return 4;
return 7;
}

constexpr Unit scopedEnum(YGUnit unscoped) {
Expand Down
12 changes: 6 additions & 6 deletions yoga/node/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,16 +314,16 @@ void Node::setPosition(
crossAxisTrailingEdge);
}

Style::Length Node::processFlexBasis() const {
Style::Length flexBasis = style_.flexBasis();
if (flexBasis.unit() != Unit::Auto && flexBasis.unit() != Unit::Undefined) {
Style::SizeLength Node::processFlexBasis() const {
Style::SizeLength flexBasis = style_.flexBasis();
if (!flexBasis.isAuto() && !flexBasis.isUndefined()) {
return flexBasis;
}
if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0f) {
return config_->useWebDefaults() ? StyleLength::ofAuto()
: StyleLength::points(0);
return config_->useWebDefaults() ? StyleSizeLength::ofAuto()
: StyleSizeLength::points(0);
}
return StyleLength::ofAuto();
return StyleSizeLength::ofAuto();
}

FloatOptional Node::resolveFlexBasis(
Expand Down
8 changes: 4 additions & 4 deletions yoga/node/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class YG_EXPORT Node : public ::YGNode {
return isDirty_;
}

Style::Length getProcessedDimension(Dimension dimension) const {
Style::SizeLength getProcessedDimension(Dimension dimension) const {
return processedDimensions_[static_cast<size_t>(dimension)];
}

Expand Down Expand Up @@ -268,7 +268,7 @@ class YG_EXPORT Node : public ::YGNode {
void setPosition(Direction direction, float ownerWidth, float ownerHeight);

// Other methods
Style::Length processFlexBasis() const;
Style::SizeLength processFlexBasis() const;
FloatOptional resolveFlexBasis(
Direction direction,
FlexDirection flexDirection,
Expand Down Expand Up @@ -322,8 +322,8 @@ class YG_EXPORT Node : public ::YGNode {
Node* owner_ = nullptr;
std::vector<Node*> children_;
const Config* config_;
std::array<Style::Length, 2> processedDimensions_{
{StyleLength::undefined(), StyleLength::undefined()}};
std::array<Style::SizeLength, 2> processedDimensions_{
{StyleSizeLength::undefined(), StyleSizeLength::undefined()}};
};

inline Node* resolveRef(const YGNodeRef ref) {
Expand Down
26 changes: 14 additions & 12 deletions yoga/style/Style.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
#include <yoga/enums/Wrap.h>
#include <yoga/numeric/FloatOptional.h>
#include <yoga/style/StyleLength.h>
#include <yoga/style/StyleSizeLength.h>
#include <yoga/style/StyleValuePool.h>

namespace facebook::yoga {

class YG_EXPORT Style {
public:
using Length = StyleLength;
using SizeLength = StyleSizeLength;

static constexpr float DefaultFlexGrow = 0.0f;
static constexpr float DefaultFlexShrink = 0.0f;
Expand Down Expand Up @@ -133,10 +135,10 @@ class YG_EXPORT Style {
pool_.store(flexShrink_, value);
}

Style::Length flexBasis() const {
return pool_.getLength(flexBasis_);
Style::SizeLength flexBasis() const {
return pool_.getSize(flexBasis_);
}
void setFlexBasis(Style::Length value) {
void setFlexBasis(Style::SizeLength value) {
pool_.store(flexBasis_, value);
}

Expand Down Expand Up @@ -175,17 +177,17 @@ class YG_EXPORT Style {
pool_.store(gap_[yoga::to_underlying(gutter)], value);
}

Style::Length dimension(Dimension axis) const {
return pool_.getLength(dimensions_[yoga::to_underlying(axis)]);
Style::SizeLength dimension(Dimension axis) const {
return pool_.getSize(dimensions_[yoga::to_underlying(axis)]);
}
void setDimension(Dimension axis, Style::Length value) {
void setDimension(Dimension axis, Style::SizeLength value) {
pool_.store(dimensions_[yoga::to_underlying(axis)], value);
}

Style::Length minDimension(Dimension axis) const {
return pool_.getLength(minDimensions_[yoga::to_underlying(axis)]);
Style::SizeLength minDimension(Dimension axis) const {
return pool_.getSize(minDimensions_[yoga::to_underlying(axis)]);
}
void setMinDimension(Dimension axis, Style::Length value) {
void setMinDimension(Dimension axis, Style::SizeLength value) {
pool_.store(minDimensions_[yoga::to_underlying(axis)], value);
}

Expand All @@ -207,10 +209,10 @@ class YG_EXPORT Style {
: FloatOptional{0.0});
}

Style::Length maxDimension(Dimension axis) const {
return pool_.getLength(maxDimensions_[yoga::to_underlying(axis)]);
Style::SizeLength maxDimension(Dimension axis) const {
return pool_.getSize(maxDimensions_[yoga::to_underlying(axis)]);
}
void setMaxDimension(Dimension axis, Style::Length value) {
void setMaxDimension(Dimension axis, Style::SizeLength value) {
pool_.store(maxDimensions_[yoga::to_underlying(axis)], value);
}

Expand Down
Loading

0 comments on commit cc5c803

Please sign in to comment.