From 587087c4e7a2e5062b709fc7d7128b30f64ae137 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 18 Mar 2019 19:16:40 -0700 Subject: [PATCH] Fabric: More asserts/invariant-checking in YogaLayoutableShadowNode Summary: More `assert`s and `ensureUnsealed` calls were added to YogaLayoutableShadowNode for simpler debugging and early failing. Reviewed By: JoshuaGross Differential Revision: D14496936 fbshipit-source-id: 898c6a0665aeac5d0b1995bd53046f58cec37007 --- .../view/yoga/YogaLayoutableShadowNode.cpp | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp b/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp index df38fa0a9b2..26b870d0d0e 100644 --- a/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp +++ b/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp @@ -38,6 +38,7 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode( yogaNode_.setConfig(&yogaConfig_); yogaNode_.setContext(this); yogaNode_.setOwner(nullptr); + // Yoga node must inherit dirty flag. assert(layoutableShadowNode.yogaNode_.isDirty() == yogaNode_.isDirty()); } @@ -79,13 +80,18 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) { auto yogaNodeRawPtr = &yogaNode_; auto childYogaNodeRawPtr = &child->yogaNode_; + // Cloned node must not be reinserted to the same parent. + assert(childYogaNodeRawPtr->getOwner() != yogaNodeRawPtr); + if (childYogaNodeRawPtr->getOwner() != nullptr) { child = static_cast( cloneAndReplaceChild(child, yogaNode_.getChildren().size())); childYogaNodeRawPtr = &child->yogaNode_; - assert(childYogaNodeRawPtr->getOwner() == nullptr); } + // Inserted node must have a clear owner (must not be shared). + assert(childYogaNodeRawPtr->getOwner() == nullptr); + child->ensureUnsealed(); childYogaNodeRawPtr->setOwner(yogaNodeRawPtr); @@ -129,6 +135,8 @@ void YogaLayoutableShadowNode::setProps(const YogaStylableProps &props) { } void YogaLayoutableShadowNode::setSize(Size size) const { + ensureUnsealed(); + auto style = yogaNode_.getStyle(); style.dimensions[YGDimensionWidth] = yogaStyleValueFromFloat(size.width); style.dimensions[YGDimensionHeight] = yogaStyleValueFromFloat(size.height); @@ -137,6 +145,8 @@ void YogaLayoutableShadowNode::setSize(Size size) const { void YogaLayoutableShadowNode::setPositionType( YGPositionType positionType) const { + ensureUnsealed(); + auto style = yogaNode_.getStyle(); style.positionType = positionType; yogaNode_.setStyle(style); @@ -177,9 +187,18 @@ void YogaLayoutableShadowNode::layoutChildren(LayoutContext layoutContext) { auto childNode = static_cast(childYogaNode->getContext()); + // Verifying that the Yoga node belongs to the ShadowNode. + assert(&childNode->yogaNode_ == childYogaNode); + LayoutMetrics childLayoutMetrics = layoutMetricsFromYogaNode(childNode->yogaNode_); childLayoutMetrics.pointScaleFactor = layoutContext.pointScaleFactor; + + // We must copy layout metrics from Yoga node only once (when the parent + // node exclusively ownes the child node). + assert(childYogaNode->getOwner() == &yogaNode_); + + childNode->ensureUnsealed(); childNode->setLayoutMetrics(childLayoutMetrics); } }