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}));
|
(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(
|
void* MarkerTest::startMarker(
|
||||||
YGMarker marker,
|
YGMarker marker,
|
||||||
YGNodeRef node,
|
YGNodeRef node,
|
||||||
@@ -218,6 +232,8 @@ void MarkerTest::endMarker(
|
|||||||
case YGMarkerLayout:
|
case YGMarkerLayout:
|
||||||
cookie->end.markerData.layout = *marker::data<YGMarkerLayout>(data);
|
cookie->end.markerData.layout = *marker::data<YGMarkerLayout>(data);
|
||||||
break;
|
break;
|
||||||
|
case YGMarkerMeasure:
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,6 +261,8 @@ const char* markerTypeName(YGMarker type) {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case YGMarkerLayout:
|
case YGMarkerLayout:
|
||||||
return "YGMarkerLayout";
|
return "YGMarkerLayout";
|
||||||
|
case YGMarkerMeasure:
|
||||||
|
return "YGMarkerMeasure";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ typedef struct YGConfig* YGConfigRef;
|
|||||||
|
|
||||||
typedef YG_ENUM_BEGIN(YGMarker){
|
typedef YG_ENUM_BEGIN(YGMarker){
|
||||||
YGMarkerLayout,
|
YGMarkerLayout,
|
||||||
|
YGMarkerMeasure,
|
||||||
} YG_ENUM_END(YGMarker);
|
} YG_ENUM_END(YGMarker);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -25,8 +26,13 @@ typedef struct {
|
|||||||
int cachedMeasures;
|
int cachedMeasures;
|
||||||
} YGMarkerLayoutData;
|
} YGMarkerLayoutData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool _unused;
|
||||||
|
} YGMarkerNoData;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
YGMarkerLayoutData* layout;
|
YGMarkerLayoutData* layout;
|
||||||
|
YGMarkerNoData* noData;
|
||||||
} YGMarkerData;
|
} YGMarkerData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -55,16 +61,24 @@ struct MarkerData;
|
|||||||
template <>
|
template <>
|
||||||
struct MarkerData<YGMarkerLayout> {
|
struct MarkerData<YGMarkerLayout> {
|
||||||
using type = YGMarkerLayoutData;
|
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
|
} // namespace detail
|
||||||
|
|
||||||
template <YGMarker M>
|
template <YGMarker M>
|
||||||
typename detail::MarkerData<M>::type* data(YGMarkerData) = delete;
|
typename detail::MarkerData<M>::type* data(YGMarkerData d) {
|
||||||
|
return detail::MarkerData<M>::get(d);
|
||||||
template <>
|
|
||||||
inline YGMarkerLayoutData* data<YGMarkerLayout>(YGMarkerData d) {
|
|
||||||
return d.layout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace marker
|
} // namespace marker
|
||||||
|
@@ -1688,8 +1688,14 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
|
|||||||
YGDimensionHeight);
|
YGDimensionHeight);
|
||||||
} else {
|
} else {
|
||||||
// Measure the text under the current constraints.
|
// Measure the text under the current constraints.
|
||||||
const YGSize measuredSize = node->getMeasure()(
|
const YGSize measuredSize = marker::MarkerSection<YGMarkerMeasure>::wrap(
|
||||||
node, innerWidth, widthMeasureMode, innerHeight, heightMeasureMode);
|
node,
|
||||||
|
node->getMeasure(),
|
||||||
|
node,
|
||||||
|
innerWidth,
|
||||||
|
widthMeasureMode,
|
||||||
|
innerHeight,
|
||||||
|
heightMeasureMode);
|
||||||
|
|
||||||
node->setLayoutMeasuredDimension(
|
node->setLayoutMeasuredDimension(
|
||||||
YGNodeBoundAxis(
|
YGNodeBoundAxis(
|
||||||
|
@@ -14,15 +14,24 @@ namespace marker {
|
|||||||
|
|
||||||
template <YGMarker MarkerType>
|
template <YGMarker MarkerType>
|
||||||
class MarkerSection {
|
class MarkerSection {
|
||||||
|
private:
|
||||||
|
using Data = detail::MarkerData<MarkerType>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MarkerSection(YGNodeRef node) : MarkerSection{node, node->getConfig()} {}
|
MarkerSection(YGNodeRef node) : MarkerSection{node, node->getConfig()} {}
|
||||||
~MarkerSection() {
|
~MarkerSection() {
|
||||||
if (endMarker_) {
|
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:
|
private:
|
||||||
decltype(YGMarkerCallbacks{}.endMarker) endMarker_;
|
decltype(YGMarkerCallbacks{}.endMarker) endMarker_;
|
||||||
@@ -34,9 +43,16 @@ private:
|
|||||||
MarkerSection(YGNodeRef node, YGMarkerCallbacks* callbacks)
|
MarkerSection(YGNodeRef node, YGMarkerCallbacks* callbacks)
|
||||||
: endMarker_{callbacks ? callbacks->endMarker : nullptr},
|
: endMarker_{callbacks ? callbacks->endMarker : nullptr},
|
||||||
node_{node},
|
node_{node},
|
||||||
userData_{callbacks && callbacks->startMarker
|
userData_{
|
||||||
? callbacks->startMarker(MarkerType, node, {&data})
|
callbacks && callbacks->startMarker
|
||||||
: nullptr} {}
|
? callbacks->startMarker(MarkerType, node, markerData(&data))
|
||||||
|
: nullptr} {}
|
||||||
|
|
||||||
|
static YGMarkerData markerData(typename Data::type* d) {
|
||||||
|
YGMarkerData markerData = {};
|
||||||
|
Data::get(markerData) = d;
|
||||||
|
return markerData;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace marker
|
} // namespace marker
|
||||||
|
Reference in New Issue
Block a user