diff --git a/tests/InstrumentationTest.cpp b/tests/InstrumentationTest.cpp index 585073ff..07053bff 100644 --- a/tests/InstrumentationTest.cpp +++ b/tests/InstrumentationTest.cpp @@ -197,6 +197,20 @@ TEST_F(MarkerTest, layout_marker_has_max_measure_cache) { (YGMarkerLayoutData{.layouts = 3, .measures = 3, .maxMeasureCache = 7})); } +TEST_F(MarkerTest, measure_functions_get_wrapped) { + auto root = makeNode(); + YGNodeSetMeasureFunc( + root.get(), [](YGNodeRef, float, YGMeasureMode, float, YGMeasureMode) { + return YGSize{}; + }); + + calculateLayout(root); + auto& markerCookie = findLastMarker(YGMarkerMeasure); + + ASSERT_EQ(markerCookie.start.marker, YGMarkerMeasure) + << "have " << markerCookies.size() << " recorded markers"; +} + void* MarkerTest::startMarker( YGMarker marker, YGNodeRef node, @@ -218,6 +232,8 @@ void MarkerTest::endMarker( case YGMarkerLayout: cookie->end.markerData.layout = *marker::data(data); break; + case YGMarkerMeasure: + break; }; } @@ -245,6 +261,8 @@ const char* markerTypeName(YGMarker type) { switch (type) { case YGMarkerLayout: return "YGMarkerLayout"; + case YGMarkerMeasure: + return "YGMarkerMeasure"; } } diff --git a/yoga/YGMarker.h b/yoga/YGMarker.h index 63f2c40f..385ee9cf 100644 --- a/yoga/YGMarker.h +++ b/yoga/YGMarker.h @@ -15,6 +15,7 @@ typedef struct YGConfig* YGConfigRef; typedef YG_ENUM_BEGIN(YGMarker){ YGMarkerLayout, + YGMarkerMeasure, } YG_ENUM_END(YGMarker); typedef struct { @@ -25,8 +26,13 @@ typedef struct { int cachedMeasures; } YGMarkerLayoutData; +typedef struct { + bool _unused; +} YGMarkerNoData; + typedef union { YGMarkerLayoutData* layout; + YGMarkerNoData* noData; } YGMarkerData; typedef struct { @@ -55,16 +61,24 @@ struct MarkerData; template <> struct MarkerData { using type = YGMarkerLayoutData; + static type*& get(YGMarkerData& d) { + return d.layout; + } +}; + +template <> +struct MarkerData { + using type = YGMarkerNoData; + static type*& get(YGMarkerData& d) { + return d.noData; + } }; } // namespace detail template -typename detail::MarkerData::type* data(YGMarkerData) = delete; - -template <> -inline YGMarkerLayoutData* data(YGMarkerData d) { - return d.layout; +typename detail::MarkerData::type* data(YGMarkerData d) { + return detail::MarkerData::get(d); } } // namespace marker diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index f60a153e..eac63d9c 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -1688,8 +1688,14 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( YGDimensionHeight); } else { // Measure the text under the current constraints. - const YGSize measuredSize = node->getMeasure()( - node, innerWidth, widthMeasureMode, innerHeight, heightMeasureMode); + const YGSize measuredSize = marker::MarkerSection::wrap( + node, + node->getMeasure(), + node, + innerWidth, + widthMeasureMode, + innerHeight, + heightMeasureMode); node->setLayoutMeasuredDimension( YGNodeBoundAxis( diff --git a/yoga/instrumentation.h b/yoga/instrumentation.h index 670fc2bd..5cc544c5 100644 --- a/yoga/instrumentation.h +++ b/yoga/instrumentation.h @@ -14,15 +14,24 @@ namespace marker { template class MarkerSection { +private: + using Data = detail::MarkerData; + public: MarkerSection(YGNodeRef node) : MarkerSection{node, node->getConfig()} {} ~MarkerSection() { if (endMarker_) { - endMarker_(MarkerType, node_, {&data}, userData_); + endMarker_(MarkerType, node_, markerData(&data), userData_); } } - typename detail::MarkerData::type data = {}; + typename Data::type data = {}; + + template + static Ret wrap(YGNodeRef node, Ret (*fn)(Args...), Args... args) { + MarkerSection section{node}; + return fn(std::forward(args)...); + } private: decltype(YGMarkerCallbacks{}.endMarker) endMarker_; @@ -34,9 +43,16 @@ private: MarkerSection(YGNodeRef node, YGMarkerCallbacks* callbacks) : endMarker_{callbacks ? callbacks->endMarker : nullptr}, node_{node}, - userData_{callbacks && callbacks->startMarker - ? callbacks->startMarker(MarkerType, node, {&data}) - : nullptr} {} + userData_{ + callbacks && callbacks->startMarker + ? callbacks->startMarker(MarkerType, node, markerData(&data)) + : nullptr} {} + + static YGMarkerData markerData(typename Data::type* d) { + YGMarkerData markerData = {}; + Data::get(markerData) = d; + return markerData; + } }; } // namespace marker