Advertisement
mpokhylets

Incorrect cached child size is used because YGNodeCanUseCach

May 4th, 2020
1,485
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.75 KB | None | 0 0
  1. #include <yoga/Yoga.h>
  2.  
  3. YGSize measure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) {
  4.     return YGSize { 0, 0};
  5. }
  6.  
  7. void dumpLayout(YGNodeRef node, char const * indent) {
  8.     float L = YGNodeLayoutGetLeft(node);
  9.     float T = YGNodeLayoutGetTop(node);
  10.     float W = YGNodeLayoutGetWidth(node);
  11.     float H = YGNodeLayoutGetHeight(node);
  12.     printf("%s L=%f, T=%f, W=%f, H=%f, %p\n", indent, L, T, W, H, node);
  13.     uint32_t k = YGNodeGetChildCount(node);
  14.     for (uint32_t i = 0; i < k; i++) {
  15.         YGNodeRef child = YGNodeGetChild(node, i);
  16.         dumpLayout(child, indent - 4);
  17.     }
  18. }
  19.  
  20. void dumpLayout(YGNodeRef node) {
  21.     static char const indentBuffer[] = "                      ";
  22.     dumpLayout(node, indentBuffer + sizeof(indentBuffer) - 1);
  23. }
  24.  
  25. static float const width = 50.f; // Irrelevant
  26.  
  27. // Case1: layout directly - works fine, child gets height of 12
  28. void works1(YGNodeRef parent) {
  29.     YGNodeCalculateLayout(parent, width, 30.f, YGDirectionLTR);
  30.     dumpLayout(parent);
  31. }
  32.  
  33. // Case2: measure, then layout - bug, child gets cached height of 10
  34. void bug(YGNodeRef parent) {
  35.     YGNodeCalculateLayout(parent, width, NAN, YGDirectionLTR);
  36.     dumpLayout(parent);
  37.     YGNodeCalculateLayout(parent, width, 30.f, YGDirectionLTR);
  38.     dumpLayout(parent);
  39. }
  40.  
  41. // Case2: measure, layout, re-layout - works, because cache gets invalidated
  42. void works2(YGNodeRef parent) {
  43.     YGNodeCalculateLayout(parent, width, NAN, YGDirectionLTR);
  44.     dumpLayout(parent);
  45.     YGNodeCalculateLayout(parent, width, 10.f, YGDirectionLTR);
  46.     dumpLayout(parent);
  47.     YGNodeCalculateLayout(parent, width, 30.f, YGDirectionLTR);
  48.     dumpLayout(parent);
  49. }
  50.  
  51. void test(void (*body)(YGNodeRef), char const * name) {
  52.     printf("-- Case: %s --\n", name);
  53.     YGConfigRef config = YGConfigNew();
  54.     YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis, true);
  55.     YGConfigSetPointScaleFactor(config, 3.f);
  56.     YGNodeRef parent = YGNodeNewWithConfig(config);
  57.     YGNodeStyleSetFlexDirection(parent, YGFlexDirectionRow);
  58.     YGNodeStyleSetAlignItems(parent, YGAlignFlexStart);
  59.     YGNodeStyleSetAlignContent(parent, YGAlignFlexStart);
  60.     YGNodeRef child = YGNodeNewWithConfig(config);
  61.     YGNodeStyleSetMinHeightPercent(child, 40.f);
  62.     YGNodeStyleSetMaxHeightPercent(child, 60.f);
  63.     YGNodeStyleSetHeight(child, 10.f);
  64.     YGNodeStyleSetWidth(child, width);
  65.     YGNodeSetMeasureFunc(child, measure);
  66.     YGNodeInsertChild(parent, child, 0);
  67.     body(parent);
  68.     YGNodeFree(parent);
  69.     YGNodeFree(child);
  70.     YGConfigFree(config);
  71. }
  72.  
  73. int main() {
  74.     test(works1, "1. layout");
  75.     test(bug, "2. measure & layout");
  76.     test(works2, "3. measure, layout, re-layout");
  77.     return 0;
  78. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement