From c6a13b610a39189960c772860ba0a1f6c80e2633 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 11 Sep 2023 19:01:04 -0700 Subject: [PATCH 1/5] const-correctness fixes Summary: This changes public Yoga API to in more places accept const structures where before they required mutable ones. This tries to avoid more breaking changes yet, e.g. changing callbacks to require clients do not modify nodes when they are passed for logging. We also don't have const variants for returning child structures which would allow mutation of dependencies of the const object. These would need new names under the public API, since we do not have operator overloading in C. Differential Revision: D49130412 fbshipit-source-id: f684c47671f6c45f1a859462e2513d998471e48b --- yoga/Yoga.cpp | 257 +++++++++++++---------------- yoga/Yoga.h | 56 +++---- yoga/algorithm/CalculateLayout.cpp | 6 +- yoga/config/Config.cpp | 22 ++- yoga/config/Config.h | 16 +- yoga/debug/AssertFatal.cpp | 26 +-- yoga/debug/AssertFatal.h | 4 +- yoga/debug/Log.cpp | 23 ++- yoga/debug/Log.h | 6 +- yoga/debug/NodeToString.cpp | 2 +- yoga/debug/NodeToString.h | 2 +- yoga/node/Node.cpp | 9 +- yoga/node/Node.h | 29 ++-- 13 files changed, 230 insertions(+), 228 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 4f18e770d1..1b81de2be5 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -99,93 +99,95 @@ YOGA_EXPORT bool YGFloatIsUndefined(const float value) { return yoga::isUndefined(value); } -YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) { - return static_cast(node)->getContext(); +YOGA_EXPORT void* YGNodeGetContext(YGNodeConstRef node) { + return resolveRef(node)->getContext(); } YOGA_EXPORT void YGNodeSetContext(YGNodeRef node, void* context) { - return static_cast(node)->setContext(context); + return resolveRef(node)->setContext(context); } YOGA_EXPORT YGConfigRef YGNodeGetConfig(YGNodeRef node) { - return static_cast(node)->getConfig(); + return resolveRef(node)->getConfig(); } YOGA_EXPORT void YGNodeSetConfig(YGNodeRef node, YGConfigRef config) { - static_cast(node)->setConfig(static_cast(config)); + resolveRef(node)->setConfig(resolveRef(config)); } -YOGA_EXPORT bool YGNodeHasMeasureFunc(YGNodeRef node) { - return static_cast(node)->hasMeasureFunc(); +YOGA_EXPORT bool YGNodeHasMeasureFunc(YGNodeConstRef node) { + return resolveRef(node)->hasMeasureFunc(); } YOGA_EXPORT void YGNodeSetMeasureFunc( YGNodeRef node, YGMeasureFunc measureFunc) { - static_cast(node)->setMeasureFunc(measureFunc); + resolveRef(node)->setMeasureFunc(measureFunc); } -YOGA_EXPORT bool YGNodeHasBaselineFunc(YGNodeRef node) { - return static_cast(node)->hasBaselineFunc(); +YOGA_EXPORT bool YGNodeHasBaselineFunc(YGNodeConstRef node) { + return resolveRef(node)->hasBaselineFunc(); } YOGA_EXPORT void YGNodeSetBaselineFunc( YGNodeRef node, YGBaselineFunc baselineFunc) { - static_cast(node)->setBaselineFunc(baselineFunc); + resolveRef(node)->setBaselineFunc(baselineFunc); } -YOGA_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node) { - return static_cast(node)->getDirtied(); +YOGA_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeConstRef node) { + return resolveRef(node)->getDirtied(); } YOGA_EXPORT void YGNodeSetDirtiedFunc( YGNodeRef node, YGDirtiedFunc dirtiedFunc) { - static_cast(node)->setDirtiedFunc(dirtiedFunc); + resolveRef(node)->setDirtiedFunc(dirtiedFunc); } YOGA_EXPORT void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc) { - static_cast(node)->setPrintFunc(printFunc); + resolveRef(node)->setPrintFunc(printFunc); } -YOGA_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node) { - return static_cast(node)->getHasNewLayout(); +YOGA_EXPORT bool YGNodeGetHasNewLayout(YGNodeConstRef node) { + return resolveRef(node)->getHasNewLayout(); } YOGA_EXPORT void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled) { - static_cast(config)->setShouldPrintTree(enabled); + resolveRef(config)->setShouldPrintTree(enabled); } YOGA_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout) { - static_cast(node)->setHasNewLayout(hasNewLayout); + resolveRef(node)->setHasNewLayout(hasNewLayout); } -YOGA_EXPORT YGNodeType YGNodeGetNodeType(YGNodeRef node) { - return static_cast(node)->getNodeType(); +YOGA_EXPORT YGNodeType YGNodeGetNodeType(YGNodeConstRef node) { + return resolveRef(node)->getNodeType(); } YOGA_EXPORT void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) { - return static_cast(node)->setNodeType(nodeType); + return resolveRef(node)->setNodeType(nodeType); } -YOGA_EXPORT bool YGNodeIsDirty(YGNodeRef node) { - return static_cast(node)->isDirty(); +YOGA_EXPORT bool YGNodeIsDirty(YGNodeConstRef node) { + return resolveRef(node)->isDirty(); } YOGA_EXPORT void YGNodeMarkDirtyAndPropagateToDescendants( const YGNodeRef node) { - return static_cast(node)->markDirtyAndPropagateDownwards(); + return resolveRef(node)->markDirtyAndPropagateDownwards(); } int32_t gConfigInstanceCount = 0; YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { - auto* node = new yoga::Node{static_cast(config)}; + auto* node = new yoga::Node{resolveRef(config)}; yoga::assertFatal( config != nullptr, "Tried to construct YGNode with null config"); yoga::assertFatalWithConfig( - config, node != nullptr, "Could not allocate memory for node"); + resolveRef(config), + node != nullptr, + "Could not allocate memory for node"); Event::publish(node, {config}); return node; @@ -201,8 +203,8 @@ YOGA_EXPORT YGNodeRef YGNodeNew(void) { } YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNodeRef) { - auto oldNode = static_cast(oldNodeRef); - auto node = new yoga::Node(*oldNode); + auto oldNode = resolveRef(oldNodeRef); + const auto node = new yoga::Node(*oldNode); yoga::assertFatalWithConfig( oldNode->getConfig(), node != nullptr, @@ -213,7 +215,7 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNodeRef) { } YOGA_EXPORT void YGNodeFree(const YGNodeRef nodeRef) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); if (auto owner = node->getOwner()) { owner->removeChild(node); @@ -232,13 +234,13 @@ YOGA_EXPORT void YGNodeFree(const YGNodeRef nodeRef) { YOGA_EXPORT void YGNodeDeallocate(const YGNodeRef node) { Event::publish(node, {YGNodeGetConfig(node)}); - delete static_cast(node); + delete resolveRef(node); } YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( const YGNodeRef rootRef, YGNodeCleanupFunc cleanup) { - const auto root = static_cast(rootRef); + const auto root = resolveRef(rootRef); uint32_t skipped = 0; while (YGNodeGetChildCount(root) > skipped) { @@ -262,7 +264,7 @@ YOGA_EXPORT void YGNodeFreeRecursive(const YGNodeRef root) { } YOGA_EXPORT void YGNodeReset(YGNodeRef node) { - static_cast(node)->reset(); + resolveRef(node)->reset(); } YOGA_EXPORT int32_t YGConfigGetInstanceCount(void) { @@ -280,30 +282,30 @@ YOGA_EXPORT YGConfigRef YGConfigNew(void) { } YOGA_EXPORT void YGConfigFree(const YGConfigRef config) { - delete static_cast(config); + delete resolveRef(config); gConfigInstanceCount--; } YOGA_EXPORT void YGNodeSetIsReferenceBaseline( YGNodeRef nodeRef, bool isReferenceBaseline) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); if (node->isReferenceBaseline() != isReferenceBaseline) { node->setIsReferenceBaseline(isReferenceBaseline); node->markDirtyAndPropagate(); } } -YOGA_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node) { - return static_cast(node)->isReferenceBaseline(); +YOGA_EXPORT bool YGNodeIsReferenceBaseline(YGNodeConstRef node) { + return resolveRef(node)->isReferenceBaseline(); } YOGA_EXPORT void YGNodeInsertChild( const YGNodeRef ownerRef, const YGNodeRef childRef, const uint32_t index) { - auto owner = static_cast(ownerRef); - auto child = static_cast(childRef); + auto owner = resolveRef(ownerRef); + auto child = resolveRef(childRef); yoga::assertFatalWithNode( owner, @@ -324,8 +326,8 @@ YOGA_EXPORT void YGNodeSwapChild( const YGNodeRef ownerRef, const YGNodeRef childRef, const uint32_t index) { - auto owner = static_cast(ownerRef); - auto child = static_cast(childRef); + auto owner = resolveRef(ownerRef); + auto child = resolveRef(childRef); owner->replaceChild(child, index); child->setOwner(owner); @@ -334,8 +336,8 @@ YOGA_EXPORT void YGNodeSwapChild( YOGA_EXPORT void YGNodeRemoveChild( const YGNodeRef ownerRef, const YGNodeRef excludedChildRef) { - auto owner = static_cast(ownerRef); - auto excludedChild = static_cast(excludedChildRef); + auto owner = resolveRef(ownerRef); + auto excludedChild = resolveRef(excludedChildRef); if (YGNodeGetChildCount(owner) == 0) { // This is an empty set. Nothing to remove. @@ -356,7 +358,7 @@ YOGA_EXPORT void YGNodeRemoveChild( } YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef ownerRef) { - auto owner = static_cast(ownerRef); + auto owner = resolveRef(ownerRef); const uint32_t childCount = YGNodeGetChildCount(owner); if (childCount == 0) { @@ -386,7 +388,7 @@ YOGA_EXPORT void YGNodeSetChildren( const YGNodeRef ownerRef, const YGNodeRef* childrenRefs, const uint32_t count) { - auto owner = static_cast(ownerRef); + auto owner = resolveRef(ownerRef); auto children = reinterpret_cast(childrenRefs); if (!owner) { @@ -425,7 +427,7 @@ YOGA_EXPORT void YGNodeSetChildren( YOGA_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef nodeRef, const uint32_t index) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); if (index < node->getChildren().size()) { return node->getChild(index); @@ -434,20 +436,19 @@ YGNodeGetChild(const YGNodeRef nodeRef, const uint32_t index) { } YOGA_EXPORT uint32_t YGNodeGetChildCount(const YGNodeConstRef node) { - return static_cast( - static_cast(node)->getChildren().size()); + return static_cast(resolveRef(node)->getChildren().size()); } YOGA_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node) { - return static_cast(node)->getOwner(); + return resolveRef(node)->getOwner(); } YOGA_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node) { - return static_cast(node)->getOwner(); + return resolveRef(node)->getOwner(); } YOGA_EXPORT void YGNodeMarkDirty(const YGNodeRef nodeRef) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); yoga::assertFatalWithNode( node, @@ -460,9 +461,9 @@ YOGA_EXPORT void YGNodeMarkDirty(const YGNodeRef nodeRef) { YOGA_EXPORT void YGNodeCopyStyle( const YGNodeRef dstNodeRef, - const YGNodeRef srcNodeRef) { - auto dstNode = static_cast(dstNodeRef); - auto srcNode = static_cast(srcNodeRef); + const YGNodeConstRef srcNodeRef) { + auto dstNode = resolveRef(dstNodeRef); + auto srcNode = resolveRef(srcNodeRef); if (!(dstNode->getStyle() == srcNode->getStyle())) { dstNode->setStyle(srcNode->getStyle()); @@ -471,14 +472,14 @@ YOGA_EXPORT void YGNodeCopyStyle( } YOGA_EXPORT float YGNodeStyleGetFlexGrow(const YGNodeConstRef nodeRef) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); return node->getStyle().flexGrow().isUndefined() ? Style::DefaultFlexGrow : node->getStyle().flexGrow().unwrap(); } YOGA_EXPORT float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); return node->getStyle().flexShrink().isUndefined() ? (node->getConfig()->useWebDefaults() ? Style::WebDefaultFlexShrink : Style::DefaultFlexShrink) @@ -502,7 +503,7 @@ void updateStyle( template void updateStyle(YGNodeRef node, Ref (Style::*prop)(), T value) { updateStyle( - static_cast(node), + resolveRef(node), value, [prop](Style& s, T x) { return (s.*prop)() != x; }, [prop](Style& s, T x) { (s.*prop)() = x; }); @@ -515,7 +516,7 @@ void updateIndexedStyleProp( Idx idx, CompactValue value) { updateStyle( - static_cast(node), + resolveRef(node), value, [idx, prop](Style& s, CompactValue x) { return (s.*prop)()[idx] != x; }, [idx, prop](Style& s, CompactValue x) { (s.*prop)()[idx] = x; }); @@ -536,7 +537,7 @@ YOGA_EXPORT void YGNodeStyleSetDirection( updateStyle(node, &Style::direction, value); } YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { - return static_cast(node)->getStyle().direction(); + return resolveRef(node)->getStyle().direction(); } YOGA_EXPORT void YGNodeStyleSetFlexDirection( @@ -547,7 +548,7 @@ YOGA_EXPORT void YGNodeStyleSetFlexDirection( } YOGA_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { - return static_cast(node)->getStyle().flexDirection(); + return resolveRef(node)->getStyle().flexDirection(); } YOGA_EXPORT void YGNodeStyleSetJustifyContent( @@ -557,7 +558,7 @@ YOGA_EXPORT void YGNodeStyleSetJustifyContent( node, &Style::justifyContent, justifyContent); } YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { - return static_cast(node)->getStyle().justifyContent(); + return resolveRef(node)->getStyle().justifyContent(); } YOGA_EXPORT void YGNodeStyleSetAlignContent( @@ -567,7 +568,7 @@ YOGA_EXPORT void YGNodeStyleSetAlignContent( node, &Style::alignContent, alignContent); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { - return static_cast(node)->getStyle().alignContent(); + return resolveRef(node)->getStyle().alignContent(); } YOGA_EXPORT void YGNodeStyleSetAlignItems( @@ -576,7 +577,7 @@ YOGA_EXPORT void YGNodeStyleSetAlignItems( updateStyle(node, &Style::alignItems, alignItems); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { - return static_cast(node)->getStyle().alignItems(); + return resolveRef(node)->getStyle().alignItems(); } YOGA_EXPORT void YGNodeStyleSetAlignSelf( @@ -585,7 +586,7 @@ YOGA_EXPORT void YGNodeStyleSetAlignSelf( updateStyle(node, &Style::alignSelf, alignSelf); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { - return static_cast(node)->getStyle().alignSelf(); + return resolveRef(node)->getStyle().alignSelf(); } YOGA_EXPORT void YGNodeStyleSetPositionType( @@ -596,7 +597,7 @@ YOGA_EXPORT void YGNodeStyleSetPositionType( } YOGA_EXPORT YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) { - return static_cast(node)->getStyle().positionType(); + return resolveRef(node)->getStyle().positionType(); } YOGA_EXPORT void YGNodeStyleSetFlexWrap( @@ -605,7 +606,7 @@ YOGA_EXPORT void YGNodeStyleSetFlexWrap( updateStyle(node, &Style::flexWrap, flexWrap); } YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { - return static_cast(node)->getStyle().flexWrap(); + return resolveRef(node)->getStyle().flexWrap(); } YOGA_EXPORT void YGNodeStyleSetOverflow( @@ -614,7 +615,7 @@ YOGA_EXPORT void YGNodeStyleSetOverflow( updateStyle(node, &Style::overflow, overflow); } YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { - return static_cast(node)->getStyle().overflow(); + return resolveRef(node)->getStyle().overflow(); } YOGA_EXPORT void YGNodeStyleSetDisplay( @@ -623,7 +624,7 @@ YOGA_EXPORT void YGNodeStyleSetDisplay( updateStyle(node, &Style::display, display); } YOGA_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { - return static_cast(node)->getStyle().display(); + return resolveRef(node)->getStyle().display(); } // TODO(T26792433): Change the API to accept FloatOptional. @@ -633,7 +634,7 @@ YOGA_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { // TODO(T26792433): Change the API to accept FloatOptional. YOGA_EXPORT float YGNodeStyleGetFlex(const YGNodeConstRef nodeRef) { - auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); return node->getStyle().flex().isUndefined() ? YGUndefined : node->getStyle().flex().unwrap(); @@ -656,8 +657,7 @@ YOGA_EXPORT void YGNodeStyleSetFlexShrink( } YOGA_EXPORT YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { - YGValue flexBasis = - static_cast(node)->getStyle().flexBasis(); + YGValue flexBasis = resolveRef(node)->getStyle().flexBasis(); if (flexBasis.unit == YGUnitUndefined || flexBasis.unit == YGUnitAuto) { // TODO(T26792433): Get rid off the use of YGUndefined at client side flexBasis.value = YGUndefined; @@ -701,7 +701,7 @@ YOGA_EXPORT void YGNodeStyleSetPositionPercent( node, &Style::position, edge, value); } YOGA_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { - return static_cast(node)->getStyle().position()[edge]; + return resolveRef(node)->getStyle().position()[edge]; } YOGA_EXPORT void YGNodeStyleSetMargin( @@ -723,7 +723,7 @@ YOGA_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { node, &Style::margin, edge, CompactValue::ofAuto()); } YOGA_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { - return static_cast(node)->getStyle().margin()[edge]; + return resolveRef(node)->getStyle().margin()[edge]; } YOGA_EXPORT void YGNodeStyleSetPadding( @@ -743,7 +743,7 @@ YOGA_EXPORT void YGNodeStyleSetPaddingPercent( node, &Style::padding, edge, value); } YOGA_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { - return static_cast(node)->getStyle().padding()[edge]; + return resolveRef(node)->getStyle().padding()[edge]; } // TODO(T26792433): Change the API to accept FloatOptional. @@ -758,7 +758,7 @@ YOGA_EXPORT void YGNodeStyleSetBorder( YOGA_EXPORT float YGNodeStyleGetBorder( const YGNodeConstRef node, const YGEdge edge) { - auto border = static_cast(node)->getStyle().border()[edge]; + auto border = resolveRef(node)->getStyle().border()[edge]; if (border.isUndefined() || border.isAuto()) { // TODO(T26792433): Rather than returning YGUndefined, change the api to // return FloatOptional. @@ -779,8 +779,7 @@ YOGA_EXPORT void YGNodeStyleSetGap( YOGA_EXPORT float YGNodeStyleGetGap( const YGNodeConstRef node, const YGGutter gutter) { - auto gapLength = - static_cast(node)->getStyle().gap()[gutter]; + auto gapLength = resolveRef(node)->getStyle().gap()[gutter]; if (gapLength.isUndefined() || gapLength.isAuto()) { // TODO(T26792433): Rather than returning YGUndefined, change the api to // return FloatOptional. @@ -794,8 +793,7 @@ YOGA_EXPORT float YGNodeStyleGetGap( // TODO(T26792433): Change the API to accept FloatOptional. YOGA_EXPORT float YGNodeStyleGetAspectRatio(const YGNodeConstRef node) { - const FloatOptional op = - static_cast(node)->getStyle().aspectRatio(); + const FloatOptional op = resolveRef(node)->getStyle().aspectRatio(); return op.isUndefined() ? YGUndefined : op.unwrap(); } @@ -822,9 +820,7 @@ YOGA_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node) { node, &Style::dimensions, YGDimensionWidth, CompactValue::ofAuto()); } YOGA_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { - return static_cast(node) - ->getStyle() - .dimensions()[YGDimensionWidth]; + return resolveRef(node)->getStyle().dimensions()[YGDimensionWidth]; } YOGA_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float points) { @@ -842,9 +838,7 @@ YOGA_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node) { node, &Style::dimensions, YGDimensionHeight, CompactValue::ofAuto()); } YOGA_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { - return static_cast(node) - ->getStyle() - .dimensions()[YGDimensionHeight]; + return resolveRef(node)->getStyle().dimensions()[YGDimensionHeight]; } YOGA_EXPORT void YGNodeStyleSetMinWidth( @@ -862,9 +856,7 @@ YOGA_EXPORT void YGNodeStyleSetMinWidthPercent( node, &Style::minDimensions, YGDimensionWidth, value); } YOGA_EXPORT YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { - return static_cast(node) - ->getStyle() - .minDimensions()[YGDimensionWidth]; + return resolveRef(node)->getStyle().minDimensions()[YGDimensionWidth]; } YOGA_EXPORT void YGNodeStyleSetMinHeight( @@ -882,9 +874,7 @@ YOGA_EXPORT void YGNodeStyleSetMinHeightPercent( node, &Style::minDimensions, YGDimensionHeight, value); } YOGA_EXPORT YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { - return static_cast(node) - ->getStyle() - .minDimensions()[YGDimensionHeight]; + return resolveRef(node)->getStyle().minDimensions()[YGDimensionHeight]; } YOGA_EXPORT void YGNodeStyleSetMaxWidth( @@ -902,9 +892,7 @@ YOGA_EXPORT void YGNodeStyleSetMaxWidthPercent( node, &Style::maxDimensions, YGDimensionWidth, value); } YOGA_EXPORT YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { - return static_cast(node) - ->getStyle() - .maxDimensions()[YGDimensionWidth]; + return resolveRef(node)->getStyle().maxDimensions()[YGDimensionWidth]; } YOGA_EXPORT void YGNodeStyleSetMaxHeight( @@ -922,20 +910,18 @@ YOGA_EXPORT void YGNodeStyleSetMaxHeightPercent( node, &Style::maxDimensions, YGDimensionHeight, value); } YOGA_EXPORT YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { - return static_cast(node) - ->getStyle() - .maxDimensions()[YGDimensionHeight]; + return resolveRef(node)->getStyle().maxDimensions()[YGDimensionHeight]; } -#define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ - YOGA_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node) { \ - return static_cast(node)->getLayout().instanceName; \ +#define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ + YOGA_EXPORT type YGNodeLayoutGet##name(const YGNodeConstRef node) { \ + return resolveRef(node)->getLayout().instanceName; \ } #define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \ YOGA_EXPORT type YGNodeLayoutGet##name( \ - const YGNodeRef nodeRef, const YGEdge edge) { \ - auto node = static_cast(nodeRef); \ + const YGNodeConstRef nodeRef, const YGEdge edge) { \ + const auto node = resolveRef(nodeRef); \ yoga::assertFatalWithNode( \ node, \ edge <= YGEdgeEnd, \ @@ -975,9 +961,9 @@ YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Padding, padding) #ifdef DEBUG YOGA_EXPORT void YGNodePrint( - const YGNodeRef nodeRef, + const YGNodeConstRef nodeRef, const YGPrintOptions options) { - const auto node = static_cast(nodeRef); + const auto node = resolveRef(nodeRef); std::string str; yoga::nodeToString(str, node, options, 0); yoga::log(node, YGLogLevelDebug, nullptr, str.c_str()); @@ -986,12 +972,12 @@ YOGA_EXPORT void YGNodePrint( YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { if (logger != nullptr) { - static_cast(config)->setLogger(logger); + resolveRef(config)->setLogger(logger); } else { #ifdef ANDROID - static_cast(config)->setLogger(&YGAndroidLog); + resolveRef(config)->setLogger(&YGAndroidLog); #else - static_cast(config)->setLogger(&YGDefaultLog); + resolveRef(config)->setLogger(&YGDefaultLog); #endif } } @@ -1000,21 +986,21 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor( const YGConfigRef config, const float pixelsInPoint) { yoga::assertFatalWithConfig( - config, + resolveRef(config), pixelsInPoint >= 0.0f, "Scale factor should not be less than zero"); // We store points for Pixel as we will use it for rounding if (pixelsInPoint == 0.0f) { // Zero is used to skip rounding - static_cast(config)->setPointScaleFactor(0.0f); + resolveRef(config)->setPointScaleFactor(0.0f); } else { - static_cast(config)->setPointScaleFactor(pixelsInPoint); + resolveRef(config)->setPointScaleFactor(pixelsInPoint); } } -YOGA_EXPORT float YGConfigGetPointScaleFactor(const YGConfigRef config) { - return static_cast(config)->getPointScaleFactor(); +YOGA_EXPORT float YGConfigGetPointScaleFactor(const YGConfigConstRef config) { + return resolveRef(config)->getPointScaleFactor(); } YOGA_EXPORT float YGRoundValueToPixelGrid( @@ -1030,63 +1016,60 @@ YOGA_EXPORT void YGConfigSetExperimentalFeatureEnabled( const YGConfigRef config, const YGExperimentalFeature feature, const bool enabled) { - static_cast(config)->setExperimentalFeatureEnabled( - feature, enabled); + resolveRef(config)->setExperimentalFeatureEnabled(feature, enabled); } YOGA_EXPORT bool YGConfigIsExperimentalFeatureEnabled( - const YGConfigRef config, + const YGConfigConstRef config, const YGExperimentalFeature feature) { - return static_cast(config)->isExperimentalFeatureEnabled( - feature); + return resolveRef(config)->isExperimentalFeatureEnabled(feature); } YOGA_EXPORT void YGConfigSetUseWebDefaults( const YGConfigRef config, const bool enabled) { - static_cast(config)->setUseWebDefaults(enabled); + resolveRef(config)->setUseWebDefaults(enabled); } YOGA_EXPORT bool YGConfigGetUseLegacyStretchBehaviour( - const YGConfigRef config) { - return static_cast(config)->hasErrata( - YGErrataStretchFlexBasis); + const YGConfigConstRef config) { + return resolveRef(config)->hasErrata(YGErrataStretchFlexBasis); } YOGA_EXPORT void YGConfigSetUseLegacyStretchBehaviour( const YGConfigRef config, const bool useLegacyStretchBehaviour) { if (useLegacyStretchBehaviour) { - static_cast(config)->addErrata(YGErrataStretchFlexBasis); + resolveRef(config)->addErrata(YGErrataStretchFlexBasis); } else { - static_cast(config)->removeErrata(YGErrataStretchFlexBasis); + resolveRef(config)->removeErrata(YGErrataStretchFlexBasis); } } -bool YGConfigGetUseWebDefaults(const YGConfigRef config) { - return static_cast(config)->useWebDefaults(); +bool YGConfigGetUseWebDefaults(const YGConfigConstRef config) { + return resolveRef(config)->useWebDefaults(); } YOGA_EXPORT void YGConfigSetContext(const YGConfigRef config, void* context) { - static_cast(config)->setContext(context); + resolveRef(config)->setContext(context); } -YOGA_EXPORT void* YGConfigGetContext(const YGConfigRef config) { - return static_cast(config)->getContext(); +YOGA_EXPORT void* YGConfigGetContext(const YGConfigConstRef config) { + return resolveRef(config)->getContext(); } YOGA_EXPORT void YGConfigSetErrata(YGConfigRef config, YGErrata errata) { - static_cast(config)->setErrata(errata); + resolveRef(config)->setErrata(errata); } -YOGA_EXPORT YGErrata YGConfigGetErrata(YGConfigRef config) { - return static_cast(config)->getErrata(); +YOGA_EXPORT YGErrata YGConfigGetErrata(YGConfigConstRef config) { + return resolveRef(config)->getErrata(); } YOGA_EXPORT void YGConfigSetCloneNodeFunc( const YGConfigRef config, const YGCloneNodeFunc callback) { - static_cast(config)->setCloneNodeCallback(callback); + resolveRef(config)->setCloneNodeCallback(callback); } // TODO: This should not be part of the public API. Remove after removing @@ -1118,7 +1101,7 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( lastComputedHeight, marginRow, marginColumn, - static_cast(config)); + resolveRef(config)); } YOGA_EXPORT void YGNodeCalculateLayout( @@ -1131,15 +1114,11 @@ YOGA_EXPORT void YGNodeCalculateLayout( } YOGA_EXPORT void YGNodeCalculateLayoutWithContext( - const YGNodeRef nodeRef, + const YGNodeRef node, const float ownerWidth, const float ownerHeight, const YGDirection ownerDirection, void* layoutContext) { yoga::calculateLayout( - static_cast(nodeRef), - ownerWidth, - ownerHeight, - ownerDirection, - layoutContext); + resolveRef(node), ownerWidth, ownerHeight, ownerDirection, layoutContext); } diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 1b12dd40d1..54569adc5d 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -23,6 +23,7 @@ typedef struct YGSize { } YGSize; typedef struct YGConfig* YGConfigRef; +typedef const struct YGConfig* YGConfigConstRef; typedef struct YGNode* YGNodeRef; typedef const struct YGNode* YGNodeConstRef; @@ -82,7 +83,7 @@ WIN_EXPORT void YGNodeSetIsReferenceBaseline( YGNodeRef node, bool isReferenceBaseline); -WIN_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node); +WIN_EXPORT bool YGNodeIsReferenceBaseline(YGNodeConstRef node); WIN_EXPORT void YGNodeCalculateLayout( YGNodeRef node, @@ -104,7 +105,7 @@ WIN_EXPORT void YGNodeMarkDirty(YGNodeRef node); // `YGCalculateLayout` will cause the recalculation of each and every node. WIN_EXPORT void YGNodeMarkDirtyAndPropagateToDescendants(YGNodeRef node); -WIN_EXPORT void YGNodePrint(YGNodeRef node, YGPrintOptions options); +WIN_EXPORT void YGNodePrint(YGNodeConstRef node, YGPrintOptions options); WIN_EXPORT bool YGFloatIsUndefined(float value); @@ -125,27 +126,27 @@ WIN_EXPORT bool YGNodeCanUseCachedMeasurement( float marginColumn, YGConfigRef config); -WIN_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeRef srcNode); +WIN_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeConstRef srcNode); -WIN_EXPORT void* YGNodeGetContext(YGNodeRef node); +WIN_EXPORT void* YGNodeGetContext(YGNodeConstRef node); WIN_EXPORT void YGNodeSetContext(YGNodeRef node, void* context); WIN_EXPORT YGConfigRef YGNodeGetConfig(YGNodeRef node); WIN_EXPORT void YGNodeSetConfig(YGNodeRef node, YGConfigRef config); void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled); -bool YGNodeHasMeasureFunc(YGNodeRef node); +bool YGNodeHasMeasureFunc(YGNodeConstRef node); WIN_EXPORT void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc); -bool YGNodeHasBaselineFunc(YGNodeRef node); +bool YGNodeHasBaselineFunc(YGNodeConstRef node); void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc); -YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node); +YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeConstRef node); void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc); void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc); -WIN_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node); +WIN_EXPORT bool YGNodeGetHasNewLayout(YGNodeConstRef node); WIN_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout); -YGNodeType YGNodeGetNodeType(YGNodeRef node); +YGNodeType YGNodeGetNodeType(YGNodeConstRef node); void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType); -WIN_EXPORT bool YGNodeIsDirty(YGNodeRef node); +WIN_EXPORT bool YGNodeIsDirty(YGNodeConstRef node); WIN_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction); WIN_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node); @@ -280,22 +281,22 @@ WIN_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node); WIN_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio); WIN_EXPORT float YGNodeStyleGetAspectRatio(YGNodeConstRef node); -WIN_EXPORT float YGNodeLayoutGetLeft(YGNodeRef node); -WIN_EXPORT float YGNodeLayoutGetTop(YGNodeRef node); -WIN_EXPORT float YGNodeLayoutGetRight(YGNodeRef node); -WIN_EXPORT float YGNodeLayoutGetBottom(YGNodeRef node); -WIN_EXPORT float YGNodeLayoutGetWidth(YGNodeRef node); -WIN_EXPORT float YGNodeLayoutGetHeight(YGNodeRef node); -WIN_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeRef node); -WIN_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeRef node); +WIN_EXPORT float YGNodeLayoutGetLeft(YGNodeConstRef node); +WIN_EXPORT float YGNodeLayoutGetTop(YGNodeConstRef node); +WIN_EXPORT float YGNodeLayoutGetRight(YGNodeConstRef node); +WIN_EXPORT float YGNodeLayoutGetBottom(YGNodeConstRef node); +WIN_EXPORT float YGNodeLayoutGetWidth(YGNodeConstRef node); +WIN_EXPORT float YGNodeLayoutGetHeight(YGNodeConstRef node); +WIN_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeConstRef node); +WIN_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeConstRef node); // Get the computed values for these nodes after performing layout. If they were // set using point values then the returned value will be the same as // YGNodeStyleGetXXX. However if they were set using a percentage value then the // returned value is the computed value used during layout. -WIN_EXPORT float YGNodeLayoutGetMargin(YGNodeRef node, YGEdge edge); -WIN_EXPORT float YGNodeLayoutGetBorder(YGNodeRef node, YGEdge edge); -WIN_EXPORT float YGNodeLayoutGetPadding(YGNodeRef node, YGEdge edge); +WIN_EXPORT float YGNodeLayoutGetMargin(YGNodeConstRef node, YGEdge edge); +WIN_EXPORT float YGNodeLayoutGetBorder(YGNodeConstRef node, YGEdge edge); +WIN_EXPORT float YGNodeLayoutGetPadding(YGNodeConstRef node, YGEdge edge); WIN_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger); // Set this to number of pixels in 1 point to round calculation results If you @@ -303,7 +304,7 @@ WIN_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger); WIN_EXPORT void YGConfigSetPointScaleFactor( YGConfigRef config, float pixelsInPoint); -WIN_EXPORT float YGConfigGetPointScaleFactor(YGConfigRef config); +WIN_EXPORT float YGConfigGetPointScaleFactor(YGConfigConstRef config); // Yoga previously had an error where containers would take the maximum space // possible instead of the minimum like they are supposed to. In practice this @@ -312,7 +313,7 @@ WIN_EXPORT float YGConfigGetPointScaleFactor(YGConfigRef config); // this behaviour. WIN_EXPORT YG_DEPRECATED( "Please use " - "\"YGConfigGetErrata()\"") bool YGConfigGetUseLegacyStretchBehaviour(YGConfigRef + "\"YGConfigGetErrata()\"") bool YGConfigGetUseLegacyStretchBehaviour(YGConfigConstRef config); WIN_EXPORT YG_DEPRECATED( @@ -336,26 +337,25 @@ WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled( YGExperimentalFeature feature, bool enabled); WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled( - YGConfigRef config, + YGConfigConstRef config, YGExperimentalFeature feature); // Using the web defaults is the preferred configuration for new projects. Usage // of non web defaults should be considered as legacy. WIN_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled); -WIN_EXPORT bool YGConfigGetUseWebDefaults(YGConfigRef config); +WIN_EXPORT bool YGConfigGetUseWebDefaults(YGConfigConstRef config); WIN_EXPORT void YGConfigSetCloneNodeFunc( YGConfigRef config, YGCloneNodeFunc callback); -// Export only for C# WIN_EXPORT YGConfigRef YGConfigGetDefault(void); WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context); -WIN_EXPORT void* YGConfigGetContext(YGConfigRef config); +WIN_EXPORT void* YGConfigGetContext(YGConfigConstRef config); WIN_EXPORT void YGConfigSetErrata(YGConfigRef config, YGErrata errata); -WIN_EXPORT YGErrata YGConfigGetErrata(YGConfigRef config); +WIN_EXPORT YGErrata YGConfigGetErrata(YGConfigConstRef config); WIN_EXPORT float YGRoundValueToPixelGrid( double value, diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index d2bc46b6cc..d94de53021 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -827,8 +827,10 @@ static void zeroOutLayoutRecursively( node->setLayoutDimension(0, YGDimensionHeight); node->setHasNewLayout(true); - node->iterChildrenAfterCloningIfNeeded( - zeroOutLayoutRecursively, layoutContext); + node->cloneChildrenIfNeeded(layoutContext); + for (const auto child : node->getChildren()) { + zeroOutLayoutRecursively(child, layoutContext); + } } static float calculateAvailableInnerDimension( diff --git a/yoga/config/Config.cpp b/yoga/config/Config.cpp index d8809cf5a2..3032a5b7d1 100644 --- a/yoga/config/Config.cpp +++ b/yoga/config/Config.cpp @@ -6,6 +6,7 @@ */ #include +#include namespace facebook::yoga { @@ -101,15 +102,28 @@ void Config::setLogger(std::nullptr_t) { } void Config::log( - YGNodeRef node, + const yoga::Node* node, YGLogLevel logLevel, void* logContext, const char* format, - va_list args) { + va_list args) const { + // TODO: Break log callback signatures to make them const correct + if (flags_.loggerUsesContext) { - logger_.withContext(this, node, logLevel, logContext, format, args); + logger_.withContext( + const_cast(this), + const_cast(node), + logLevel, + logContext, + format, + args); } else { - logger_.noContext(this, node, logLevel, format, args); + logger_.noContext( + const_cast(this), + const_cast(node), + logLevel, + format, + args); } } diff --git a/yoga/config/Config.h b/yoga/config/Config.h index ebf3f77f79..0a422c9c29 100644 --- a/yoga/config/Config.h +++ b/yoga/config/Config.h @@ -16,6 +16,7 @@ struct YGConfig {}; namespace facebook::yoga { class Config; +class Node; // Whether moving a node from config "a" to config "b" should dirty previously // calculated layout results. @@ -78,7 +79,12 @@ class YOGA_EXPORT Config : public ::YGConfig { void setLogger(YGLogger logger); void setLogger(LogWithContextFn logger); void setLogger(std::nullptr_t); - void log(YGNodeRef, YGLogLevel, void*, const char*, va_list); + void log( + const yoga::Node* node, + YGLogLevel logLevel, + void* logContext, + const char* format, + va_list args) const; void setCloneNodeCallback(YGCloneNodeFunc cloneNode); void setCloneNodeCallback(CloneWithContextFn cloneNode); @@ -106,4 +112,12 @@ class YOGA_EXPORT Config : public ::YGConfig { void* context_ = nullptr; }; +inline Config* resolveRef(const YGConfigRef ref) { + return static_cast(ref); +} + +inline const Config* resolveRef(const YGConfigConstRef ref) { + return static_cast(ref); +} + } // namespace facebook::yoga diff --git a/yoga/debug/AssertFatal.cpp b/yoga/debug/AssertFatal.cpp index 6be4cc67be..bc85235a85 100644 --- a/yoga/debug/AssertFatal.cpp +++ b/yoga/debug/AssertFatal.cpp @@ -22,43 +22,27 @@ namespace facebook::yoga { void assertFatal(const bool condition, const char* message) { if (!condition) { - yoga::log( - static_cast(nullptr), - YGLogLevelFatal, - nullptr, - "%s\n", - message); + yoga::log(YGLogLevelFatal, nullptr, "%s\n", message); fatalWithMessage(message); } } void assertFatalWithNode( - const YGNodeConstRef node, + const yoga::Node* const node, const bool condition, const char* message) { if (!condition) { - yoga::log( - // TODO: Break log callbacks and make them const correct - static_cast(const_cast(node)), - YGLogLevelFatal, - nullptr, - "%s\n", - message); + yoga::log(node, YGLogLevelFatal, nullptr, "%s\n", message); fatalWithMessage(message); } } void assertFatalWithConfig( - YGConfigRef config, + const yoga::Config* const config, const bool condition, const char* message) { if (!condition) { - yoga::log( - static_cast(config), - YGLogLevelFatal, - nullptr, - "%s\n", - message); + yoga::log(config, YGLogLevelFatal, nullptr, "%s\n", message); fatalWithMessage(message); } } diff --git a/yoga/debug/AssertFatal.h b/yoga/debug/AssertFatal.h index ae5a1d5ae8..5aa3b9e473 100644 --- a/yoga/debug/AssertFatal.h +++ b/yoga/debug/AssertFatal.h @@ -17,11 +17,11 @@ namespace facebook::yoga { void assertFatal(bool condition, const char* message); void assertFatalWithNode( - YGNodeConstRef node, + const yoga::Node* node, bool condition, const char* message); void assertFatalWithConfig( - YGConfigRef config, + const yoga::Config* config, bool condition, const char* message); diff --git a/yoga/debug/Log.cpp b/yoga/debug/Log.cpp index f3d704aa71..21d8c6075b 100644 --- a/yoga/debug/Log.cpp +++ b/yoga/debug/Log.cpp @@ -12,21 +12,28 @@ namespace facebook::yoga { namespace { void vlog( - yoga::Config* config, - yoga::Node* node, + const yoga::Config* config, + const yoga::Node* node, YGLogLevel level, void* context, const char* format, va_list args) { - yoga::Config* logConfig = config != nullptr - ? config - : static_cast(YGConfigGetDefault()); - logConfig->log(node, level, context, format, args); + const yoga::Config* logConfig = + config != nullptr ? config : resolveRef(YGConfigGetDefault()); + + logConfig->log(const_cast(node), level, context, format, args); } } // namespace +void log(YGLogLevel level, void* context, const char* format, ...) noexcept { + va_list args; + va_start(args, format); + vlog(nullptr, nullptr, level, context, format, args); + va_end(args); +} + void log( - yoga::Node* node, + const yoga::Node* node, YGLogLevel level, void* context, const char* format, @@ -44,7 +51,7 @@ void log( } void log( - yoga::Config* config, + const yoga::Config* config, YGLogLevel level, void* context, const char* format, diff --git a/yoga/debug/Log.h b/yoga/debug/Log.h index dd4db2f4d1..47ed5d4118 100644 --- a/yoga/debug/Log.h +++ b/yoga/debug/Log.h @@ -13,15 +13,17 @@ namespace facebook::yoga { +void log(YGLogLevel level, void*, const char* format, ...) noexcept; + void log( - yoga::Node* node, + const yoga::Node* node, YGLogLevel level, void*, const char* message, ...) noexcept; void log( - yoga::Config* config, + const yoga::Config* config, YGLogLevel level, void*, const char* format, diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index 449fbc7012..30697dd6ed 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -117,7 +117,7 @@ static void appendEdgeIfNotUndefined( void nodeToString( std::string& str, - yoga::Node* node, + const yoga::Node* node, YGPrintOptions options, uint32_t level) { indent(str, level); diff --git a/yoga/debug/NodeToString.h b/yoga/debug/NodeToString.h index c00439b33a..07f5941ab2 100644 --- a/yoga/debug/NodeToString.h +++ b/yoga/debug/NodeToString.h @@ -18,7 +18,7 @@ namespace facebook::yoga { void nodeToString( std::string& str, - yoga::Node* node, + const yoga::Node* node, YGPrintOptions options, uint32_t level); diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index 70a81bd182..295f4eb9c6 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -484,7 +484,14 @@ YOGA_EXPORT void Node::clearChildren() { // Other Methods void Node::cloneChildrenIfNeeded(void* cloneContext) { - iterChildrenAfterCloningIfNeeded([](Node*, void*) {}, cloneContext); + int i = 0; + for (Node*& child : children_) { + if (child->getOwner() != this) { + child = resolveRef(config_->cloneNode(child, this, i, cloneContext)); + child->setOwner(this); + } + i += 1; + } } void Node::markDirtyAndPropagate() { diff --git a/yoga/node/Node.h b/yoga/node/Node.h index c7d69267cd..8a21d43060 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -11,6 +11,8 @@ #include #include +#include + #include #include #include @@ -139,7 +141,7 @@ class YOGA_EXPORT Node : public ::YGNode { uint32_t getLineIndex() const { return lineIndex_; } - bool isReferenceBaseline() { return flags_.isReferenceBaseline; } + bool isReferenceBaseline() const { return flags_.isReferenceBaseline; } // returns the Node that owns this Node. An owner is used to identify // the YogaTree that a Node belongs to. This method will return the parent @@ -152,23 +154,6 @@ class YOGA_EXPORT Node : public ::YGNode { const std::vector& getChildren() const { return children_; } - // Applies a callback to all children, after cloning them if they are not - // owned. - template - void iterChildrenAfterCloningIfNeeded(T callback, void* cloneContext) { - int i = 0; - for (Node*& child : children_) { - if (child->getOwner() != this) { - child = static_cast( - config_->cloneNode(child, this, i, cloneContext)); - child->setOwner(this); - } - i += 1; - - callback(child, cloneContext); - } - } - Node* getChild(size_t index) const { return children_.at(index); } size_t getChildCount() const { return children_.size(); } @@ -343,4 +328,12 @@ class YOGA_EXPORT Node : public ::YGNode { void reset(); }; +inline Node* resolveRef(const YGNodeRef ref) { + return static_cast(ref); +} + +inline const Node* resolveRef(const YGNodeConstRef ref) { + return static_cast(ref); +} + } // namespace facebook::yoga From 7f655e91962b38c90e5f3a69081ce8dfd4551a9a Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 11 Sep 2023 19:01:04 -0700 Subject: [PATCH 2/5] Breaking: Fix callback const-correctness (#1369) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1369 X-link: https://github.com/facebook/react-native/pull/39370 This fixes const-correctness of callbacks (e.g. not letting a logger function modify nodes during layout). This helps us to continue to fix const-correctness issues inside of Yoga. This change is breaking to the public API, since it requires a change in signature passed to Yoga. Changelog: [Internal] Differential Revision: https://internalfb.com/D49130714 fbshipit-source-id: 855a4fdb9dbeef284bd0f00cfa3af03d9d6fc328 --- benchmark/YGBenchmark.c | 2 +- java/jni/YGJNIVanilla.cpp | 12 ++++---- javascript/src/Node.cpp | 4 +-- tests/EventsTest.cpp | 5 ++-- tests/YGAlignBaselineTest.cpp | 6 ++-- tests/YGAspectRatioTest.cpp | 2 +- tests/YGBaselineFuncTest.cpp | 2 +- tests/YGDirtiedTest.cpp | 2 +- tests/YGDirtyMarkingTest.cpp | 2 +- tests/YGLoggerTest.cpp | 4 +-- tests/YGMeasureCacheTest.cpp | 6 ++-- tests/YGMeasureModeTest.cpp | 2 +- tests/YGMeasureTest.cpp | 10 +++---- tests/YGNodeCallbackTest.cpp | 46 ++++++++++++++++------------- tests/YGRoundingFunctionTest.cpp | 2 +- tests/YGRoundingMeasureFuncTest.cpp | 6 ++-- tests/generated/YGConfigTest.cpp | 15 ++++++---- yoga/Yoga.cpp | 24 ++++++--------- yoga/Yoga.h | 22 +++++++------- yoga/config/Config.cpp | 21 +++---------- yoga/config/Config.h | 12 ++++---- yoga/node/Node.h | 15 +++++++--- 22 files changed, 111 insertions(+), 111 deletions(-) diff --git a/benchmark/YGBenchmark.c b/benchmark/YGBenchmark.c index 443ed7e438..78aa2d2d6d 100644 --- a/benchmark/YGBenchmark.c +++ b/benchmark/YGBenchmark.c @@ -76,7 +76,7 @@ static void __printBenchmarkResult( } static YGSize _measure( - YGNodeRef node, + YGNodeConstRef node, float width, YGMeasureMode widthMode, float height, diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index 6a1406c170..af06c4a396 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -27,7 +27,7 @@ using namespace facebook::yoga; using namespace facebook::yoga::vanillajni; static inline ScopedLocalRef YGNodeJobject( - YGNodeRef node, + YGNodeConstRef node, void* layoutContext) { return reinterpret_cast(layoutContext)->ref(node); } @@ -138,8 +138,8 @@ static jlong jni_YGNodeNewWithConfigJNI( } static int YGJNILogFunc( - const YGConfigRef config, - const YGNodeRef /*node*/, + const YGConfigConstRef config, + const YGNodeConstRef /*node*/, YGLogLevel level, void* /*layoutContext*/, const char* format, @@ -639,7 +639,7 @@ static void jni_YGNodeStyleSetBorderJNI( yogaNodeRef, static_cast(edge), static_cast(border)); } -static void YGTransferLayoutDirection(YGNodeRef node, jobject javaNode) { +static void YGTransferLayoutDirection(YGNodeConstRef node, jobject javaNode) { // Don't change this field name without changing the name of the field in // Database.java JNIEnv* env = getCurrentEnv(); @@ -655,7 +655,7 @@ static void YGTransferLayoutDirection(YGNodeRef node, jobject javaNode) { } static YGSize YGJNIMeasureFunc( - YGNodeRef node, + YGNodeConstRef node, float width, YGMeasureMode widthMode, float height, @@ -700,7 +700,7 @@ static void jni_YGNodeSetHasMeasureFuncJNI( } static float YGJNIBaselineFunc( - YGNodeRef node, + YGNodeConstRef node, float width, float height, void* layoutContext) { diff --git a/javascript/src/Node.cpp b/javascript/src/Node.cpp index 2a1afa985c..7f4d674511 100644 --- a/javascript/src/Node.cpp +++ b/javascript/src/Node.cpp @@ -15,7 +15,7 @@ #include "./Config.h" static YGSize globalMeasureFunc( - YGNodeRef nodeRef, + YGNodeConstRef nodeRef, float width, YGMeasureMode widthMode, float height, @@ -29,7 +29,7 @@ static YGSize globalMeasureFunc( return ygSize; } -static void globalDirtiedFunc(YGNodeRef nodeRef) { +static void globalDirtiedFunc(YGNodeConstRef nodeRef) { Node const& node = *reinterpret_cast(YGNodeGetContext(nodeRef)); node.callDirtiedFunc(); diff --git a/tests/EventsTest.cpp b/tests/EventsTest.cpp index 11131d4333..7dcee28918 100644 --- a/tests/EventsTest.cpp +++ b/tests/EventsTest.cpp @@ -249,7 +249,7 @@ TEST_F(EventTest, layout_events_has_max_measure_cache) { TEST_F(EventTest, measure_functions_get_wrapped) { auto root = YGNodeNew(); YGNodeSetMeasureFunc( - root, [](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode) { + root, [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode) { return YGSize{}; }); @@ -267,7 +267,8 @@ TEST_F(EventTest, baseline_functions_get_wrapped) { auto child = YGNodeNew(); YGNodeInsertChild(root, child, 0); - YGNodeSetBaselineFunc(child, [](YGNodeRef, float, float) { return 0.0f; }); + YGNodeSetBaselineFunc( + child, [](YGNodeConstRef, float, float) { return 0.0f; }); YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); YGNodeStyleSetAlignItems(root, YGAlignBaseline); diff --git a/tests/YGAlignBaselineTest.cpp b/tests/YGAlignBaselineTest.cpp index df64a1517a..2750a474b6 100644 --- a/tests/YGAlignBaselineTest.cpp +++ b/tests/YGAlignBaselineTest.cpp @@ -9,14 +9,14 @@ #include static float _baselineFunc( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, const float /*width*/, const float height) { return height / 2; } static YGSize _measure1( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, @@ -25,7 +25,7 @@ static YGSize _measure1( } static YGSize _measure2( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp index 4a5fe60003..378f407165 100644 --- a/tests/YGAspectRatioTest.cpp +++ b/tests/YGAspectRatioTest.cpp @@ -9,7 +9,7 @@ #include static YGSize _measure( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float width, YGMeasureMode widthMode, float height, diff --git a/tests/YGBaselineFuncTest.cpp b/tests/YGBaselineFuncTest.cpp index 5888dcae88..d93910d489 100644 --- a/tests/YGBaselineFuncTest.cpp +++ b/tests/YGBaselineFuncTest.cpp @@ -9,7 +9,7 @@ #include static float _baseline( - YGNodeRef node, + YGNodeConstRef node, const float /*width*/, const float /*height*/) { float* baseline = (float*) YGNodeGetContext(node); diff --git a/tests/YGDirtiedTest.cpp b/tests/YGDirtiedTest.cpp index f996ac5f1b..6b9b38f685 100644 --- a/tests/YGDirtiedTest.cpp +++ b/tests/YGDirtiedTest.cpp @@ -11,7 +11,7 @@ using namespace facebook; -static void _dirtied(YGNodeRef node) { +static void _dirtied(YGNodeConstRef node) { int* dirtiedCount = (int*) YGNodeGetContext(node); (*dirtiedCount)++; } diff --git a/tests/YGDirtyMarkingTest.cpp b/tests/YGDirtyMarkingTest.cpp index b548a921e9..a032b27801 100644 --- a/tests/YGDirtyMarkingTest.cpp +++ b/tests/YGDirtyMarkingTest.cpp @@ -147,7 +147,7 @@ TEST(YogaTest, dirty_propagation_changing_benign_config) { YGConfigRef newConfig = YGConfigNew(); YGConfigSetLogger( newConfig, - [](const YGConfigRef, const YGNodeRef, YGLogLevel, const char*, va_list) { + [](YGConfigConstRef, YGNodeConstRef, YGLogLevel, const char*, va_list) { return 0; }); YGNodeSetConfig(root_child0, newConfig); diff --git a/tests/YGLoggerTest.cpp b/tests/YGLoggerTest.cpp index d1aa972741..276d3fe0ca 100644 --- a/tests/YGLoggerTest.cpp +++ b/tests/YGLoggerTest.cpp @@ -14,8 +14,8 @@ namespace { char writeBuffer[4096]; int _unmanagedLogger( - const YGConfigRef /*config*/, - const YGNodeRef /*node*/, + const YGConfigConstRef /*config*/, + const YGNodeConstRef /*node*/, YGLogLevel /*level*/, const char* format, va_list args) { diff --git a/tests/YGMeasureCacheTest.cpp b/tests/YGMeasureCacheTest.cpp index a973837413..f5d73520eb 100644 --- a/tests/YGMeasureCacheTest.cpp +++ b/tests/YGMeasureCacheTest.cpp @@ -9,7 +9,7 @@ #include static YGSize _measureMax( - YGNodeRef node, + YGNodeConstRef node, float width, YGMeasureMode widthMode, float height, @@ -24,7 +24,7 @@ static YGSize _measureMax( } static YGSize _measureMin( - YGNodeRef node, + YGNodeConstRef node, float width, YGMeasureMode widthMode, float height, @@ -44,7 +44,7 @@ static YGSize _measureMin( } static YGSize _measure_84_49( - YGNodeRef node, + YGNodeConstRef node, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, diff --git a/tests/YGMeasureModeTest.cpp b/tests/YGMeasureModeTest.cpp index e9f977aa4e..8825a02374 100644 --- a/tests/YGMeasureModeTest.cpp +++ b/tests/YGMeasureModeTest.cpp @@ -21,7 +21,7 @@ struct _MeasureConstraintList { }; static YGSize _measure( - YGNodeRef node, + YGNodeConstRef node, float width, YGMeasureMode widthMode, float height, diff --git a/tests/YGMeasureTest.cpp b/tests/YGMeasureTest.cpp index e6d851cdc2..cce30f8d2a 100644 --- a/tests/YGMeasureTest.cpp +++ b/tests/YGMeasureTest.cpp @@ -9,7 +9,7 @@ #include static YGSize _measure( - YGNodeRef node, + YGNodeConstRef node, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, @@ -23,7 +23,7 @@ static YGSize _measure( } static YGSize _simulate_wrapping_text( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float width, YGMeasureMode widthMode, float /*height*/, @@ -36,7 +36,7 @@ static YGSize _simulate_wrapping_text( } static YGSize _measure_assert_negative( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float width, YGMeasureMode /*widthMode*/, float height, @@ -640,7 +640,7 @@ TEST(YogaTest, cant_call_negative_measure_horizontal) { } static YGSize _measure_90_10( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, @@ -650,7 +650,7 @@ static YGSize _measure_90_10( } static YGSize _measure_100_100( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, diff --git a/tests/YGNodeCallbackTest.cpp b/tests/YGNodeCallbackTest.cpp index ec41bb43ba..e599af501b 100644 --- a/tests/YGNodeCallbackTest.cpp +++ b/tests/YGNodeCallbackTest.cpp @@ -22,9 +22,10 @@ TEST(Node, hasMeasureFunc_initial) { TEST(Node, hasMeasureFunc_with_measure_fn) { auto n = Node{}; - n.setMeasureFunc([](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode) { - return YGSize{}; - }); + n.setMeasureFunc( + [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode) { + return YGSize{}; + }); ASSERT_TRUE(n.hasMeasureFunc()); } @@ -32,7 +33,7 @@ TEST(Node, measure_with_measure_fn) { auto n = Node{}; n.setMeasureFunc( - [](YGNodeRef, float w, YGMeasureMode wm, float h, YGMeasureMode hm) { + [](YGNodeConstRef, float w, YGMeasureMode wm, float h, YGMeasureMode hm) { return YGSize{w * static_cast(wm), h / static_cast(hm)}; }); @@ -43,10 +44,12 @@ TEST(Node, measure_with_measure_fn) { TEST(Node, measure_with_context_measure_fn) { auto n = Node{}; - n.setMeasureFunc( - [](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode, void* ctx) { - return *(YGSize*) ctx; - }); + n.setMeasureFunc([](YGNodeConstRef, + float, + YGMeasureMode, + float, + YGMeasureMode, + void* ctx) { return *(YGSize*) ctx; }); auto result = YGSize{123.4f, -56.7f}; ASSERT_EQ( @@ -57,11 +60,11 @@ TEST(Node, measure_with_context_measure_fn) { TEST(Node, switching_measure_fn_types) { auto n = Node{}; n.setMeasureFunc( - [](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode, void*) { + [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode, void*) { return YGSize{}; }); n.setMeasureFunc( - [](YGNodeRef, float w, YGMeasureMode wm, float h, YGMeasureMode hm) { + [](YGNodeConstRef, float w, YGMeasureMode wm, float h, YGMeasureMode hm) { return YGSize{w * static_cast(wm), h / static_cast(hm)}; }); @@ -72,9 +75,10 @@ TEST(Node, switching_measure_fn_types) { TEST(Node, hasMeasureFunc_after_unset) { auto n = Node{}; - n.setMeasureFunc([](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode) { - return YGSize{}; - }); + n.setMeasureFunc( + [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode) { + return YGSize{}; + }); n.setMeasureFunc(nullptr); ASSERT_FALSE(n.hasMeasureFunc()); @@ -83,7 +87,7 @@ TEST(Node, hasMeasureFunc_after_unset) { TEST(Node, hasMeasureFunc_after_unset_context) { auto n = Node{}; n.setMeasureFunc( - [](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode, void*) { + [](YGNodeConstRef, float, YGMeasureMode, float, YGMeasureMode, void*) { return YGSize{}; }); @@ -98,20 +102,20 @@ TEST(Node, hasBaselineFunc_initial) { TEST(Node, hasBaselineFunc_with_baseline_fn) { auto n = Node{}; - n.setBaselineFunc([](YGNodeRef, float, float) { return 0.0f; }); + n.setBaselineFunc([](YGNodeConstRef, float, float) { return 0.0f; }); ASSERT_TRUE(n.hasBaselineFunc()); } TEST(Node, baseline_with_baseline_fn) { auto n = Node{}; - n.setBaselineFunc([](YGNodeRef, float w, float h) { return w + h; }); + n.setBaselineFunc([](YGNodeConstRef, float w, float h) { return w + h; }); ASSERT_EQ(n.baseline(1.25f, 2.5f, nullptr), 3.75f); } TEST(Node, baseline_with_context_baseline_fn) { auto n = Node{}; - n.setBaselineFunc([](YGNodeRef, float w, float h, void* ctx) { + n.setBaselineFunc([](YGNodeConstRef, float w, float h, void* ctx) { return w + h + *(float*) ctx; }); @@ -121,7 +125,7 @@ TEST(Node, baseline_with_context_baseline_fn) { TEST(Node, hasBaselineFunc_after_unset) { auto n = Node{}; - n.setBaselineFunc([](YGNodeRef, float, float) { return 0.0f; }); + n.setBaselineFunc([](YGNodeConstRef, float, float) { return 0.0f; }); n.setBaselineFunc(nullptr); ASSERT_FALSE(n.hasBaselineFunc()); @@ -129,7 +133,7 @@ TEST(Node, hasBaselineFunc_after_unset) { TEST(Node, hasBaselineFunc_after_unset_context) { auto n = Node{}; - n.setBaselineFunc([](YGNodeRef, float, float, void*) { return 0.0f; }); + n.setBaselineFunc([](YGNodeConstRef, float, float, void*) { return 0.0f; }); n.setMeasureFunc(nullptr); ASSERT_FALSE(n.hasMeasureFunc()); @@ -137,7 +141,7 @@ TEST(Node, hasBaselineFunc_after_unset_context) { TEST(Node, switching_baseline_fn_types) { auto n = Node{}; - n.setBaselineFunc([](YGNodeRef, float, float, void*) { return 0.0f; }); - n.setBaselineFunc([](YGNodeRef, float, float) { return 1.0f; }); + n.setBaselineFunc([](YGNodeConstRef, float, float, void*) { return 0.0f; }); + n.setBaselineFunc([](YGNodeConstRef, float, float) { return 1.0f; }); ASSERT_EQ(n.baseline(1, 2, nullptr), 1.0f); } diff --git a/tests/YGRoundingFunctionTest.cpp b/tests/YGRoundingFunctionTest.cpp index 4405b855d0..90b15f7e43 100644 --- a/tests/YGRoundingFunctionTest.cpp +++ b/tests/YGRoundingFunctionTest.cpp @@ -43,7 +43,7 @@ TEST(YogaTest, rounding_value) { } static YGSize measureText( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float /*width*/, YGMeasureMode /*widthMode*/, float /*height*/, diff --git a/tests/YGRoundingMeasureFuncTest.cpp b/tests/YGRoundingMeasureFuncTest.cpp index c5c3a3ab6b..045089d797 100644 --- a/tests/YGRoundingMeasureFuncTest.cpp +++ b/tests/YGRoundingMeasureFuncTest.cpp @@ -9,7 +9,7 @@ #include static YGSize _measureFloor( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float width, YGMeasureMode /*widthMode*/, float height, @@ -21,7 +21,7 @@ static YGSize _measureFloor( } static YGSize _measureCeil( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float width, YGMeasureMode /*widthMode*/, float height, @@ -33,7 +33,7 @@ static YGSize _measureCeil( } static YGSize _measureFractial( - YGNodeRef /*node*/, + YGNodeConstRef /*node*/, float width, YGMeasureMode /*widthMode*/, float height, diff --git a/tests/generated/YGConfigTest.cpp b/tests/generated/YGConfigTest.cpp index 8665d50023..4cfd90eff2 100644 --- a/tests/generated/YGConfigTest.cpp +++ b/tests/generated/YGConfigTest.cpp @@ -23,8 +23,12 @@ struct ConfigCloningTest : public ::testing::Test { void TearDown() override; static yoga::Node clonedNode; - static YGNodeRef cloneNode(YGNodeRef, YGNodeRef, int) { return &clonedNode; } - static YGNodeRef doNotClone(YGNodeRef, YGNodeRef, int) { return nullptr; } + static YGNodeRef cloneNode(YGNodeConstRef, YGNodeConstRef, int) { + return &clonedNode; + } + static YGNodeRef doNotClone(YGNodeConstRef, YGNodeConstRef, int) { + return nullptr; + } }; TEST_F(ConfigCloningTest, uses_values_provided_by_cloning_callback) { @@ -49,9 +53,10 @@ TEST_F( } TEST_F(ConfigCloningTest, can_clone_with_context) { - config->setCloneNodeCallback([](YGNodeRef, YGNodeRef, int, void* context) { - return (YGNodeRef) context; - }); + config->setCloneNodeCallback( + [](YGNodeConstRef, YGNodeConstRef, int, void* context) { + return (YGNodeRef) context; + }); yoga::Node node{}, owner{}, clone{}; ASSERT_EQ(config->cloneNode(&node, &owner, 0, &clone), &clone); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 1b81de2be5..0e89c06d8a 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -22,15 +22,15 @@ using namespace facebook::yoga; #ifdef ANDROID static int YGAndroidLog( - const YGConfigRef config, - const YGNodeRef node, + const YGConfigConstRef config, + const YGNodeConstRef node, YGLogLevel level, const char* format, va_list args); #else static int YGDefaultLog( - const YGConfigRef config, - const YGNodeRef node, + const YGConfigConstRef config, + const YGNodeConstRef node, YGLogLevel level, const char* format, va_list args); @@ -39,8 +39,8 @@ static int YGDefaultLog( #ifdef ANDROID #include static int YGAndroidLog( - const YGConfigRef /*config*/, - const YGNodeRef /*node*/, + const YGConfigConstRef /*config*/, + const YGNodeConstRef /*node*/, YGLogLevel level, const char* format, va_list args) { @@ -69,16 +69,12 @@ static int YGAndroidLog( return result; } #else -#define YG_UNUSED(x) (void) (x); - static int YGDefaultLog( - const YGConfigRef config, - const YGNodeRef node, + const YGConfigConstRef /*config*/, + const YGNodeConstRef /*node*/, YGLogLevel level, const char* format, va_list args) { - YG_UNUSED(config); - YG_UNUSED(node); switch (level) { case YGLogLevelError: case YGLogLevelFatal: @@ -91,8 +87,6 @@ static int YGDefaultLog( return vprintf(format, args); } } - -#undef YG_UNUSED #endif YOGA_EXPORT bool YGFloatIsUndefined(const float value) { @@ -202,7 +196,7 @@ YOGA_EXPORT YGNodeRef YGNodeNew(void) { return YGNodeNewWithConfig(YGConfigGetDefault()); } -YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNodeRef) { +YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeConstRef oldNodeRef) { auto oldNode = resolveRef(oldNodeRef); const auto node = new yoga::Node(*oldNode); yoga::assertFatalWithConfig( diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 54569adc5d..fa5b9834ec 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -29,28 +29,30 @@ typedef struct YGNode* YGNodeRef; typedef const struct YGNode* YGNodeConstRef; typedef YGSize (*YGMeasureFunc)( - YGNodeRef node, + YGNodeConstRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); -typedef float (*YGBaselineFunc)(YGNodeRef node, float width, float height); -typedef void (*YGDirtiedFunc)(YGNodeRef node); -typedef void (*YGPrintFunc)(YGNodeRef node); -typedef void (*YGNodeCleanupFunc)(YGNodeRef node); +typedef float (*YGBaselineFunc)(YGNodeConstRef node, float width, float height); +typedef void (*YGDirtiedFunc)(YGNodeConstRef node); +typedef void (*YGPrintFunc)(YGNodeConstRef node); +typedef void (*YGNodeCleanupFunc)(YGNodeConstRef node); typedef int (*YGLogger)( - YGConfigRef config, - YGNodeRef node, + YGConfigConstRef config, + YGNodeConstRef node, YGLogLevel level, const char* format, va_list args); -typedef YGNodeRef ( - *YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex); +typedef YGNodeRef (*YGCloneNodeFunc)( + YGNodeConstRef oldNode, + YGNodeConstRef owner, + int childIndex); // YGNode WIN_EXPORT YGNodeRef YGNodeNew(void); WIN_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigRef config); -WIN_EXPORT YGNodeRef YGNodeClone(YGNodeRef node); +WIN_EXPORT YGNodeRef YGNodeClone(YGNodeConstRef node); WIN_EXPORT void YGNodeFree(YGNodeRef node); WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( YGNodeRef node, diff --git a/yoga/config/Config.cpp b/yoga/config/Config.cpp index 3032a5b7d1..deb7b5fe4d 100644 --- a/yoga/config/Config.cpp +++ b/yoga/config/Config.cpp @@ -107,23 +107,10 @@ void Config::log( void* logContext, const char* format, va_list args) const { - // TODO: Break log callback signatures to make them const correct - if (flags_.loggerUsesContext) { - logger_.withContext( - const_cast(this), - const_cast(node), - logLevel, - logContext, - format, - args); + logger_.withContext(this, node, logLevel, logContext, format, args); } else { - logger_.noContext( - const_cast(this), - const_cast(node), - logLevel, - format, - args); + logger_.noContext(this, node, logLevel, format, args); } } @@ -142,8 +129,8 @@ void Config::setCloneNodeCallback(std::nullptr_t) { } YGNodeRef Config::cloneNode( - YGNodeRef node, - YGNodeRef owner, + YGNodeConstRef node, + YGNodeConstRef owner, int childIndex, void* cloneContext) const { YGNodeRef clone = nullptr; diff --git a/yoga/config/Config.h b/yoga/config/Config.h index 0a422c9c29..75bde993b6 100644 --- a/yoga/config/Config.h +++ b/yoga/config/Config.h @@ -25,15 +25,15 @@ bool configUpdateInvalidatesLayout(Config* a, Config* b); // Internal variants of log functions, currently used only by JNI bindings. // TODO: Reconcile this with the public API using LogWithContextFn = int (*)( - YGConfigRef config, - YGNodeRef node, + YGConfigConstRef config, + YGNodeConstRef node, YGLogLevel level, void* context, const char* format, va_list args); using CloneWithContextFn = YGNodeRef (*)( - YGNodeRef node, - YGNodeRef owner, + YGNodeConstRef node, + YGNodeConstRef owner, int childIndex, void* cloneContext); @@ -90,8 +90,8 @@ class YOGA_EXPORT Config : public ::YGConfig { void setCloneNodeCallback(CloneWithContextFn cloneNode); void setCloneNodeCallback(std::nullptr_t); YGNodeRef cloneNode( - YGNodeRef node, - YGNodeRef owner, + YGNodeConstRef node, + YGNodeConstRef owner, int childIndex, void* cloneContext) const; diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 8a21d43060..4e8ef24ede 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -38,10 +38,17 @@ struct NodeFlags { class YOGA_EXPORT Node : public ::YGNode { public: - using MeasureWithContextFn = - YGSize (*)(YGNode*, float, YGMeasureMode, float, YGMeasureMode, void*); - using BaselineWithContextFn = float (*)(YGNode*, float, float, void*); - using PrintWithContextFn = void (*)(YGNode*, void*); + // Internal variants of callbacks, currently used only by JNI bindings. + // TODO: Reconcile this with the public API + using MeasureWithContextFn = YGSize (*)( + YGNodeConstRef, + float, + YGMeasureMode, + float, + YGMeasureMode, + void*); + using BaselineWithContextFn = float (*)(YGNodeConstRef, float, float, void*); + using PrintWithContextFn = void (*)(YGNodeConstRef, void*); private: void* context_ = nullptr; From 4ff608c4aac537ea47017b607db13022831c9751 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 11 Sep 2023 19:01:04 -0700 Subject: [PATCH 3/5] Breaking: size_t indices Summary: Yoga's public API exposes indices most often as `uint32_t`, with exception of clone callbacks which are `int32_t`. Yoga internally represents these indices as `size_t` when dealing with the child vector, and this is the true index. This changes the API to consistently be `size_t`. This should not be breaking for most users, but will cause breaks where: 1. Users set a clone node callback (I think this should be rare. RN uses it, but only because it relies on a separate private API). 2. Callers of `YGNodeGetChildCount()` are assigning to an int with less width than `size_t` and have strong warnings enabled. 3. Using a newer Yoga binary with older source, since we are not preserving ABI compatibility (Yoga in general does not aim to be ABI stable between major versions, only ABI safe for a given set of sources). Differential Revision: D49130914 fbshipit-source-id: 31ad14864f94952d36e36e5b99df6d82caf5ea16 --- java/jni/YGJNIVanilla.cpp | 2 +- tests/{generated => }/YGConfigTest.cpp | 8 ++--- tests/YGTreeMutationTest.cpp | 4 +-- yoga/Yoga.cpp | 30 +++++++++--------- yoga/Yoga.h | 16 +++++----- yoga/algorithm/Baseline.cpp | 4 +-- yoga/algorithm/CalculateLayout.cpp | 36 ++++++++++------------ yoga/algorithm/CollectFlexItemsRowValues.h | 4 +-- yoga/algorithm/PixelGrid.cpp | 4 +-- yoga/config/Config.cpp | 2 +- yoga/config/Config.h | 4 +-- yoga/debug/NodeToString.cpp | 4 +-- yoga/node/Node.cpp | 2 +- yoga/node/Node.h | 6 ++-- 14 files changed, 60 insertions(+), 66 deletions(-) rename tests/{generated => }/YGConfigTest.cpp (85%) diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index af06c4a396..a95a00340d 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -362,7 +362,7 @@ static void YGTransferLayoutOutputsRecursive( YGNodeSetHasNewLayout(root, false); - for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) { + for (size_t i = 0; i < YGNodeGetChildCount(root); i++) { YGTransferLayoutOutputsRecursive( env, thiz, YGNodeGetChild(root, i), layoutContext); } diff --git a/tests/generated/YGConfigTest.cpp b/tests/YGConfigTest.cpp similarity index 85% rename from tests/generated/YGConfigTest.cpp rename to tests/YGConfigTest.cpp index 4cfd90eff2..0a3e128a25 100644 --- a/tests/generated/YGConfigTest.cpp +++ b/tests/YGConfigTest.cpp @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -// @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html - #include #include #include @@ -23,10 +21,10 @@ struct ConfigCloningTest : public ::testing::Test { void TearDown() override; static yoga::Node clonedNode; - static YGNodeRef cloneNode(YGNodeConstRef, YGNodeConstRef, int) { + static YGNodeRef cloneNode(YGNodeConstRef, YGNodeConstRef, size_t) { return &clonedNode; } - static YGNodeRef doNotClone(YGNodeConstRef, YGNodeConstRef, int) { + static YGNodeRef doNotClone(YGNodeConstRef, YGNodeConstRef, size_t) { return nullptr; } }; @@ -54,7 +52,7 @@ TEST_F( TEST_F(ConfigCloningTest, can_clone_with_context) { config->setCloneNodeCallback( - [](YGNodeConstRef, YGNodeConstRef, int, void* context) { + [](YGNodeConstRef, YGNodeConstRef, size_t, void* context) { return (YGNodeRef) context; }); diff --git a/tests/YGTreeMutationTest.cpp b/tests/YGTreeMutationTest.cpp index 5c0cc51859..301d0989f7 100644 --- a/tests/YGTreeMutationTest.cpp +++ b/tests/YGTreeMutationTest.cpp @@ -9,10 +9,10 @@ #include static std::vector getChildren(YGNodeRef const node) { - const uint32_t count = YGNodeGetChildCount(node); + const auto count = YGNodeGetChildCount(node); std::vector children; children.reserve(count); - for (uint32_t i = 0; i < count; i++) { + for (size_t i = 0; i < count; i++) { children.push_back(YGNodeGetChild(node, i)); } return children; diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 0e89c06d8a..9a91e032bc 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -216,8 +216,8 @@ YOGA_EXPORT void YGNodeFree(const YGNodeRef nodeRef) { node->setOwner(nullptr); } - const uint32_t childCount = YGNodeGetChildCount(node); - for (uint32_t i = 0; i < childCount; i++) { + const size_t childCount = node->getChildCount(); + for (size_t i = 0; i < childCount; i++) { auto child = node->getChild(i); child->setOwner(nullptr); } @@ -236,8 +236,8 @@ YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( YGNodeCleanupFunc cleanup) { const auto root = resolveRef(rootRef); - uint32_t skipped = 0; - while (YGNodeGetChildCount(root) > skipped) { + size_t skipped = 0; + while (root->getChildCount() > skipped) { const auto child = root->getChild(skipped); if (child->getOwner() != root) { // Don't free shared nodes that we don't own. @@ -297,7 +297,7 @@ YOGA_EXPORT bool YGNodeIsReferenceBaseline(YGNodeConstRef node) { YOGA_EXPORT void YGNodeInsertChild( const YGNodeRef ownerRef, const YGNodeRef childRef, - const uint32_t index) { + const size_t index) { auto owner = resolveRef(ownerRef); auto child = resolveRef(childRef); @@ -319,7 +319,7 @@ YOGA_EXPORT void YGNodeInsertChild( YOGA_EXPORT void YGNodeSwapChild( const YGNodeRef ownerRef, const YGNodeRef childRef, - const uint32_t index) { + const size_t index) { auto owner = resolveRef(ownerRef); auto child = resolveRef(childRef); @@ -333,7 +333,7 @@ YOGA_EXPORT void YGNodeRemoveChild( auto owner = resolveRef(ownerRef); auto excludedChild = resolveRef(excludedChildRef); - if (YGNodeGetChildCount(owner) == 0) { + if (owner->getChildCount() == 0) { // This is an empty set. Nothing to remove. return; } @@ -354,7 +354,7 @@ YOGA_EXPORT void YGNodeRemoveChild( YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef ownerRef) { auto owner = resolveRef(ownerRef); - const uint32_t childCount = YGNodeGetChildCount(owner); + const size_t childCount = owner->getChildCount(); if (childCount == 0) { // This is an empty set already. Nothing to do. return; @@ -363,7 +363,7 @@ YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef ownerRef) { if (firstChild->getOwner() == owner) { // If the first child has this node as its owner, we assume that this child // set is unique. - for (uint32_t i = 0; i < childCount; i++) { + for (size_t i = 0; i < childCount; i++) { yoga::Node* oldChild = owner->getChild(i); oldChild->setLayout({}); // layout is no longer valid oldChild->setOwner(nullptr); @@ -381,7 +381,7 @@ YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef ownerRef) { YOGA_EXPORT void YGNodeSetChildren( const YGNodeRef ownerRef, const YGNodeRef* childrenRefs, - const uint32_t count) { + const size_t count) { auto owner = resolveRef(ownerRef); auto children = reinterpret_cast(childrenRefs); @@ -391,7 +391,7 @@ YOGA_EXPORT void YGNodeSetChildren( const std::vector childrenVector = {children, children + count}; if (childrenVector.size() == 0) { - if (YGNodeGetChildCount(owner) > 0) { + if (owner->getChildCount() > 0) { for (auto* child : owner->getChildren()) { child->setLayout({}); child->setOwner(nullptr); @@ -400,7 +400,7 @@ YOGA_EXPORT void YGNodeSetChildren( owner->markDirtyAndPropagate(); } } else { - if (YGNodeGetChildCount(owner) > 0) { + if (owner->getChildCount() > 0) { for (auto* oldChild : owner->getChildren()) { // Our new children may have nodes in common with the old children. We // don't reset these common nodes. @@ -420,7 +420,7 @@ YOGA_EXPORT void YGNodeSetChildren( } YOGA_EXPORT YGNodeRef -YGNodeGetChild(const YGNodeRef nodeRef, const uint32_t index) { +YGNodeGetChild(const YGNodeRef nodeRef, const size_t index) { const auto node = resolveRef(nodeRef); if (index < node->getChildren().size()) { @@ -429,8 +429,8 @@ YGNodeGetChild(const YGNodeRef nodeRef, const uint32_t index) { return nullptr; } -YOGA_EXPORT uint32_t YGNodeGetChildCount(const YGNodeConstRef node) { - return static_cast(resolveRef(node)->getChildren().size()); +YOGA_EXPORT size_t YGNodeGetChildCount(const YGNodeConstRef node) { + return resolveRef(node)->getChildren().size(); } YOGA_EXPORT YGNodeRef YGNodeGetOwner(const YGNodeRef node) { diff --git a/yoga/Yoga.h b/yoga/Yoga.h index fa5b9834ec..41464e1ee5 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -47,7 +48,7 @@ typedef int (*YGLogger)( typedef YGNodeRef (*YGCloneNodeFunc)( YGNodeConstRef oldNode, YGNodeConstRef owner, - int childIndex); + size_t childIndex); // YGNode WIN_EXPORT YGNodeRef YGNodeNew(void); @@ -63,23 +64,20 @@ WIN_EXPORT void YGNodeReset(YGNodeRef node); WIN_EXPORT void YGNodeInsertChild( YGNodeRef node, YGNodeRef child, - uint32_t index); + size_t index); -WIN_EXPORT void YGNodeSwapChild( - YGNodeRef node, - YGNodeRef child, - uint32_t index); +WIN_EXPORT void YGNodeSwapChild(YGNodeRef node, YGNodeRef child, size_t index); WIN_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); WIN_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node); -WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index); +WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, size_t index); WIN_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node); WIN_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node); -WIN_EXPORT uint32_t YGNodeGetChildCount(YGNodeConstRef node); +WIN_EXPORT size_t YGNodeGetChildCount(YGNodeConstRef node); WIN_EXPORT void YGNodeSetChildren( YGNodeRef owner, const YGNodeRef* children, - uint32_t count); + size_t count); WIN_EXPORT void YGNodeSetIsReferenceBaseline( YGNodeRef node, diff --git a/yoga/algorithm/Baseline.cpp b/yoga/algorithm/Baseline.cpp index 6fb256c7bd..5042074a1e 100644 --- a/yoga/algorithm/Baseline.cpp +++ b/yoga/algorithm/Baseline.cpp @@ -34,8 +34,8 @@ float calculateBaseline(const yoga::Node* node, void* layoutContext) { } yoga::Node* baselineChild = nullptr; - const uint32_t childCount = YGNodeGetChildCount(node); - for (uint32_t i = 0; i < childCount; i++) { + const size_t childCount = node->getChildCount(); + for (size_t i = 0; i < childCount; i++) { auto child = node->getChild(i); if (child->getLineIndex() > 0) { break; diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index d94de53021..7d6c931cc3 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -965,8 +965,8 @@ static CollectFlexItemsRowValues calculateCollectFlexItemsRowValues( const float mainAxisownerSize, const float availableInnerWidth, const float availableInnerMainDim, - const uint32_t startOfLineIndex, - const uint32_t lineCount) { + const size_t startOfLineIndex, + const size_t lineCount) { CollectFlexItemsRowValues flexAlgoRowMeasurement = {}; flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size()); @@ -977,7 +977,7 @@ static CollectFlexItemsRowValues calculateCollectFlexItemsRowValues( const float gap = node->getGapForAxis(mainAxis, availableInnerWidth).unwrap(); // Add items to the current line until it's full or we run out of items. - uint32_t endOfLineIndex = startOfLineIndex; + size_t endOfLineIndex = startOfLineIndex; for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { auto child = node->getChild(endOfLineIndex); if (child->getStyle().display() == YGDisplayNone || @@ -1408,7 +1408,7 @@ static void resolveFlexibleLength( static void YGJustifyMainAxis( yoga::Node* const node, CollectFlexItemsRowValues& collectedFlexItemsValues, - const uint32_t startOfLineIndex, + const size_t startOfLineIndex, const YGFlexDirection mainAxis, const YGFlexDirection crossAxis, const YGMeasureMode measureModeMainDim, @@ -1456,8 +1456,7 @@ static void YGJustifyMainAxis( } int numberOfAutoMarginsOnCurrentLine = 0; - for (uint32_t i = startOfLineIndex; - i < collectedFlexItemsValues.endOfLineIndex; + for (size_t i = startOfLineIndex; i < collectedFlexItemsValues.endOfLineIndex; i++) { auto child = node->getChild(i); if (child->getStyle().positionType() != YGPositionTypeAbsolute) { @@ -1517,8 +1516,7 @@ static void YGJustifyMainAxis( float maxAscentForCurrentLine = 0; float maxDescentForCurrentLine = 0; bool isNodeBaselineLayout = isBaselineLayout(node); - for (uint32_t i = startOfLineIndex; - i < collectedFlexItemsValues.endOfLineIndex; + for (size_t i = startOfLineIndex; i < collectedFlexItemsValues.endOfLineIndex; i++) { const auto child = node->getChild(i); const Style& childStyle = child->getStyle(); @@ -1906,11 +1904,11 @@ static void calculateLayoutImpl( // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES // Indexes of children that represent the first and last items in the line. - uint32_t startOfLineIndex = 0; - uint32_t endOfLineIndex = 0; + size_t startOfLineIndex = 0; + size_t endOfLineIndex = 0; // Number of lines. - uint32_t lineCount = 0; + size_t lineCount = 0; // Accumulated cross dimensions of all lines so far. float totalLineCrossDim = 0; @@ -2093,7 +2091,7 @@ static void calculateLayoutImpl( // STEP 7: CROSS-AXIS ALIGNMENT // We can skip child alignment if we're just measuring the container. if (performLayout) { - for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) { + for (size_t i = startOfLineIndex; i < endOfLineIndex; i++) { const auto child = node->getChild(i); if (child->getStyle().display() == YGDisplayNone) { continue; @@ -2291,10 +2289,10 @@ static void calculateLayoutImpl( break; } } - uint32_t endIndex = 0; - for (uint32_t i = 0; i < lineCount; i++) { - const uint32_t startIndex = endIndex; - uint32_t ii; + size_t endIndex = 0; + for (size_t i = 0; i < lineCount; i++) { + const size_t startIndex = endIndex; + size_t ii; // compute the line's height and find the endIndex float lineHeight = 0; @@ -2537,7 +2535,7 @@ static void calculateLayoutImpl( // As we only wrapped in normal direction yet, we need to reverse the // positions on wrap-reverse. if (performLayout && node->getStyle().flexWrap() == YGWrapWrapReverse) { - for (uint32_t i = 0; i < childCount; i++) { + for (size_t i = 0; i < childCount; i++) { const auto child = node->getChild(i); if (child->getStyle().positionType() != YGPositionTypeAbsolute) { child->setLayoutPosition( @@ -2586,7 +2584,7 @@ static void calculateLayoutImpl( // Set trailing position if necessary. if (needsMainTrailingPos || needsCrossTrailingPos) { - for (uint32_t i = 0; i < childCount; i++) { + for (size_t i = 0; i < childCount; i++) { const auto child = node->getChild(i); if (child->getStyle().display() == YGDisplayNone) { continue; @@ -2710,7 +2708,7 @@ bool calculateLayoutInternal( cachedResults = &layout->cachedLayout; } else { // Try to use the measurement cache. - for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + for (size_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { if (canUseCachedMeasurement( widthMeasureMode, availableWidth, diff --git a/yoga/algorithm/CollectFlexItemsRowValues.h b/yoga/algorithm/CollectFlexItemsRowValues.h index 58a3916ac3..f3ba7e2947 100644 --- a/yoga/algorithm/CollectFlexItemsRowValues.h +++ b/yoga/algorithm/CollectFlexItemsRowValues.h @@ -39,11 +39,11 @@ namespace facebook::yoga { // and/or grow. struct CollectFlexItemsRowValues { - uint32_t itemsOnLine; + size_t itemsOnLine; float sizeConsumedOnCurrentLine; float totalFlexGrowFactors; float totalFlexShrinkScaledFactors; - uint32_t endOfLineIndex; + size_t endOfLineIndex; std::vector relativeChildren; float remainingFreeSpace; // The size of the mainDim for the row after considering size, padding, margin diff --git a/yoga/algorithm/PixelGrid.cpp b/yoga/algorithm/PixelGrid.cpp index 105e57a315..0a4bda2213 100644 --- a/yoga/algorithm/PixelGrid.cpp +++ b/yoga/algorithm/PixelGrid.cpp @@ -125,8 +125,8 @@ void roundLayoutResultsToPixelGrid( absoluteNodeTop, pointScaleFactor, false, textRounding), YGDimensionHeight); - const uint32_t childCount = YGNodeGetChildCount(node); - for (uint32_t i = 0; i < childCount; i++) { + const size_t childCount = node->getChildCount(); + for (size_t i = 0; i < childCount; i++) { roundLayoutResultsToPixelGrid( node->getChild(i), pointScaleFactor, absoluteNodeLeft, absoluteNodeTop); } diff --git a/yoga/config/Config.cpp b/yoga/config/Config.cpp index deb7b5fe4d..f4dea8433c 100644 --- a/yoga/config/Config.cpp +++ b/yoga/config/Config.cpp @@ -131,7 +131,7 @@ void Config::setCloneNodeCallback(std::nullptr_t) { YGNodeRef Config::cloneNode( YGNodeConstRef node, YGNodeConstRef owner, - int childIndex, + size_t childIndex, void* cloneContext) const { YGNodeRef clone = nullptr; if (cloneNodeCallback_.noContext != nullptr) { diff --git a/yoga/config/Config.h b/yoga/config/Config.h index 75bde993b6..d06b1bacf7 100644 --- a/yoga/config/Config.h +++ b/yoga/config/Config.h @@ -34,7 +34,7 @@ using LogWithContextFn = int (*)( using CloneWithContextFn = YGNodeRef (*)( YGNodeConstRef node, YGNodeConstRef owner, - int childIndex, + size_t childIndex, void* cloneContext); #pragma pack(push) @@ -92,7 +92,7 @@ class YOGA_EXPORT Config : public ::YGConfig { YGNodeRef cloneNode( YGNodeConstRef node, YGNodeConstRef owner, - int childIndex, + size_t childIndex, void* cloneContext) const; private: diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index 30697dd6ed..787ec976e4 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -227,9 +227,9 @@ void nodeToString( } appendFormattedString(str, ">"); - const uint32_t childCount = static_cast(node->getChildren().size()); + const size_t childCount = node->getChildCount(); if (options & YGPrintOptionsChildren && childCount > 0) { - for (uint32_t i = 0; i < childCount; i++) { + for (size_t i = 0; i < childCount; i++) { appendFormattedString(str, "\n"); nodeToString(str, node->getChild(i), options, level + 1); } diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index 295f4eb9c6..005542dae1 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -484,7 +484,7 @@ YOGA_EXPORT void Node::clearChildren() { // Other Methods void Node::cloneChildrenIfNeeded(void* cloneContext) { - int i = 0; + size_t i = 0; for (Node*& child : children_) { if (child->getOwner() != this) { child = resolveRef(config_->cloneNode(child, this, i, cloneContext)); diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 4e8ef24ede..e99a376425 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -68,7 +68,7 @@ class YOGA_EXPORT Node : public ::YGNode { YGDirtiedFunc dirtied_ = nullptr; Style style_ = {}; LayoutResults layout_ = {}; - uint32_t lineIndex_ = 0; + size_t lineIndex_ = 0; Node* owner_ = nullptr; std::vector children_ = {}; Config* config_; @@ -146,7 +146,7 @@ class YOGA_EXPORT Node : public ::YGNode { const LayoutResults& getLayout() const { return layout_; } - uint32_t getLineIndex() const { return lineIndex_; } + size_t getLineIndex() const { return lineIndex_; } bool isReferenceBaseline() const { return flags_.isReferenceBaseline; } @@ -276,7 +276,7 @@ class YOGA_EXPORT Node : public ::YGNode { void setLayout(const LayoutResults& layout) { layout_ = layout; } - void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; } + void setLineIndex(size_t lineIndex) { lineIndex_ = lineIndex; } void setIsReferenceBaseline(bool isReferenceBaseline) { flags_.isReferenceBaseline = isReferenceBaseline; From b11e4067ce7d6dd5c8fec8dd63769fa54f7267a8 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 11 Sep 2023 19:01:04 -0700 Subject: [PATCH 4/5] Breaking: Remove YGConfigGetInstanceCount Summary: This was added in https://github.com/facebook/yoga/pull/497 specifically for tests related to memory leaks in the C# bindings to count how often YGConfigFree. This is the wrong layer for this check, we don't have officially supported C# bindings anymore, and this API is not safe when Yoga runs on multiple threads. This removes it. Differential Revision: D49131207 fbshipit-source-id: 72423f737c3cabf5c44a7b9793c47450da58fb44 --- yoga/Yoga.cpp | 8 -------- yoga/Yoga.h | 1 - 2 files changed, 9 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 9a91e032bc..b9a5961d44 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -172,8 +172,6 @@ YOGA_EXPORT void YGNodeMarkDirtyAndPropagateToDescendants( return resolveRef(node)->markDirtyAndPropagateDownwards(); } -int32_t gConfigInstanceCount = 0; - YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { auto* node = new yoga::Node{resolveRef(config)}; yoga::assertFatal( @@ -261,23 +259,17 @@ YOGA_EXPORT void YGNodeReset(YGNodeRef node) { resolveRef(node)->reset(); } -YOGA_EXPORT int32_t YGConfigGetInstanceCount(void) { - return gConfigInstanceCount; -} - YOGA_EXPORT YGConfigRef YGConfigNew(void) { #ifdef ANDROID const YGConfigRef config = new yoga::Config(YGAndroidLog); #else const YGConfigRef config = new yoga::Config(YGDefaultLog); #endif - gConfigInstanceCount++; return config; } YOGA_EXPORT void YGConfigFree(const YGConfigRef config) { delete resolveRef(config); - gConfigInstanceCount--; } YOGA_EXPORT void YGNodeSetIsReferenceBaseline( diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 41464e1ee5..c9efb85fd8 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -330,7 +330,6 @@ void YGConfigSetUseLegacyStretchBehaviour( // YGConfig WIN_EXPORT YGConfigRef YGConfigNew(void); WIN_EXPORT void YGConfigFree(YGConfigRef config); -WIN_EXPORT int32_t YGConfigGetInstanceCount(void); WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled( YGConfigRef config, From 66ac052141b494427ceea198c3664129b7c408c2 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 11 Sep 2023 19:01:20 -0700 Subject: [PATCH 5/5] Breaking: Remove "UseLegacyStretchBehaviour" functions (#1368) Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1368 X-link: https://github.com/facebook/react-native/pull/39372 These were marked as deprecated as part of the public Yoga 2.0 release, and were alredy emitting deprecation warnings. Remove them. Reviewed By: javache Differential Revision: D49131250 fbshipit-source-id: 1959e0a330f49ec4ce99303b66354aafb20aa26b --- java/com/facebook/yoga/YogaConfig.java | 12 ----------- java/com/facebook/yoga/YogaConfigJNIBase.java | 9 -------- java/com/facebook/yoga/YogaNative.java | 1 - java/jni/YGJNIVanilla.cpp | 15 ------------- .../tests/com/facebook/yoga/YogaNodeTest.java | 2 +- javascript/src/Config.cpp | 14 ------------- javascript/src/Config.h | 2 -- javascript/src/embind.cpp | 3 --- javascript/src/wrapAssembly.d.ts | 12 ----------- yoga/Yoga.cpp | 15 ------------- yoga/Yoga.h | 21 ------------------- 11 files changed, 1 insertion(+), 105 deletions(-) diff --git a/java/com/facebook/yoga/YogaConfig.java b/java/com/facebook/yoga/YogaConfig.java index 931313594b..bd7b2998ce 100644 --- a/java/com/facebook/yoga/YogaConfig.java +++ b/java/com/facebook/yoga/YogaConfig.java @@ -18,18 +18,6 @@ public abstract class YogaConfig { public abstract void setPrintTreeFlag(boolean enable); public abstract void setPointScaleFactor(float pixelsInPoint); - /** - * Yoga previously had an error where containers would take the maximum space possible instead of the minimum - * like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch; - * Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour. - * - * @deprecated "setUseLegacyStretchBehaviour" will be removed in the next release. Usage should be replaced with - * "setErrata(YogaErrata.ALL)" to opt out of all future breaking conformance fixes, or - * "setErrata(YogaErrata.STRETCH_FLEX_BASIS)" to opt out of the specific conformance fix previously disabled by - * "UseLegacyStretchBehaviour". - */ - @Deprecated - public abstract void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour); public abstract void setErrata(YogaErrata errata); diff --git a/java/com/facebook/yoga/YogaConfigJNIBase.java b/java/com/facebook/yoga/YogaConfigJNIBase.java index bbe526d700..8e7c94921c 100644 --- a/java/com/facebook/yoga/YogaConfigJNIBase.java +++ b/java/com/facebook/yoga/YogaConfigJNIBase.java @@ -43,15 +43,6 @@ public void setPointScaleFactor(float pixelsInPoint) { YogaNative.jni_YGConfigSetPointScaleFactorJNI(mNativePointer, pixelsInPoint); } - /** - * Yoga previously had an error where containers would take the maximum space possible instead of the minimum - * like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch; - * Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour. - */ - public void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour) { - YogaNative.jni_YGConfigSetUseLegacyStretchBehaviourJNI(mNativePointer, useLegacyStretchBehaviour); - } - public void setErrata(YogaErrata errata) { YogaNative.jni_YGConfigSetErrataJNI(mNativePointer, errata.intValue()); } diff --git a/java/com/facebook/yoga/YogaNative.java b/java/com/facebook/yoga/YogaNative.java index 74f4a98cb4..89e3cde6b0 100644 --- a/java/com/facebook/yoga/YogaNative.java +++ b/java/com/facebook/yoga/YogaNative.java @@ -24,7 +24,6 @@ public class YogaNative { static native void jni_YGConfigSetUseWebDefaultsJNI(long nativePointer, boolean useWebDefaults); static native void jni_YGConfigSetPrintTreeFlagJNI(long nativePointer, boolean enable); static native void jni_YGConfigSetPointScaleFactorJNI(long nativePointer, float pixelsInPoint); - static native void jni_YGConfigSetUseLegacyStretchBehaviourJNI(long nativePointer, boolean useLegacyStretchBehaviour); static native void jni_YGConfigSetErrataJNI(long nativePointer, int errata); static native int jni_YGConfigGetErrataJNI(long nativePointer); static native void jni_YGConfigSetLoggerJNI(long nativePointer, YogaLogger logger); diff --git a/java/jni/YGJNIVanilla.cpp b/java/jni/YGJNIVanilla.cpp index a95a00340d..86f740e1f5 100644 --- a/java/jni/YGJNIVanilla.cpp +++ b/java/jni/YGJNIVanilla.cpp @@ -93,18 +93,6 @@ static void jni_YGConfigSetPointScaleFactorJNI( YGConfigSetPointScaleFactor(config, pixelsInPoint); } -static void jni_YGConfigSetUseLegacyStretchBehaviourJNI( - JNIEnv* /*env*/, - jobject /*obj*/, - jlong nativePointer, - jboolean useLegacyStretchBehaviour) { - const YGConfigRef config = _jlong2YGConfigRef(nativePointer); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" - YGConfigSetUseLegacyStretchBehaviour(config, useLegacyStretchBehaviour); -#pragma clang diagnostic pop -} - static void jni_YGConfigSetErrataJNI( JNIEnv* /*env*/, jobject /*obj*/, @@ -790,9 +778,6 @@ static JNINativeMethod methods[] = { {"jni_YGConfigSetPointScaleFactorJNI", "(JF)V", (void*) jni_YGConfigSetPointScaleFactorJNI}, - {"jni_YGConfigSetUseLegacyStretchBehaviourJNI", - "(JZ)V", - (void*) jni_YGConfigSetUseLegacyStretchBehaviourJNI}, {"jni_YGConfigSetErrataJNI", "(JI)V", (void*) jni_YGConfigSetErrataJNI}, {"jni_YGConfigGetErrataJNI", "(J)I", (void*) jni_YGConfigGetErrataJNI}, {"jni_YGConfigSetLoggerJNI", diff --git a/java/tests/com/facebook/yoga/YogaNodeTest.java b/java/tests/com/facebook/yoga/YogaNodeTest.java index 3dfdd81e1a..8341d1cf5f 100644 --- a/java/tests/com/facebook/yoga/YogaNodeTest.java +++ b/java/tests/com/facebook/yoga/YogaNodeTest.java @@ -292,7 +292,7 @@ public void directionIsPassedThrough() { @Test public void testResetApiShouldResetAllLayoutOutputs() { YogaConfig config = YogaConfigFactory.create(); - config.setUseLegacyStretchBehaviour(true); + config.setErrata(YogaErrata.STRETCH_FLEX_BASIS); YogaNode node = createNode(config); node.setWidth(100); node.setHeight(100); diff --git a/javascript/src/Config.cpp b/javascript/src/Config.cpp index 986e553e2b..d9313d8e38 100644 --- a/javascript/src/Config.cpp +++ b/javascript/src/Config.cpp @@ -32,13 +32,6 @@ void Config::setPointScaleFactor(float pixelsInPoint) { YGConfigSetPointScaleFactor(m_config, pixelsInPoint); } -void Config::setUseLegacyStretchBehaviour(bool useLegacyStretchBehaviour) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" - YGConfigSetUseLegacyStretchBehaviour(m_config, useLegacyStretchBehaviour); -#pragma clang diagnostic pop -} - void Config::setErrata(int errata) { YGConfigSetErrata(m_config, static_cast(errata)); } @@ -52,13 +45,6 @@ bool Config::isExperimentalFeatureEnabled(int feature) const { m_config, static_cast(feature)); } -bool Config::useLegacyStretchBehaviour() const { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" - return YGConfigGetUseLegacyStretchBehaviour(m_config); -#pragma clang diagnostic pop -} - int Config::getErrata() const { return static_cast(YGConfigGetErrata(m_config)); } diff --git a/javascript/src/Config.h b/javascript/src/Config.h index 5abfdd5b40..5a15bd450d 100644 --- a/javascript/src/Config.h +++ b/javascript/src/Config.h @@ -32,13 +32,11 @@ class Config { public: // Setters void setExperimentalFeatureEnabled(int feature, bool enabled); void setPointScaleFactor(float pixelsInPoint); - void setUseLegacyStretchBehaviour(bool useLegacyStretchBehaviour); void setErrata(int errata); void setUseWebDefaults(bool useWebDefaults); public: // Getters bool isExperimentalFeatureEnabled(int feature) const; - bool useLegacyStretchBehaviour() const; int getErrata() const; bool useWebDefaults() const; diff --git a/javascript/src/embind.cpp b/javascript/src/embind.cpp index d30094e978..e9b79c8f76 100644 --- a/javascript/src/embind.cpp +++ b/javascript/src/embind.cpp @@ -32,13 +32,10 @@ EMSCRIPTEN_BINDINGS(YOGA_LAYOUT) { "setExperimentalFeatureEnabled", &Config::setExperimentalFeatureEnabled) .function("setPointScaleFactor", &Config::setPointScaleFactor) - .function( - "setUseLegacyStretchBehaviour", &Config::setUseLegacyStretchBehaviour) .function("setErrata", &Config::setErrata) .function("setUseWebDefaults", &Config::setUseWebDefaults) .function( "isExperimentalFeatureEnabled", &Config::isExperimentalFeatureEnabled) - .function("useLegacyStretchBehaviour", &Config::useLegacyStretchBehaviour) .function("getErrata", &Config::getErrata) .function("useWebDefaults", &Config::useWebDefaults); diff --git a/javascript/src/wrapAssembly.d.ts b/javascript/src/wrapAssembly.d.ts index 4e3cbb2bc9..b6e2cbab3c 100644 --- a/javascript/src/wrapAssembly.d.ts +++ b/javascript/src/wrapAssembly.d.ts @@ -53,18 +53,6 @@ export type Config = { enabled: boolean, ): void; setPointScaleFactor(factor: number): void; - /** - * @deprecated Please use "getErrata()" - */ - useLegacyStretchBehaviour(): boolean; - /** - * @deprecated "setUseLegacyStretchBehaviour" will be removed in the next - * release. Usage should be replaced with "setErrata(ERRATA_ALL)" to opt out - * of all future breaking conformance fixes, or - * "setErrata(ERRATA_STRETCH_FLEX_BASIS)" to opt out of the specific - * conformance fix previously disabled by "UseLegacyStretchBehaviour". - */ - setUseLegacyStretchBehaviour(useLegacyStretchBehaviour: boolean): void; getErrata(): Errata; setErrata(errata: Errata): void; useWebDefaults(): boolean; diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index b9a5961d44..0a50aa84a4 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1017,21 +1017,6 @@ YOGA_EXPORT void YGConfigSetUseWebDefaults( resolveRef(config)->setUseWebDefaults(enabled); } -YOGA_EXPORT bool YGConfigGetUseLegacyStretchBehaviour( - const YGConfigConstRef config) { - return resolveRef(config)->hasErrata(YGErrataStretchFlexBasis); -} - -YOGA_EXPORT void YGConfigSetUseLegacyStretchBehaviour( - const YGConfigRef config, - const bool useLegacyStretchBehaviour) { - if (useLegacyStretchBehaviour) { - resolveRef(config)->addErrata(YGErrataStretchFlexBasis); - } else { - resolveRef(config)->removeErrata(YGErrataStretchFlexBasis); - } -} - bool YGConfigGetUseWebDefaults(const YGConfigConstRef config) { return resolveRef(config)->useWebDefaults(); } diff --git a/yoga/Yoga.h b/yoga/Yoga.h index c9efb85fd8..2697bb40ef 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -306,27 +306,6 @@ WIN_EXPORT void YGConfigSetPointScaleFactor( float pixelsInPoint); WIN_EXPORT float YGConfigGetPointScaleFactor(YGConfigConstRef config); -// Yoga previously had an error where containers would take the maximum space -// possible instead of the minimum like they are supposed to. In practice this -// resulted in implicit behaviour similar to align-self: stretch; Because this -// was such a long-standing bug we must allow legacy users to switch back to -// this behaviour. -WIN_EXPORT YG_DEPRECATED( - "Please use " - "\"YGConfigGetErrata()\"") bool YGConfigGetUseLegacyStretchBehaviour(YGConfigConstRef - config); -WIN_EXPORT -YG_DEPRECATED( - "\"YGConfigSetUseLegacyStretchBehaviour\" will be removed in the next " - "release. Usage should be replaced with \"YGConfigSetErrata(YGErrataAll)\" " - "to opt out of all future breaking conformance fixes, or " - "\"YGConfigSetErrata(YGErrataStretchFlexBasis)\" to opt out of the " - "specific conformance fix previously disabled by " - "\"UseLegacyStretchBehaviour\".") -void YGConfigSetUseLegacyStretchBehaviour( - YGConfigRef config, - bool useLegacyStretchBehaviour); - // YGConfig WIN_EXPORT YGConfigRef YGConfigNew(void); WIN_EXPORT void YGConfigFree(YGConfigRef config);