From ef6b916e48204158f649035d08d2183fafeab00b Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 10 Apr 2018 12:45:53 -0700 Subject: [PATCH] Fabric: New approach to manage Yoga's parent/owner references Summary: The modern Concurent Yoga's concept is: We have to set parent/owner reference as part of `appendChild` process only if the current reference to parent/owner is `null`. The motivation: * Null-parent indicates that this node was not attached to anything yet; * So, in this case there is no any concurrent memory access because we always create and (first time) attach the node on same thread; * Simmetrical parent-child relationship indicates that we don't need to (re)clone assosiated ShadowNode (nor Yoga node). Reviewed By: mdvacca Differential Revision: D7467791 fbshipit-source-id: 9a7f517380fde3bb00272de18fd5dc13edb52071 --- .../fabric/view/yoga/YogaLayoutableShadowNode.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp b/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp index 6ad453100..9aadda4d8 100644 --- a/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp +++ b/ReactCommon/fabric/view/yoga/YogaLayoutableShadowNode.cpp @@ -97,6 +97,11 @@ void YogaLayoutableShadowNode::appendChild(SharedYogaLayoutableShadowNode child) auto nonConstYogaNode = std::const_pointer_cast(yogaNode_); auto nonConstChildYogaNode = std::const_pointer_cast(child->yogaNode_); nonConstYogaNode->insertChild(nonConstChildYogaNode.get(), nonConstYogaNode->getChildrenCount()); + + if (nonConstChildYogaNode->getParent() == nullptr) { + child->ensureUnsealed(); + nonConstChildYogaNode->setParent(nonConstYogaNode.get()); + } } void YogaLayoutableShadowNode::layout(LayoutContext layoutContext) { @@ -211,7 +216,14 @@ void YogaLayoutableShadowNode::setYogaNodeChildrenBasedOnShadowNodeChildren(YGNo continue; } - yogaNodeChildren.push_back((YGNode *)yogaLayoutableShadowNode->yogaNode_.get()); + YGNode *yogaNodeChild = (YGNode *)yogaLayoutableShadowNode->yogaNode_.get(); + + yogaNodeChildren.push_back(yogaNodeChild); + + if (yogaNodeChild->getParent() == nullptr) { + yogaLayoutableShadowNode->ensureUnsealed(); + yogaNodeChild->setParent(&yogaNode); + } } yogaNode.setChildren(yogaNodeChildren);