Skip to content

Commit

Permalink
[skip ci] Modify private apis to set, store, and get intrinsic sizing…
Browse files Browse the repository at this point in the history
… keywords (facebook#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`.

Reviewed By: NickGerleman

Differential Revision: D63927512
  • Loading branch information
joevilches authored and facebook-github-bot committed Oct 31, 2024
1 parent 6ba7cb3 commit c771517
Show file tree
Hide file tree
Showing 20 changed files with 402 additions and 105 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
3 changes: 3 additions & 0 deletions packages/react-native/React/Views/RCTLayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue)
return RCTCoreGraphicsFloatFromYogaFloat(value.value) * baseFloatValue;
case YGUnitAuto:
case YGUnitUndefined:
case YGUnitMaxContent:
case YGUnitFitContent:
case YGUnitStretch:
return baseFloatValue;
}
}
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 @@ -538,9 +538,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 @@ -631,16 +631,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 @@ -92,18 +92,15 @@ inline yoga::FloatOptional yogaOptionalFloatFromFloat(Float value) {
inline std::optional<Float> optionalFloatFromYogaValue(
const yoga::Style::Length& length,
std::optional<Float> base = {}) {
switch (length.unit()) {
case yoga::Unit::Undefined:
return {};
case yoga::Unit::Point:
return floatFromYogaOptionalFloat(length.value());
case yoga::Unit::Percent:
return base.has_value()
? std::optional<Float>(
base.value() * floatFromYogaOptionalFloat(length.value()))
: std::optional<Float>();
case yoga::Unit::Auto:
return {};
if (length.isPoints()) {
return floatFromYogaOptionalFloat(length.value());
} else if (length.isPercent()) {
return base.has_value()
? std::optional<Float>(
base.value() * floatFromYogaOptionalFloat(length.value()))
: std::optional<Float>();
} else {
return {};
}
}

Expand Down Expand Up @@ -446,6 +443,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 == "max-content") {
result = yoga::StyleSizeValue::ofMaxContent();
return;
} else if (stringValue == "stretch") {
result = yoga::StyleSizeValue::ofStretch();
return;
} else if (stringValue == "fit-content") {
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 @@ -1370,6 +1408,20 @@ inline std::string toString(const yoga::Display& value) {
}

inline std::string toString(const yoga::Style::Length& length) {
if (length.isUndefined()) {
return "undefined";
} else if (length.isAuto()) {
return "auto";
} else if (length.isPoints()) {
return std::to_string(length.value().unwrap());
} else if (length.isPercent()) {
return std::to_string(length.value().unwrap()) + "%";
} else {
return "unknown";
}
}

inline std::string toString(const yoga::Style::SizeValue& length) {
switch (length.unit()) {
case yoga::Unit::Undefined:
return "undefined";
Expand All @@ -1379,6 +1431,12 @@ 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 "fit-content";
case yoga::Unit::MaxContent:
return "max-content";
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 @@ -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 packages/react-native/ReactCommon/yoga/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
Loading

0 comments on commit c771517

Please sign in to comment.