Allow lazy resolution of edge dimension values (#1453)

Summary:
X-link: https://github.com/facebook/react-native/pull/41347

Pull Request resolved: https://github.com/facebook/yoga/pull/1453

This follows the previous patterns used for `Gutters` and `Dimension`, where we hide CompactValue array implementation from `yoga::Style` callers.

This allows a single read of a style to only need access to the resolved values of a single edge, vs all edges. This is cheap now because the interface is the representation, but gets expensive if `StyleValuePool` is the actual implementation.

This prevents us from needing to resolve nine dimensions, in order to read a single value like `marginLeft`. Doing this, in the new style, also lets us remove `IdxRef` from the API.

We unroll the structure dependent parts in the props parsing code, for something more verbose, but also a bit clearer.

Changelog: [Internal]

Reviewed By: joevilches

Differential Revision: D50998164

fbshipit-source-id: 248396f9587e29d62cde05ae7512d8194f60c809
This commit is contained in:
Nick Gerleman
2023-11-14 09:12:35 -08:00
committed by Facebook GitHub Bot
parent bb892af3a4
commit f2c8acad2c
9 changed files with 124 additions and 416 deletions

View File

@@ -35,19 +35,6 @@ void updateStyle(YGNodeRef node, Ref (Style::*prop)(), T value) {
[prop](Style& s, T x) { (s.*prop)() = x; });
}
template <typename Ref, typename Idx>
void updateIndexedStyleProp(
YGNodeRef node,
Ref (Style::*prop)(),
Idx idx,
CompactValue value) {
updateStyle(
resolveRef(node),
value,
[idx, prop](Style& s, CompactValue x) { return (s.*prop)()[idx] != x; },
[idx, prop](Style& s, CompactValue x) { (s.*prop)()[idx] = x; });
}
template <auto GetterT, auto SetterT, typename IdxT>
void updateIndexedStyleProp(YGNodeRef node, IdxT idx, CompactValue value) {
updateStyle(
@@ -237,53 +224,53 @@ YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) {
void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float points) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
updateIndexedStyleProp<MSVC_HINT(position)>(
node, &Style::position, edge, value);
updateIndexedStyleProp<&Style::position, &Style::setPosition>(
node, edge, value);
}
void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) {
auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
updateIndexedStyleProp<MSVC_HINT(position)>(
node, &Style::position, edge, value);
updateIndexedStyleProp<&Style::position, &Style::setPosition>(
node, edge, value);
}
YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) {
return resolveRef(node)->getStyle().position()[edge];
return resolveRef(node)->getStyle().position(edge);
}
void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
updateIndexedStyleProp<MSVC_HINT(margin)>(node, &Style::margin, edge, value);
updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value);
}
void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float percent) {
auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
updateIndexedStyleProp<MSVC_HINT(margin)>(node, &Style::margin, edge, value);
updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value);
}
void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) {
updateIndexedStyleProp<MSVC_HINT(margin)>(
node, &Style::margin, edge, CompactValue::ofAuto());
updateIndexedStyleProp<&Style::margin, &Style::setMargin>(
node, edge, CompactValue::ofAuto());
}
YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) {
return resolveRef(node)->getStyle().margin()[edge];
return resolveRef(node)->getStyle().margin(edge);
}
void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
updateIndexedStyleProp<MSVC_HINT(padding)>(
node, &Style::padding, edge, value);
updateIndexedStyleProp<&Style::padding, &Style::setPadding>(
node, edge, value);
}
void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) {
auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
updateIndexedStyleProp<MSVC_HINT(padding)>(
node, &Style::padding, edge, value);
updateIndexedStyleProp<&Style::padding, &Style::setPadding>(
node, edge, value);
}
YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) {
return resolveRef(node)->getStyle().padding()[edge];
return resolveRef(node)->getStyle().padding(edge);
}
void YGNodeStyleSetBorder(
@@ -291,11 +278,11 @@ void YGNodeStyleSetBorder(
const YGEdge edge,
const float border) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(border);
updateIndexedStyleProp<MSVC_HINT(border)>(node, &Style::border, edge, value);
updateIndexedStyleProp<&Style::border, &Style::setBorder>(node, edge, value);
}
float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) {
auto border = resolveRef(node)->getStyle().border()[edge];
auto border = resolveRef(node)->getStyle().border(edge);
if (border.isUndefined() || border.isAuto()) {
return YGUndefined;
}