Files
yoga/yoga/instrumentation.h
David Aurelio f86c74ce7e Call measure and baseline fns within YGNode
Summary:
@public

Stricter encapsulation of baseline and measure callbacks withing `YGNode`.

Instead of invoking these callbacks directly (`node->getBaseline()(...)`), they are invoked via methods on `YGNode` (`node->baseline(...)`).

This change will allow us to add the concept of a *Layout Context,* where measure and baseline functions will be able to receive an additional `void *` argument if configured accordingly. This API will be used internally for Yoga’s JNI bindings, to avoid storing a weak JNI reference for each node, and avoid reference table overflows.

Changed API:

- `YGNodeGetMeasureFunc()` -> `YGNodeHasMeasureFunc()`
- `YGNodeGetBaselineFunc()` -> `YGNodeHasBaselineFunc()`
- `YGNode::getMeasure()` -> `YGNode::hasMeasureFunc()` + `YGNode::measure()`
- `YGNpde::getBaseline()` -> `YGNode::hasBaselineFunc()` + `YGNode::baseline()`

Reviewed By: SidharthGuglani

Differential Revision: D14099550

fbshipit-source-id: 2653ab36acc252a9747986bc88d21dac22d8c91b
2019-02-19 09:58:42 -08:00

64 lines
1.6 KiB
C++

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*/
#include "YGConfig.h"
#include "YGMarker.h"
#include "YGNode.h"
namespace facebook {
namespace yoga {
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_, markerData(&data), userData_);
}
}
typename Data::type data = {};
template <typename Ret, typename... Args>
static Ret wrap(
YGNodeRef node,
Ret (YGNode::*method)(Args...),
Args... args) {
MarkerSection<MarkerType> section{node};
return (node->*method)(std::forward<Args>(args)...);
}
private:
decltype(YGMarkerCallbacks{}.endMarker) endMarker_;
YGNodeRef node_;
void* userData_;
MarkerSection(YGNodeRef node, YGConfigRef config)
: MarkerSection{node, config ? &config->markerCallbacks : nullptr} {}
MarkerSection(YGNodeRef node, YGMarkerCallbacks* callbacks)
: endMarker_{callbacks ? callbacks->endMarker : nullptr},
node_{node},
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
} // namespace yoga
} // namespace facebook