facebook / yoga

Yoga is an embeddable layout engine targeting web standards.

Home Page:https://yogalayout.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Discrepancy between playground and C++

caiovlp opened this issue · comments

Report

Issues and Steps to Reproduce

Not sure if this is a configuration issue or not, but it seems I'm getting different behaviors when testing with the same tree on the playground vs c++ code.

Here's the c++ code:

TEST(test_yoga, Check) {
    YGConfigRef config = YGConfigNew();
    YGConfigSetUseWebDefaults(config, false);

    YGNodeRef root = YGNodeNewWithConfig(config);
    YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn);

    {
        YGNodeRef container = YGNodeNewWithConfig(config);
        YGNodeStyleSetFlexDirection(container, YGFlexDirectionColumn);
        YGNodeStyleSetWidth(container, 600);
        YGNodeInsertChild(root, container, 0);

        {
            YGNodeRef child = YGNodeNewWithConfig(config);
            YGNodeStyleSetFlexDirection(child, YGFlexDirectionColumn);
            // margin: 30
            YGNodeStyleSetMargin(child, YGEdgeLeft, 30);
            YGNodeStyleSetMargin(child, YGEdgeTop, 30);
            YGNodeStyleSetMargin(child, YGEdgeRight, 30);
            YGNodeStyleSetMargin(child, YGEdgeBottom, 30);
            YGNodeInsertChild(container, child, 0);

            {
                YGNodeRef grandchild1 = YGNodeNewWithConfig(config);
                YGNodeStyleSetFlexDirection(grandchild1, YGFlexDirectionRow);
                // margin: 40
                YGNodeStyleSetMargin(grandchild1, YGEdgeLeft, 40);
                YGNodeStyleSetMargin(grandchild1, YGEdgeTop, 40);
                YGNodeStyleSetMargin(grandchild1, YGEdgeRight, 40);
                YGNodeStyleSetMargin(grandchild1, YGEdgeBottom, 40);
                // padding: 20
                YGNodeStyleSetPadding(grandchild1, YGEdgeLeft, 20);
                YGNodeStyleSetPadding(grandchild1, YGEdgeTop, 20);
                YGNodeStyleSetPadding(grandchild1, YGEdgeRight, 20);
                YGNodeStyleSetPadding(grandchild1, YGEdgeBottom, 20);
                // height: 100
                YGNodeStyleSetHeight(grandchild1, 100);
                YGNodeInsertChild(child, grandchild1, 0);

                YGNodeRef grandchild2 = YGNodeNewWithConfig(config);
                YGNodeStyleSetFlexDirection(grandchild2, YGFlexDirectionRow);
                // margin: 40
                YGNodeStyleSetMargin(grandchild2, YGEdgeLeft, 50);
                YGNodeStyleSetMargin(grandchild2, YGEdgeTop, 50);
                YGNodeStyleSetMargin(grandchild2, YGEdgeRight, 50);
                YGNodeStyleSetMargin(grandchild2, YGEdgeBottom, 50);
                YGNodeInsertChild(child, grandchild2, 1);

                {
                    YGNodeRef greatgrandchild1 = YGNodeNewWithConfig(config);
                    YGNodeStyleSetFlexDirection(greatgrandchild1, YGFlexDirectionRow);
                    YGNodeStyleSetHeight(greatgrandchild1, 50);
                    // margin: 40
                    YGNodeStyleSetMargin(greatgrandchild1, YGEdgeLeft, 45);
                    YGNodeStyleSetMargin(greatgrandchild1, YGEdgeTop, 45);
                    YGNodeStyleSetMargin(greatgrandchild1, YGEdgeRight, 45);
                    YGNodeStyleSetMargin(greatgrandchild1, YGEdgeBottom, 45);
                    YGNodeInsertChild(grandchild2, greatgrandchild1, 0);
                }
            }
        }
    }

    YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);

    std::function<void(YGNodeRef, int)> dumpNodeTree;

    dumpNodeTree = [&dumpNodeTree](YGNodeRef node, int depth) {
        std::string indent(depth * 4, ' ');

        std::cout << indent << "Node [left: " << YGNodeLayoutGetLeft(node)
                  << ", top: " << YGNodeLayoutGetTop(node)
                  << ", width: " << YGNodeLayoutGetWidth(node)
                  << ", height: " << YGNodeLayoutGetHeight(node) << "]\n";

        for (int i = 0; i < YGNodeGetChildCount(node); i++) {
            dumpNodeTree(YGNodeGetChild(node, i), depth + 1);
        }
    };

    dumpNodeTree(root, 0);
}

Here's the equivalent playground code (plus comments):

<Layout config={{useWebDefaults: false}}> 
  <Node style={{width: 600, direction: "column"}}> <!-- container -->
    <Node style={{margin: 30, direction: "column"}}> <!-- child -->
      <Node style={{margin: 40, padding: 20, height: 100, direction: "row"}}></Node> <!-- grandchild1 -->
      <Node style={{margin: 50, direction: "row"}}> <!-- grandchild2 -->
        <Node style={{margin: 45, height: 50, direction: "row"}}></Node> <!-- greatgrandchild1 -->
      </Node>
    </Node>
  </Node>
</Layout>

In the output of the c++ code, I get:

Node [left: 0, top: 0, width: 600, height: 480]
    Node [left: 0, top: 0, width: 600, height: 480]
        Node [left: 30, top: 30, width: 540, height: 420]
            Node [left: 40, top: 40, width: 460, height: 100]
            Node [left: 50, top: 230, width: 440, height: 140]
                Node [left: 45, top: 45, width: 0, height: 50]

Width shouldn't be zero imo and the playground correctly assigns the appropriate width:

discrepancy-yoga

Tested both v3.0.2 and v2.0.1 with WebDefaults and without.

Interesting. Playground uses same C++ API under the hood. Minor differences like JS would use YGEdgeAll in the example given. Would need to debug why these two would behave differently.