Marker for measure callbacks

Summary:
@public

Wraps measure callbacks with a marker.

Reviewed By: SidharthGuglani

Differential Revision: D13896745

fbshipit-source-id: d6e14fe93f666b06516be1aef7f8e1bfe45440a7
This commit is contained in:
David Aurelio
2019-02-01 03:31:12 -08:00
committed by Facebook Github Bot
parent 719fa3cca3
commit 0d026bd1a0
4 changed files with 66 additions and 12 deletions

View File

@@ -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<YGMarkerLayout>(data);
break;
case YGMarkerMeasure:
break;
};
}
@@ -245,6 +261,8 @@ const char* markerTypeName(YGMarker type) {
switch (type) {
case YGMarkerLayout:
return "YGMarkerLayout";
case YGMarkerMeasure:
return "YGMarkerMeasure";
}
}

View File

@@ -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<YGMarkerLayout> {
using type = YGMarkerLayoutData;
static type*& get(YGMarkerData& d) {
return d.layout;
}
};
template <>
struct MarkerData<YGMarkerMeasure> {
using type = YGMarkerNoData;
static type*& get(YGMarkerData& d) {
return d.noData;
}
};
} // namespace detail
template <YGMarker M>
typename detail::MarkerData<M>::type* data(YGMarkerData) = delete;
template <>
inline YGMarkerLayoutData* data<YGMarkerLayout>(YGMarkerData d) {
return d.layout;
typename detail::MarkerData<M>::type* data(YGMarkerData d) {
return detail::MarkerData<M>::get(d);
}
} // namespace marker

View File

@@ -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<YGMarkerMeasure>::wrap(
node,
node->getMeasure(),
node,
innerWidth,
widthMeasureMode,
innerHeight,
heightMeasureMode);
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(

View File

@@ -14,15 +14,24 @@ namespace marker {
template <YGMarker MarkerType>
class MarkerSection {
private:
using Data = detail::MarkerData<MarkerType>;
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<MarkerType>::type data = {};
typename Data::type data = {};
template <typename Ret, typename... Args>
static Ret wrap(YGNodeRef node, Ret (*fn)(Args...), Args... args) {
MarkerSection<MarkerType> section{node};
return fn(std::forward<Args>(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