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:
committed by
Facebook Github Bot
parent
719fa3cca3
commit
0d026bd1a0
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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(
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user