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

View File

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

View File

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