From d2b23167226198a13041e3aebfeeea4abeb05c8e Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 1 Feb 2019 03:31:12 -0800 Subject: [PATCH] Marker for measure callbacks Summary: @public Wraps measure callbacks with a marker. Reviewed By: SidharthGuglani Differential Revision: D13896745 fbshipit-source-id: d6e14fe93f666b06516be1aef7f8e1bfe45440a7 --- ReactCommon/yoga/yoga/YGMarker.h | 24 ++++++++++++++++++----- ReactCommon/yoga/yoga/Yoga.cpp | 10 ++++++++-- ReactCommon/yoga/yoga/instrumentation.h | 26 ++++++++++++++++++++----- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/ReactCommon/yoga/yoga/YGMarker.h b/ReactCommon/yoga/yoga/YGMarker.h index 63f2c40fb..385ee9cf5 100644 --- a/ReactCommon/yoga/yoga/YGMarker.h +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index f60a153ef..eac63d9cd 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/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/ReactCommon/yoga/yoga/instrumentation.h b/ReactCommon/yoga/yoga/instrumentation.h index 670fc2bda..5cc544c5f 100644 --- a/ReactCommon/yoga/yoga/instrumentation.h +++ b/ReactCommon/yoga/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