Introducing on-dirty handler (aka `YGNodeSetDirtiedFunc`)

Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.

Reviewed By: emilsjolander

Differential Revision: D6597856

fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
This commit is contained in:
Valentin Shergin 2018-01-10 09:45:08 -08:00 committed by Facebook Github Bot
parent 0205207e02
commit c2b0f34533
3 changed files with 25 additions and 1 deletions

View File

@ -35,6 +35,10 @@ YGBaselineFunc YGNode::getBaseline() const {
return baseline_;
}
YGDirtiedFunc YGNode::getDirtied() const {
return dirtied_;
}
YGStyle& YGNode::getStyle() {
return style_;
}
@ -128,6 +132,10 @@ void YGNode::setBaseLineFunc(YGBaselineFunc baseLineFunc) {
baseline_ = baseLineFunc;
}
void YGNode::setDirtiedFunc(YGDirtiedFunc dirtiedFunc) {
dirtied_ = dirtiedFunc;
}
void YGNode::setStyle(YGStyle style) {
style_ = style;
}
@ -169,7 +177,13 @@ void YGNode::setConfig(YGConfigRef config) {
}
void YGNode::setDirty(bool isDirty) {
if (isDirty == isDirty_) {
return;
}
isDirty_ = isDirty;
if (isDirty && dirtied_) {
dirtied_(this);
}
}
bool YGNode::removeChild(YGNodeRef child) {
@ -238,6 +252,7 @@ YGNode::YGNode()
nodeType_(YGNodeTypeDefault),
measure_(nullptr),
baseline_(nullptr),
dirtied_(nullptr),
style_(gYGNodeStyleDefaults),
layout_(gYGNodeLayoutDefaults),
lineIndex_(0),
@ -255,6 +270,7 @@ YGNode::YGNode(const YGNode& node)
nodeType_(node.nodeType_),
measure_(node.measure_),
baseline_(node.baseline_),
dirtied_(node.dirtied_),
style_(node.style_),
layout_(node.layout_),
lineIndex_(node.lineIndex_),
@ -276,6 +292,7 @@ YGNode::YGNode(
YGNodeType nodeType,
YGMeasureFunc measure,
YGBaselineFunc baseline,
YGDirtiedFunc dirtied,
YGStyle style,
YGLayout layout,
uint32_t lineIndex,
@ -291,6 +308,7 @@ YGNode::YGNode(
nodeType_(nodeType),
measure_(measure),
baseline_(baseline),
dirtied_(dirtied),
style_(style),
layout_(layout),
lineIndex_(lineIndex),
@ -316,6 +334,7 @@ YGNode& YGNode::operator=(const YGNode& node) {
nodeType_ = node.getNodeType();
measure_ = node.getMeasure();
baseline_ = node.getBaseline();
dirtied_ = node.getDirtied();
style_ = node.style_;
layout_ = node.layout_;
lineIndex_ = node.getLineIndex();
@ -415,7 +434,7 @@ void YGNode::cloneChildrenIfNeeded() {
void YGNode::markDirtyAndPropogate() {
if (!isDirty_) {
isDirty_ = true;
setDirty(true);
setLayoutComputedFlexBasis(YGUndefined);
if (parent_) {
parent_->markDirtyAndPropogate();

View File

@ -20,6 +20,7 @@ struct YGNode {
YGNodeType nodeType_;
YGMeasureFunc measure_;
YGBaselineFunc baseline_;
YGDirtiedFunc dirtied_;
YGStyle style_;
YGLayout layout_;
uint32_t lineIndex_;
@ -43,6 +44,7 @@ struct YGNode {
YGNodeType nodeType,
YGMeasureFunc measure,
YGBaselineFunc baseline,
YGDirtiedFunc dirtied,
YGStyle style,
YGLayout layout,
uint32_t lineIndex,
@ -60,6 +62,7 @@ struct YGNode {
YGNodeType getNodeType() const;
YGMeasureFunc getMeasure() const;
YGBaselineFunc getBaseline() const;
YGDirtiedFunc getDirtied() const;
// For Perfomance reasons passing as reference.
YGStyle& getStyle();
// For Perfomance reasons passing as reference.
@ -82,6 +85,7 @@ struct YGNode {
void setNodeType(YGNodeType nodeTye);
void setMeasureFunc(YGMeasureFunc measureFunc);
void setBaseLineFunc(YGBaselineFunc baseLineFunc);
void setDirtiedFunc(YGDirtiedFunc dirtiedFunc);
void setStyle(YGStyle style);
void setStyleFlexDirection(YGFlexDirection direction);
void setStyleAlignContent(YGAlign alignContent);

View File

@ -56,6 +56,7 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node,
float height,
YGMeasureMode heightMode);
typedef float (*YGBaselineFunc)(YGNodeRef node, const float width, const float height);
typedef void (*YGDirtiedFunc)(YGNodeRef node);
typedef void (*YGPrintFunc)(YGNodeRef node);
typedef int (*YGLogger)(const YGConfigRef config,
const YGNodeRef node,