diff --git a/benchmark/Benchmark.cpp b/benchmark/Benchmark.cpp index 39d66b46ba..747c14c8fd 100644 --- a/benchmark/Benchmark.cpp +++ b/benchmark/Benchmark.cpp @@ -7,8 +7,10 @@ #include #include +#include #include +#include #include #include @@ -20,154 +22,37 @@ using namespace std::chrono; constexpr uint32_t kNumRepititions = 1000; using SteadyClockDurations = std::array; - -std::string invalidArgumentMessage(std::string arg, std::string enumName) { - return arg + " does not represent any " + enumName + " values"; -} - -YGFlexDirection flexDirectionFromString(std::string str) { - if (str == "row") { - return YGFlexDirectionRow; - } else if (str == "row-reverse") { - return YGFlexDirectionRowReverse; - } else if (str == "column") { - return YGFlexDirectionColumn; - } else if (str == "column-reverse") { - return YGFlexDirectionColumnReverse; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGFlexDirection")); - } -} - -YGJustify justifyContentFromString(std::string str) { - if (str == "flex-start") { - return YGJustifyFlexStart; - } else if (str == "center") { - return YGJustifyCenter; - } else if (str == "flex-end") { - return YGJustifyFlexEnd; - } else if (str == "space-between") { - return YGJustifySpaceBetween; - } else if (str == "space-around") { - return YGJustifySpaceAround; - } else if (str == "space-evenly") { - return YGJustifySpaceEvenly; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGJustify")); - } -} - -YGAlign alignFromString(std::string str) { - if (str == "auto") { - return YGAlignAuto; - } else if (str == "flex-start") { - return YGAlignFlexStart; - } else if (str == "center") { - return YGAlignCenter; - } else if (str == "flex-end") { - return YGAlignFlexEnd; - } else if (str == "stretch") { - return YGAlignStretch; - } else if (str == "baseline") { - return YGAlignBaseline; - } else if (str == "space-between") { - return YGAlignSpaceBetween; - } else if (str == "space-around") { - return YGAlignSpaceAround; - } else if (str == "space-evenly") { - return YGAlignSpaceEvenly; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); - } -} - -YGWrap wrapFromString(std::string str) { - if (str == "no-wrap") { - return YGWrapNoWrap; - } else if (str == "wrap") { - return YGWrapWrap; - } else if (str == "wrap-reverse") { - return YGWrapWrapReverse; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); - } -} - -YGOverflow overflowFromString(std::string str) { - if (str == "visible") { - return YGOverflowVisible; - } else if (str == "hidden") { - return YGOverflowHidden; - } else if (str == "scroll") { - return YGOverflowScroll; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); - } -} - -YGDisplay displayFromString(std::string str) { - if (str == "flex") { - return YGDisplayFlex; - } else if (str == "none") { - return YGDisplayNone; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); - } -} - -YGPositionType positionTypeFromString(std::string str) { - if (str == "static") { - return YGPositionTypeStatic; - } else if (str == "relative") { - return YGPositionTypeRelative; - } else if (str == "absolute") { - return YGPositionTypeAbsolute; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); - } -} - -bool isAuto(json& j) { - return j.is_string() && j == "auto"; -} - -YGUnit unitFromJson(json& j) { - if (isAuto(j)) { - return YGUnitAuto; +using YGConfigShared = std::shared_ptr; +using YGNodeShared = std::shared_ptr; + +struct YogaNodeAndConfig { + YGNodeShared node_; + YGConfigShared config_; + std::shared_ptr> children_; +}; + +YGConfigShared buildConfigFromJson(json& j) { + json jsonConfig = j["config"]; + YGConfigShared config(YGConfigNew(), YGConfigFree); + for (json::iterator it = jsonConfig.begin(); it != jsonConfig.end(); it++) { + if (it.key() == "use-web-defaults") { + YGConfigSetUseWebDefaults(config.get(), it.value()); + } else if (it.key() == "point-scale-factor") { + YGConfigSetPointScaleFactor(config.get(), it.value()); + } else if (it.key() == "errata") { + YGConfigSetErrata(config.get(), errataFromString(it.value())); + } else if (it.key() == "experimental-features") { + // Experimental features is serialized into an array where the values + // present indicate that that feature is enabled + for (json::iterator efIt = it.value().begin(); efIt != it.value().end(); + efIt++) { + YGConfigSetExperimentalFeatureEnabled( + config.get(), experimentalFeatureFromString(efIt.value()), true); + } + } } - std::string unit = j["unit"]; - if (unit == "px") { - return YGUnitPoint; - } else if (unit == "pct") { - return YGUnitPercent; - } else { - throw std::invalid_argument(invalidArgumentMessage(unit, "YGUnit")); - } -} - -YGEdge edgeFromString(std::string str) { - if (str == "left") { - return YGEdgeLeft; - } else if (str == "top") { - return YGEdgeTop; - } else if (str == "right") { - return YGEdgeRight; - } else if (str == "bottom") { - return YGEdgeBottom; - } else if (str == "start") { - return YGEdgeStart; - } else if (str == "end") { - return YGEdgeEnd; - } else if (str == "horizontal") { - return YGEdgeHorizontal; - } else if (str == "vertical") { - return YGEdgeVertical; - } else if (str == "all") { - return YGEdgeAll; - } else { - throw std::invalid_argument(invalidArgumentMessage(str, "YGEdge")); - } + return config; } std::string edgeStringFromPropertyName( @@ -176,151 +61,160 @@ std::string edgeStringFromPropertyName( return key.substr(propertyName.length() + 1); } -YGNodeRef buildTreeFromJson(json& j, YGNodeRef parent, size_t index) { - const YGNodeRef node = YGNodeNew(); - if (parent != nullptr) { - YGNodeInsertChild(parent, node, index); - } - +void setStylesFromJson(json& j, YGNodeShared node) { json style = j["style"]; for (const auto& [key, value] : style.items()) { if (key == "flex-direction") { - YGNodeStyleSetFlexDirection(node, flexDirectionFromString(value)); + YGNodeStyleSetFlexDirection(node.get(), flexDirectionFromString(value)); } else if (key == "justify-content") { - YGNodeStyleSetJustifyContent(node, justifyContentFromString(value)); + YGNodeStyleSetJustifyContent(node.get(), justifyContentFromString(value)); } else if (key == "align-items") { - YGNodeStyleSetAlignItems(node, alignFromString(value)); + YGNodeStyleSetAlignItems(node.get(), alignFromString(value)); } else if (key == "align-content") { - YGNodeStyleSetAlignContent(node, alignFromString(value)); + YGNodeStyleSetAlignContent(node.get(), alignFromString(value)); } else if (key == "align-self") { - YGNodeStyleSetAlignSelf(node, alignFromString(value)); + YGNodeStyleSetAlignSelf(node.get(), alignFromString(value)); } else if (key == "flex-wrap") { - YGNodeStyleSetFlexWrap(node, wrapFromString(value)); + YGNodeStyleSetFlexWrap(node.get(), wrapFromString(value)); } else if (key == "overflow") { - YGNodeStyleSetOverflow(node, overflowFromString(value)); + YGNodeStyleSetOverflow(node.get(), overflowFromString(value)); } else if (key == "display") { - YGNodeStyleSetDisplay(node, displayFromString(value)); + YGNodeStyleSetDisplay(node.get(), displayFromString(value)); } else if (key == "position-type") { - YGNodeStyleSetPositionType(node, positionTypeFromString(value)); + YGNodeStyleSetPositionType(node.get(), positionTypeFromString(value)); } else if (key == "flex-grow") { - YGNodeStyleSetFlexGrow(node, value); + YGNodeStyleSetFlexGrow(node.get(), value); } else if (key == "flex-shrink") { - YGNodeStyleSetFlexShrink(node, value); + YGNodeStyleSetFlexShrink(node.get(), value); } else if (key == "flex") { - YGNodeStyleSetFlex(node, value); + YGNodeStyleSetFlex(node.get(), value); } else if (key == "flex-basis") { YGUnit unit = unitFromJson(value); if (unit == YGUnitAuto) { - YGNodeStyleSetFlexBasisAuto(node); + YGNodeStyleSetFlexBasisAuto(node.get()); } else if (unit == YGUnitPoint) { - YGNodeStyleSetFlexBasis(node, value["value"]); + YGNodeStyleSetFlexBasis(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetFlexBasisPercent(node, value["value"]); + YGNodeStyleSetFlexBasisPercent(node.get(), value["value"]); } } else if (key.starts_with("position")) { YGEdge edge = edgeFromString(edgeStringFromPropertyName(key, "position")); YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetPosition(node, edge, value["value"]); + YGNodeStyleSetPosition(node.get(), edge, value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetPositionPercent(node, edge, value["value"]); + YGNodeStyleSetPositionPercent(node.get(), edge, value["value"]); } } else if (key.starts_with("padding")) { YGEdge edge = edgeFromString(edgeStringFromPropertyName(key, "padding")); YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetPadding(node, edge, value["value"]); + YGNodeStyleSetPadding(node.get(), edge, value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetPaddingPercent(node, edge, value["value"]); + YGNodeStyleSetPaddingPercent(node.get(), edge, value["value"]); } } else if (key.starts_with("border")) { YGEdge edge = edgeFromString(edgeStringFromPropertyName(key, "border")); YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetBorder(node, edge, value["value"]); + YGNodeStyleSetBorder(node.get(), edge, value["value"]); } } else if (key.starts_with("margin")) { YGEdge edge = edgeFromString(edgeStringFromPropertyName(key, "margin")); YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetMargin(node, edge, value["value"]); + YGNodeStyleSetMargin(node.get(), edge, value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetMarginPercent(node, edge, value["value"]); + YGNodeStyleSetMarginPercent(node.get(), edge, value["value"]); } else if (unit == YGUnitAuto) { - YGNodeStyleSetMarginAuto(node, edge); + YGNodeStyleSetMarginAuto(node.get(), edge); } } else if (key == "gap") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetGap(node, YGGutterAll, value["value"]); + YGNodeStyleSetGap(node.get(), YGGutterAll, value["value"]); } } else if (key == "column-gap") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetGap(node, YGGutterColumn, value["value"]); + YGNodeStyleSetGap(node.get(), YGGutterColumn, value["value"]); } } else if (key == "row-gap") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetGap(node, YGGutterRow, value["value"]); + YGNodeStyleSetGap(node.get(), YGGutterRow, value["value"]); } } else if (key == "height") { YGUnit unit = unitFromJson(value); if (unit == YGUnitAuto) { - YGNodeStyleSetHeightAuto(node); + YGNodeStyleSetHeightAuto(node.get()); } else if (unit == YGUnitPoint) { - YGNodeStyleSetHeight(node, value["value"]); + YGNodeStyleSetHeight(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetHeightPercent(node, value["value"]); + YGNodeStyleSetHeightPercent(node.get(), value["value"]); } } else if (key == "width") { YGUnit unit = unitFromJson(value); if (unit == YGUnitAuto) { - YGNodeStyleSetWidthAuto(node); + YGNodeStyleSetWidthAuto(node.get()); } else if (unit == YGUnitPoint) { - YGNodeStyleSetWidth(node, value["value"]); + YGNodeStyleSetWidth(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetWidthPercent(node, value["value"]); + YGNodeStyleSetWidthPercent(node.get(), value["value"]); } } else if (key == "min-height") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetMinHeight(node, value["value"]); + YGNodeStyleSetMinHeight(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetMinHeightPercent(node, value["value"]); + YGNodeStyleSetMinHeightPercent(node.get(), value["value"]); } } else if (key == "min-width") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetMinWidth(node, value["value"]); + YGNodeStyleSetMinWidth(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetMinWidthPercent(node, value["value"]); + YGNodeStyleSetMinWidthPercent(node.get(), value["value"]); } } else if (key == "max-height") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetMaxHeight(node, value["value"]); + YGNodeStyleSetMaxHeight(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetMaxHeightPercent(node, value["value"]); + YGNodeStyleSetMaxHeightPercent(node.get(), value["value"]); } } else if (key == "max-width") { YGUnit unit = unitFromJson(value); if (unit == YGUnitPoint) { - YGNodeStyleSetMaxWidth(node, value["value"]); + YGNodeStyleSetMaxWidth(node.get(), value["value"]); } else if (unit == YGUnitPercent) { - YGNodeStyleSetMaxWidthPercent(node, value["value"]); + YGNodeStyleSetMaxWidthPercent(node.get(), value["value"]); } } } +} + +YogaNodeAndConfig +buildTreeFromJson(json& j, YogaNodeAndConfig* parent, size_t index) { + YGConfigShared config = buildConfigFromJson(j); + YGNodeShared node(YGNodeNewWithConfig(config.get()), YGNodeFree); + YogaNodeAndConfig wrapper{ + node, config, std::make_shared>()}; + if (parent != nullptr) { + YGNodeInsertChild(parent->node_.get(), node.get(), index); + parent->children_->push_back(wrapper); + } + + setStylesFromJson(j, node); json children = j["children"]; size_t childIndex = 0; for (json child : children) { - buildTreeFromJson(child, node, childIndex); + buildTreeFromJson(child, &wrapper, childIndex); childIndex++; } - return node; + return wrapper; } BenchmarkResult generateBenchmark(const std::filesystem::path& capturePath) { @@ -328,15 +222,14 @@ BenchmarkResult generateBenchmark(const std::filesystem::path& capturePath) { json capture = json::parse(captureFile); auto treeCreationBegin = steady_clock::now(); - YGNodeRef root = buildTreeFromJson(capture, nullptr, 0 /*index*/); + YogaNodeAndConfig root = buildTreeFromJson(capture, nullptr, 0 /*index*/); auto treeCreationEnd = steady_clock::now(); auto layoutBegin = steady_clock::now(); - YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + YGNodeCalculateLayout( + root.node_.get(), YGUndefined, YGUndefined, YGDirectionLTR); auto layoutEnd = steady_clock::now(); - YGNodeFreeRecursive(root); - return BenchmarkResult{ treeCreationEnd - treeCreationBegin, layoutEnd - layoutBegin}; } diff --git a/benchmark/TreeDeserialization.h b/benchmark/TreeDeserialization.h new file mode 100644 index 0000000000..1c6f3951e2 --- /dev/null +++ b/benchmark/TreeDeserialization.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook::yoga { + +using namespace nlohmann; + +inline std::string invalidArgumentMessage( + std::string arg, + std::string enumName) { + return arg + " does not represent any " + enumName + " values"; +} + +inline YGFlexDirection flexDirectionFromString(std::string str) { + if (str == "row") { + return YGFlexDirectionRow; + } else if (str == "row-reverse") { + return YGFlexDirectionRowReverse; + } else if (str == "column") { + return YGFlexDirectionColumn; + } else if (str == "column-reverse") { + return YGFlexDirectionColumnReverse; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGFlexDirection")); + } +} + +inline YGJustify justifyContentFromString(std::string str) { + if (str == "flex-start") { + return YGJustifyFlexStart; + } else if (str == "center") { + return YGJustifyCenter; + } else if (str == "flex-end") { + return YGJustifyFlexEnd; + } else if (str == "space-between") { + return YGJustifySpaceBetween; + } else if (str == "space-around") { + return YGJustifySpaceAround; + } else if (str == "space-evenly") { + return YGJustifySpaceEvenly; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGJustify")); + } +} + +inline YGAlign alignFromString(std::string str) { + if (str == "auto") { + return YGAlignAuto; + } else if (str == "flex-start") { + return YGAlignFlexStart; + } else if (str == "center") { + return YGAlignCenter; + } else if (str == "flex-end") { + return YGAlignFlexEnd; + } else if (str == "stretch") { + return YGAlignStretch; + } else if (str == "baseline") { + return YGAlignBaseline; + } else if (str == "space-between") { + return YGAlignSpaceBetween; + } else if (str == "space-around") { + return YGAlignSpaceAround; + } else if (str == "space-evenly") { + return YGAlignSpaceEvenly; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); + } +} + +inline YGWrap wrapFromString(std::string str) { + if (str == "no-wrap") { + return YGWrapNoWrap; + } else if (str == "wrap") { + return YGWrapWrap; + } else if (str == "wrap-reverse") { + return YGWrapWrapReverse; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); + } +} + +inline YGOverflow overflowFromString(std::string str) { + if (str == "visible") { + return YGOverflowVisible; + } else if (str == "hidden") { + return YGOverflowHidden; + } else if (str == "scroll") { + return YGOverflowScroll; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); + } +} + +inline YGDisplay displayFromString(std::string str) { + if (str == "flex") { + return YGDisplayFlex; + } else if (str == "none") { + return YGDisplayNone; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); + } +} + +inline YGPositionType positionTypeFromString(std::string str) { + if (str == "static") { + return YGPositionTypeStatic; + } else if (str == "relative") { + return YGPositionTypeRelative; + } else if (str == "absolute") { + return YGPositionTypeAbsolute; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGAlign")); + } +} + +inline bool isAuto(json& j) { + return j.is_string() && j == "auto"; +} + +inline YGUnit unitFromJson(json& j) { + if (isAuto(j)) { + return YGUnitAuto; + } + + std::string unit = j["unit"]; + if (unit == "px") { + return YGUnitPoint; + } else if (unit == "pct") { + return YGUnitPercent; + } else { + throw std::invalid_argument(invalidArgumentMessage(unit, "YGUnit")); + } +} + +inline YGEdge edgeFromString(std::string str) { + if (str == "left") { + return YGEdgeLeft; + } else if (str == "top") { + return YGEdgeTop; + } else if (str == "right") { + return YGEdgeRight; + } else if (str == "bottom") { + return YGEdgeBottom; + } else if (str == "start") { + return YGEdgeStart; + } else if (str == "end") { + return YGEdgeEnd; + } else if (str == "horizontal") { + return YGEdgeHorizontal; + } else if (str == "vertical") { + return YGEdgeVertical; + } else if (str == "all") { + return YGEdgeAll; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGEdge")); + } +} + +inline YGErrata errataFromString(std::string str) { + if (str == "none") { + return YGErrataNone; + } else if (str == "all") { + return YGErrataAll; + } else if (str == "classic") { + return YGErrataClassic; + } else { + throw std::invalid_argument(invalidArgumentMessage(str, "YGErrata")); + } +} + +inline YGExperimentalFeature experimentalFeatureFromString(std::string str) { + if (str == "web-flex-basis") { + return YGExperimentalFeatureWebFlexBasis; + } else { + throw std::invalid_argument( + invalidArgumentMessage(str, "YGExperimentalFeature")); + } +} + +inline std::string edgeStringFromPropertyName( + json::iterator it, + std::string propertyName) { + return it.key().substr(propertyName.length() + 1); +} +} // namespace facebook::yoga diff --git a/capture/CaptureTree.cpp b/capture/CaptureTree.cpp index 54d681a198..7fb1262413 100644 --- a/capture/CaptureTree.cpp +++ b/capture/CaptureTree.cpp @@ -14,7 +14,10 @@ namespace facebook::yoga { void captureTree(YGNodeRef node, const std::filesystem::path& path) { std::string str; - nodeToString(str, node, YGPrintOptionsStyle | YGPrintOptionsChildren); + nodeToString( + str, + node, + PrintOptions::Style | PrintOptions::Children | PrintOptions::Config); std::ofstream file(path); file << str; } diff --git a/capture/NodeToString.cpp b/capture/NodeToString.cpp index f00bffa6d4..314a5937ee 100644 --- a/capture/NodeToString.cpp +++ b/capture/NodeToString.cpp @@ -18,7 +18,7 @@ static void appendFloatIfNotDefault( float num, float defaultNum) { if (num != defaultNum && !YGFloatIsUndefined(num)) { - j["style"][key] = num; + j[key] = num; } } @@ -29,13 +29,13 @@ static void appendYGValueIfNotDefault( const YGValue& defaultValue) { if (value != defaultValue) { if (value.unit == YGUnitAuto) { - j["style"][key] = "auto"; + j[key] = "auto"; } else if (value.unit == YGUnitUndefined) { - j["style"][key] = "undefined"; + j[key] = "undefined"; } else { std::string unit = value.unit == YGUnitPoint ? "px" : "pct"; - j["style"][key]["value"] = value.value; - j["style"][key]["unit"] = unit; + j[key]["value"] = value.value; + j[key]["unit"] = unit; } } } @@ -46,7 +46,17 @@ static void appendEnumValueIfNotDefault( std::string_view value, std::string_view defaultValue) { if (value != defaultValue) { - j["style"][key] = value; + j[key] = value; + } +} + +static void appendBoolIfNotDefault( + json& j, + std::string_view key, + bool value, + bool defaultValue) { + if (value != defaultValue) { + j[key] = value; } } @@ -57,47 +67,47 @@ static void appendEdges( YGNodeRef node, YGNodeRef defaultNode) { appendYGValueIfNotDefault( - j, + j["style"], key + "-left", (*Field)(node, YGEdgeLeft), (*Field)(defaultNode, YGEdgeLeft)); appendYGValueIfNotDefault( - j, + j["style"], key + "-right", (*Field)(node, YGEdgeRight), (*Field)(defaultNode, YGEdgeRight)); appendYGValueIfNotDefault( - j, + j["style"], key + "-top", (*Field)(node, YGEdgeTop), (*Field)(defaultNode, YGEdgeTop)); appendYGValueIfNotDefault( - j, + j["style"], key + "-bottom", (*Field)(node, YGEdgeBottom), (*Field)(defaultNode, YGEdgeBottom)); appendYGValueIfNotDefault( - j, + j["style"], key + "-all", (*Field)(node, YGEdgeAll), (*Field)(defaultNode, YGEdgeAll)); appendYGValueIfNotDefault( - j, + j["style"], key + "-start", (*Field)(node, YGEdgeStart), (*Field)(defaultNode, YGEdgeStart)); appendYGValueIfNotDefault( - j, + j["style"], key + "-end", (*Field)(node, YGEdgeEnd), (*Field)(defaultNode, YGEdgeEnd)); appendYGValueIfNotDefault( - j, + j["style"], key + "-vertical", (*Field)(node, YGEdgeVertical), (*Field)(defaultNode, YGEdgeVertical)); appendYGValueIfNotDefault( - j, + j["style"], key + "-horizontal", (*Field)(node, YGEdgeHorizontal), (*Field)(defaultNode, YGEdgeHorizontal)); @@ -109,76 +119,79 @@ YGValue borderFloatToYGValue(YGNodeRef node, YGEdge edge) { return YGValue{val, unit}; } -static void nodeToStringImpl(json& j, YGNodeRef node, YGPrintOptions options) { - if ((options & YGPrintOptionsLayout) == YGPrintOptionsLayout) { +static void nodeToStringImpl(json& j, YGNodeRef node, PrintOptions options) { + if ((options & PrintOptions::Layout) == PrintOptions::Layout) { j["layout"]["width"] = YGNodeStyleGetWidth(node).value; j["layout"]["height"] = YGNodeStyleGetHeight(node).value; j["layout"]["top"] = YGNodeStyleGetPosition(node, YGEdgeTop).value; j["layout"]["left"] = YGNodeStyleGetPosition(node, YGEdgeLeft).value; } - if ((options & YGPrintOptionsStyle) == YGPrintOptionsStyle) { + if ((options & PrintOptions::Style) == PrintOptions::Style) { const YGNodeRef defaultNode = YGNodeNew(); appendEnumValueIfNotDefault( - j, + j["style"], "flex-direction", YGFlexDirectionToString(YGNodeStyleGetFlexDirection(node)), YGFlexDirectionToString(YGNodeStyleGetFlexDirection(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "justify-content", YGJustifyToString(YGNodeStyleGetJustifyContent(node)), YGJustifyToString(YGNodeStyleGetJustifyContent(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "align-items", YGAlignToString(YGNodeStyleGetAlignItems(node)), YGAlignToString(YGNodeStyleGetAlignItems(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "align-content", YGAlignToString(YGNodeStyleGetAlignContent(node)), YGAlignToString(YGNodeStyleGetAlignContent(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "align-self", YGAlignToString(YGNodeStyleGetAlignSelf(node)), YGAlignToString(YGNodeStyleGetAlignSelf(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "flex-wrap", YGWrapToString(YGNodeStyleGetFlexWrap(node)), YGWrapToString(YGNodeStyleGetFlexWrap(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "overflow", YGOverflowToString(YGNodeStyleGetOverflow(node)), YGOverflowToString(YGNodeStyleGetOverflow(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "display", YGDisplayToString(YGNodeStyleGetDisplay(node)), YGDisplayToString(YGNodeStyleGetDisplay(defaultNode))); appendEnumValueIfNotDefault( - j, + j["style"], "position-type", YGPositionTypeToString(YGNodeStyleGetPositionType(node)), YGPositionTypeToString(YGNodeStyleGetPositionType(defaultNode))); appendFloatIfNotDefault( - j, + j["style"], "flex-grow", YGNodeStyleGetFlexGrow(node), YGNodeStyleGetFlexGrow(defaultNode)); appendFloatIfNotDefault( - j, + j["style"], "flex-shrink", YGNodeStyleGetFlexShrink(node), YGNodeStyleGetFlexShrink(defaultNode)); appendFloatIfNotDefault( - j, "flex", YGNodeStyleGetFlex(node), YGNodeStyleGetFlex(defaultNode)); + j["style"], + "flex", + YGNodeStyleGetFlex(node), + YGNodeStyleGetFlex(defaultNode)); appendYGValueIfNotDefault( - j, + j["style"], "flex-basis", YGNodeStyleGetFlexBasis(node), YGNodeStyleGetFlexBasis(defaultNode)); @@ -189,48 +202,48 @@ static void nodeToStringImpl(json& j, YGNodeRef node, YGPrintOptions options) { appendEdges<&YGNodeStyleGetPosition>(j, "position", node, defaultNode); appendFloatIfNotDefault( - j, + j["style"], "gap", YGNodeStyleGetGap(node, YGGutterAll), YGNodeStyleGetGap(defaultNode, YGGutterAll)); appendFloatIfNotDefault( - j, + j["style"], "column-gap", YGNodeStyleGetGap(node, YGGutterColumn), YGNodeStyleGetGap(defaultNode, YGGutterColumn)); appendFloatIfNotDefault( - j, + j["style"], "row-gap", YGNodeStyleGetGap(node, YGGutterRow), YGNodeStyleGetGap(defaultNode, YGGutterRow)); appendYGValueIfNotDefault( - j, + j["style"], "width", YGNodeStyleGetWidth(node), YGNodeStyleGetWidth(defaultNode)); appendYGValueIfNotDefault( - j, + j["style"], "height", YGNodeStyleGetHeight(node), YGNodeStyleGetHeight(defaultNode)); appendYGValueIfNotDefault( - j, + j["style"], "max-width", YGNodeStyleGetMaxWidth(node), YGNodeStyleGetMaxWidth(defaultNode)); appendYGValueIfNotDefault( - j, + j["style"], "max-height", YGNodeStyleGetMaxHeight(node), YGNodeStyleGetMaxHeight(defaultNode)); appendYGValueIfNotDefault( - j, + j["style"], "min-width", YGNodeStyleGetMinWidth(node), YGNodeStyleGetMinWidth(defaultNode)); appendYGValueIfNotDefault( - j, + j["style"], "min-height", YGNodeStyleGetMinHeight(node), YGNodeStyleGetMinHeight(defaultNode)); @@ -240,8 +253,41 @@ static void nodeToStringImpl(json& j, YGNodeRef node, YGPrintOptions options) { } } + if ((options & PrintOptions::Config) == PrintOptions::Config) { + YGConfigConstRef config = YGNodeGetConfig(node); + YGConfigConstRef defaultConfig = YGConfigGetDefault(); + + appendBoolIfNotDefault( + j["config"], + "use-web-defaults", + YGConfigGetUseWebDefaults(config), + YGConfigGetUseWebDefaults(defaultConfig)); + appendFloatIfNotDefault( + j["config"], + "point-scale-factor", + YGConfigGetPointScaleFactor(config), + YGConfigGetPointScaleFactor(defaultConfig)); + YGErrata errata = YGConfigGetErrata(config); + if (errata == YGErrataNone || errata == YGErrataAll || + errata == YGErrataClassic) { + appendEnumValueIfNotDefault( + j["config"], + "errata", + YGErrataToString(errata), + YGErrataToString(YGConfigGetErrata(defaultConfig))); + } + + if (YGConfigIsExperimentalFeatureEnabled( + config, YGExperimentalFeatureWebFlexBasis) != + YGConfigIsExperimentalFeatureEnabled( + defaultConfig, YGExperimentalFeatureWebFlexBasis)) { + j["config"]["experimental-features"].push_back( + YGExperimentalFeatureToString(YGExperimentalFeatureWebFlexBasis)); + } + } + const size_t childCount = YGNodeGetChildCount(node); - if ((options & YGPrintOptionsChildren) == YGPrintOptionsChildren && + if ((options & PrintOptions::Children) == PrintOptions::Children && childCount > 0) { for (size_t i = 0; i < childCount; i++) { j["children"].push_back({}); @@ -250,7 +296,7 @@ static void nodeToStringImpl(json& j, YGNodeRef node, YGPrintOptions options) { } } -void nodeToString(std::string& str, YGNodeRef node, YGPrintOptions options) { +void nodeToString(std::string& str, YGNodeRef node, PrintOptions options) { json j; nodeToStringImpl(j, node, options); str = j.dump(2); diff --git a/capture/NodeToString.h b/capture/NodeToString.h index d442cb3cf1..e9d668ae47 100644 --- a/capture/NodeToString.h +++ b/capture/NodeToString.h @@ -13,6 +13,14 @@ namespace facebook::yoga { -void nodeToString(std::string& str, YGNodeRef node, YGPrintOptions options); +enum class PrintOptions : uint8_t { + Layout = 1 << 0, + Children = 1 << 1, + Style = 1 << 2, + Config = 1 << 3, +}; +YG_DEFINE_ENUM_FLAG_OPERATORS(PrintOptions); + +void nodeToString(std::string& str, YGNodeRef node, PrintOptions options); } // namespace facebook::yoga diff --git a/enums.py b/enums.py index 087d64433d..19bbed8b0d 100755 --- a/enums.py +++ b/enums.py @@ -53,11 +53,6 @@ # Mimic web flex-basis behavior (experiment may be broken) "WebFlexBasis", ], - "PrintOptions": [ - ("Layout", 1 << 0), - ("Style", 1 << 1), - ("Children", 1 << 2), - ], "Gutter": ["Column", "Row", "All"], # Known incorrect behavior which can be enabled for compatibility "Errata": [ @@ -82,7 +77,7 @@ DO_NOT_STRIP = ["LogLevel"] -BITSET_ENUMS = ["PrintOptions", "Errata"] +BITSET_ENUMS = ["Errata"] def get_license(ext): diff --git a/java/com/facebook/yoga/YogaPrintOptions.java b/java/com/facebook/yoga/YogaPrintOptions.java deleted file mode 100644 index 54eacc51d3..0000000000 --- a/java/com/facebook/yoga/YogaPrintOptions.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// @generated by enums.py - -package com.facebook.yoga; - -public enum YogaPrintOptions { - LAYOUT(1), - STYLE(2), - CHILDREN(4); - - private final int mIntValue; - - YogaPrintOptions(int intValue) { - mIntValue = intValue; - } - - public int intValue() { - return mIntValue; - } - - public static YogaPrintOptions fromInt(int value) { - switch (value) { - case 1: return LAYOUT; - case 2: return STYLE; - case 4: return CHILDREN; - default: throw new IllegalArgumentException("Unknown enum value: " + value); - } - } -} diff --git a/javascript/src/generated/YGEnums.ts b/javascript/src/generated/YGEnums.ts index 6a8356c75f..b4dcaa337d 100644 --- a/javascript/src/generated/YGEnums.ts +++ b/javascript/src/generated/YGEnums.ts @@ -114,12 +114,6 @@ export enum PositionType { Absolute = 2, } -export enum PrintOptions { - Layout = 1, - Style = 2, - Children = 4, -} - export enum Unit { Undefined = 0, Point = 1, @@ -196,9 +190,6 @@ const constants = { POSITION_TYPE_STATIC: PositionType.Static, POSITION_TYPE_RELATIVE: PositionType.Relative, POSITION_TYPE_ABSOLUTE: PositionType.Absolute, - PRINT_OPTIONS_LAYOUT: PrintOptions.Layout, - PRINT_OPTIONS_STYLE: PrintOptions.Style, - PRINT_OPTIONS_CHILDREN: PrintOptions.Children, UNIT_UNDEFINED: Unit.Undefined, UNIT_POINT: Unit.Point, UNIT_PERCENT: Unit.Percent, diff --git a/yoga/YGEnums.cpp b/yoga/YGEnums.cpp index d3365d3a42..222a5d12a4 100644 --- a/yoga/YGEnums.cpp +++ b/yoga/YGEnums.cpp @@ -223,18 +223,6 @@ const char* YGPositionTypeToString(const YGPositionType value) { return "unknown"; } -const char* YGPrintOptionsToString(const YGPrintOptions value) { - switch (value) { - case YGPrintOptionsLayout: - return "layout"; - case YGPrintOptionsStyle: - return "style"; - case YGPrintOptionsChildren: - return "children"; - } - return "unknown"; -} - const char* YGUnitToString(const YGUnit value) { switch (value) { case YGUnitUndefined: diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index 18fbe0fe02..44335277fc 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -120,13 +120,6 @@ YG_ENUM_DECL( YGPositionTypeRelative, YGPositionTypeAbsolute) -YG_ENUM_DECL( - YGPrintOptions, - YGPrintOptionsLayout = 1, - YGPrintOptionsStyle = 2, - YGPrintOptionsChildren = 4) -YG_DEFINE_ENUM_FLAG_OPERATORS(YGPrintOptions) - YG_ENUM_DECL( YGUnit, YGUnitUndefined, diff --git a/yoga/enums/PrintOptions.h b/yoga/enums/PrintOptions.h deleted file mode 100644 index 5970bafb47..0000000000 --- a/yoga/enums/PrintOptions.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -// @generated by enums.py -// clang-format off -#pragma once - -#include -#include -#include - -namespace facebook::yoga { - -enum class PrintOptions : uint32_t { - Layout = YGPrintOptionsLayout, - Style = YGPrintOptionsStyle, - Children = YGPrintOptionsChildren, -}; - -YG_DEFINE_ENUM_FLAG_OPERATORS(PrintOptions) - -constexpr PrintOptions scopedEnum(YGPrintOptions unscoped) { - return static_cast(unscoped); -} - -constexpr YGPrintOptions unscopedEnum(PrintOptions scoped) { - return static_cast(scoped); -} - -inline const char* toString(PrintOptions e) { - return YGPrintOptionsToString(unscopedEnum(e)); -} - -} // namespace facebook::yoga