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#46938)

Summary:
X-link: facebook/yoga#1721


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`.

Differential Revision: D63927512
  • Loading branch information
joevilches authored and facebook-github-bot committed Oct 10, 2024
1 parent 1459d80 commit fbeb2e0
Show file tree
Hide file tree
Showing 17 changed files with 374 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ - (void)setUp
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(200));
return sharedProps;
})
.children({
Expand All @@ -136,8 +136,8 @@ - (void)setUp
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(0));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(200));
return sharedProps;
})
.children({
Expand Down Expand Up @@ -216,8 +216,8 @@ - (void)setUp
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(30));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(50));
return sharedProps;
})
.children({
Expand Down Expand Up @@ -260,8 +260,8 @@ - (void)setUp
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(50));
return sharedProps;
})
.children({
Expand Down Expand Up @@ -418,8 +418,8 @@ - (void)testEntireParagraphLink
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0, 0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(200));
return sharedProps;
})
.children({
Expand All @@ -434,8 +434,8 @@ - (void)testEntireParagraphLink
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(0));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(20));
return sharedProps;
})
.children({
Expand Down
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
Original file line number Diff line number Diff line change
Expand Up @@ -533,9 +533,9 @@ void YogaLayoutableShadowNode::setSize(Size size) const {

auto style = yogaNode_.style();
style.setDimension(
yoga::Dimension::Width, yoga::StyleLength::points(size.width));
yoga::Dimension::Width, yoga::StyleSizeValue::points(size.width));
style.setDimension(
yoga::Dimension::Height, yoga::StyleLength::points(size.height));
yoga::Dimension::Height, yoga::StyleSizeValue::points(size.height));
yogaNode_.setStyle(style);
yogaNode_.setDirty(true);
}
Expand Down Expand Up @@ -626,16 +626,18 @@ void YogaLayoutableShadowNode::layoutTree(
auto ownerHeight = yogaFloatFromFloat(maximumSize.height);

yogaStyle.setMaxDimension(
yoga::Dimension::Width, yoga::StyleLength::points(maximumSize.width));
yoga::Dimension::Width, yoga::StyleSizeValue::points(maximumSize.width));

yogaStyle.setMaxDimension(
yoga::Dimension::Height, yoga::StyleLength::points(maximumSize.height));
yoga::Dimension::Height,
yoga::StyleSizeValue::points(maximumSize.height));

yogaStyle.setMinDimension(
yoga::Dimension::Width, yoga::StyleLength::points(minimumSize.width));
yoga::Dimension::Width, yoga::StyleSizeValue::points(minimumSize.width));

yogaStyle.setMinDimension(
yoga::Dimension::Height, yoga::StyleLength::points(minimumSize.height));
yoga::Dimension::Height,
yoga::StyleSizeValue::points(minimumSize.height));

auto direction =
yogaDirectionFromLayoutDirection(layoutConstraints.layoutDirection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ inline std::optional<Float> optionalFloatFromYogaValue(
std::optional<Float> base = {}) {
switch (length.unit()) {
case yoga::Unit::Undefined:
case yoga::Unit::Auto:
case yoga::Unit::MaxContent:
case yoga::Unit::Stretch:
case yoga::Unit::FitContent:
return {};
case yoga::Unit::Point:
return floatFromYogaOptionalFloat(length.value());
Expand All @@ -102,8 +106,6 @@ inline std::optional<Float> optionalFloatFromYogaValue(
? std::optional<Float>(
base.value() * floatFromYogaOptionalFloat(length.value()))
: std::optional<Float>();
case yoga::Unit::Auto:
return {};
}
}

Expand Down Expand Up @@ -432,6 +434,47 @@ inline void fromRawValue(
LOG(ERROR) << "Could not parse yoga::Display: " << stringValue;
}

inline void fromRawValue(
const PropsParserContext& /*context*/,
const RawValue& value,
yoga::Style::SizeValue& result) {
if (value.hasType<Float>()) {
result = yoga::StyleSizeValue::points((float)value);
return;
} else if (value.hasType<std::string>()) {
const auto stringValue = (std::string)value;
if (stringValue == "auto") {
result = yoga::StyleSizeValue::ofAuto();
return;
} else if (stringValue == "maxContent") {
result = yoga::StyleSizeValue::ofMaxContent();
return;
} else if (stringValue == "stretch") {
result = yoga::StyleSizeValue::ofStretch();
return;
} else if (stringValue == "fitContent") {
result = yoga::StyleSizeValue::ofFitContent();
return;
} else {
if (stringValue.back() == '%') {
auto tryValue = folly::tryTo<float>(
std::string_view(stringValue).substr(0, stringValue.length() - 1));
if (tryValue.hasValue()) {
result = yoga::StyleSizeValue::percent(tryValue.value());
return;
}
} else {
auto tryValue = folly::tryTo<float>(stringValue);
if (tryValue.hasValue()) {
result = yoga::StyleSizeValue::points(tryValue.value());
return;
}
}
}
}
result = yoga::StyleSizeValue::undefined();
}

inline void fromRawValue(
const PropsParserContext& context,
const RawValue& value,
Expand Down Expand Up @@ -1365,6 +1408,31 @@ inline std::string toString(const yoga::Style::Length& length) {
return std::to_string(length.value().unwrap()) + "%";
case yoga::Unit::Auto:
return "auto";
case yoga::Unit::FitContent:
return "fitContent";
case yoga::Unit::MaxContent:
return "maxContent";
case yoga::Unit::Stretch:
return "stretch";
}
}

inline std::string toString(const yoga::Style::SizeValue& length) {
switch (length.unit()) {
case yoga::Unit::Undefined:
return "undefined";
case yoga::Unit::Point:
return std::to_string(length.value().unwrap());
case yoga::Unit::Percent:
return std::to_string(length.value().unwrap()) + "%";
case yoga::Unit::Auto:
return "auto";
case yoga::Unit::FitContent:
return "fitContent";
case yoga::Unit::MaxContent:
return "maxContent";
case yoga::Unit::Stretch:
return "stretch";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ class LayoutTest : public ::testing::Test {
auto &props = *sharedProps;
props.layoutConstraints = LayoutConstraints{{0,0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(200));
return sharedProps;
})
.children({
Expand All @@ -90,8 +90,8 @@ class LayoutTest : public ::testing::Test {
auto &props = *sharedProps;
auto &yogaStyle = props.yogaStyle;
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(50));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(50));
return sharedProps;
})
.children({
Expand All @@ -105,8 +105,8 @@ class LayoutTest : public ::testing::Test {
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(10));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(10));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(30));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(90));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(30));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(90));

if (testCase == TRANSFORM_SCALE) {
props.transform = props.transform * Transform::Scale(2, 2, 1);
Expand Down Expand Up @@ -138,8 +138,8 @@ class LayoutTest : public ::testing::Test {
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(10));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(10));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(110));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(110));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(20));
return sharedProps;
})
.children({
Expand All @@ -153,8 +153,8 @@ class LayoutTest : public ::testing::Test {
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(70));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(-50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(30));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(60));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(30));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(60));
return sharedProps;
})
}),
Expand All @@ -168,8 +168,8 @@ class LayoutTest : public ::testing::Test {
yogaStyle.setPositionType(yoga::PositionType::Absolute);
yogaStyle.setPosition(yoga::Edge::Left, yoga::StyleLength::points(-60));
yogaStyle.setPosition(yoga::Edge::Top, yoga::StyleLength::points(50));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(70));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(20));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(70));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(20));
return sharedProps;
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ class PointerEventsProcessorTest : public ::testing::Test {
listenToAllPointerEvents(props);
props.layoutConstraints = LayoutConstraints{{0,0}, {500, 500}};
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(400));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(400));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(400));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(400));
yogaStyle.setDisplay(yoga::Display::Flex);
yogaStyle.setFlexDirection(yoga::FlexDirection::Row);
yogaStyle.setAlignItems(yoga::Align::Center);
Expand All @@ -109,8 +109,8 @@ class PointerEventsProcessorTest : public ::testing::Test {
yogaStyle.setFlexDirection(yoga::FlexDirection::Column);
yogaStyle.setAlignItems(yoga::Align::FlexEnd);
yogaStyle.setJustifyContent(yoga::Justify::Center);
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(150));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(300));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(150));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(300));
return sharedProps;
})
.children({
Expand All @@ -123,8 +123,8 @@ class PointerEventsProcessorTest : public ::testing::Test {
auto &props = *sharedProps;
listenToAllPointerEvents(props);
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(100));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(100));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(200));
return sharedProps;
})
}),
Expand All @@ -141,8 +141,8 @@ class PointerEventsProcessorTest : public ::testing::Test {
yogaStyle.setFlexDirection(yoga::FlexDirection::Column);
yogaStyle.setAlignItems(yoga::Align::FlexStart);
yogaStyle.setJustifyContent(yoga::Justify::Center);
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(150));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(300));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(150));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(300));
return sharedProps;
})
.children({
Expand All @@ -155,8 +155,8 @@ class PointerEventsProcessorTest : public ::testing::Test {
auto &props = *sharedProps;
listenToAllPointerEvents(props);
auto &yogaStyle = props.yogaStyle;
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleLength::points(100));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleLength::points(200));
yogaStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeValue::points(100));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeValue::points(200));
return sharedProps;
})
})
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native/ReactCommon/yoga/yoga/YGEnums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,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 packages/react-native/ReactCommon/yoga/yoga/YGEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ YG_ENUM_DECL(
YGUnitUndefined,
YGUnitPoint,
YGUnitPercent,
YGUnitAuto)
YGUnitAuto,
YGUnitMaxContent,
YGUnitFitContent,
YGUnitStretch)

YG_ENUM_DECL(
YGWrap,
Expand Down
Loading

0 comments on commit fbeb2e0

Please sign in to comment.