From ab1ed0c320d32a23ac1a1c054282c7553d33eadb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20W=C3=B6hrl?= Date: Thu, 11 Jun 2020 21:21:20 +0200 Subject: [PATCH] fix missing invalidation if owner has undefinied dims --- tests/YGRelayoutTest.cpp | 30 ++++++++++++++++++++++++++++++ yoga/YGLayout.h | 3 +++ yoga/Yoga.cpp | 9 ++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/YGRelayoutTest.cpp b/tests/YGRelayoutTest.cpp index 7a4d1d64..2a326969 100644 --- a/tests/YGRelayoutTest.cpp +++ b/tests/YGRelayoutTest.cpp @@ -49,3 +49,33 @@ TEST(YogaTest, recalculate_resolvedDimonsion_onchange) { YGNodeFreeRecursive(root); } + + +YGSize _measureRecalc(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) { + return YGSize { 0, 0}; +} + +TEST(YogaTest, recalculate_on_layout_values_change) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis, true); + YGConfigSetPointScaleFactor(config, 3.f); + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetAlignContent(root, YGAlignFlexStart); + const YGNodeRef child = YGNodeNewWithConfig(config); + YGNodeStyleSetMinHeightPercent(child, 40.f); + YGNodeStyleSetMaxHeightPercent(child, 60.f); + YGNodeStyleSetHeight(child, 10.f); + YGNodeStyleSetWidth(child, 50.0f); + YGNodeSetMeasureFunc(child, _measureRecalc); + YGNodeInsertChild(root, child, 0); + + YGNodeCalculateLayout(root, 50.0f, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(child)); + + YGNodeCalculateLayout(root, 50.0f, 30.0f, YGDirectionLTR); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetHeight(child)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index b7604d8e..e703e786 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -38,6 +38,9 @@ public: uint32_t generationCount = 0; YGDirection lastOwnerDirection = YGDirectionInherit; + bool lastOwnerHadUndefinedHeight = false; + bool lastOwnerHadUndefinedWidth = false; + uint32_t nextCachedMeasurementsIndex = 0; std::array cachedMeasurements = {}; diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 91e09c15..2ba55bed 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3811,9 +3811,14 @@ bool YGLayoutNodeInternal( depth++; + bool ownerHasUndefinedHeight = YGFloatIsUndefined(ownerHeight); + bool ownerHasUndefinedWidth = YGFloatIsUndefined(ownerWidth); + const bool needToVisitNode = (node->isDirty() && layout->generationCount != generationCount) || - layout->lastOwnerDirection != ownerDirection; + layout->lastOwnerDirection != ownerDirection || + layout->lastOwnerHadUndefinedHeight != ownerHasUndefinedHeight|| + layout->lastOwnerHadUndefinedWidth != ownerHasUndefinedWidth; if (needToVisitNode) { // Invalidate the cached results. @@ -3995,6 +4000,8 @@ bool YGLayoutNodeInternal( } layout->lastOwnerDirection = ownerDirection; + layout->lastOwnerHadUndefinedHeight = ownerHasUndefinedHeight; + layout->lastOwnerHadUndefinedWidth = ownerHasUndefinedWidth; if (cachedResults == nullptr) { if (layout->nextCachedMeasurementsIndex + 1 >