void YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode *oldYogaNode, YGNode *newYogaNode, YGNode *parentYogaNode, int childIndex) { // We have only raw pointer to the parent shadow node, but that's enough for now. YogaLayoutableShadowNode *parentShadowNodeRawPtr = (YogaLayoutableShadowNode *)parentYogaNode->getContext(); assert(parentShadowNodeRawPtr); // Old child shadow node already exists but we have only raw pointer to it... YogaLayoutableShadowNode *oldShadowNodeRawPtr = (YogaLayoutableShadowNode *)oldYogaNode->getContext(); assert(oldShadowNodeRawPtr); // ... but we have to address this by `shared_ptr`. We cannot create a new `shared_ptr` for it because we will end up with two shared pointers to // single object which will cause preluminary destroyng the object. // Another approaches to consider: // * Create a new `shared_ptr` with empty deleter. // * Using `childIndex` to find exact node. SharedLayoutableShadowNode oldShadowNode = nullptr; for (auto child : parentShadowNodeRawPtr->getChildren()) { if (child.get() == oldShadowNodeRawPtr) { oldShadowNode = child; break; } } assert(oldShadowNode); // The new one does not exist yet. So, we have to clone and replace this using `cloneAndReplaceChild`. SharedYogaLayoutableShadowNode newShadowNode = std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(parentShadowNodeRawPtr->cloneAndReplaceChild(oldShadowNode)); assert(newShadowNode); // And finally, we have to replace underline yoga node with the new one provided by Yoga. newYogaNode->setContext((void *)newShadowNode.get()); newShadowNode->yogaNode_ = std::shared_ptr<YGNode>(newYogaNode); }
void YogaLayoutableShadowNode::appendChild(SharedYogaLayoutableShadowNode child) { ensureUnsealed(); auto yogaNodeRawPtr = &yogaNode_; auto childYogaNodeRawPtr = &child->yogaNode_; yogaNodeRawPtr->insertChild(childYogaNodeRawPtr, yogaNodeRawPtr->getChildrenCount()); if (childYogaNodeRawPtr->getOwner() == nullptr) { child->ensureUnsealed(); childYogaNodeRawPtr->setOwner(yogaNodeRawPtr); } }
void YogaLayoutableShadowNode::setYogaNodeChildrenBasedOnShadowNodeChildren(YGNode *yogaNodeRawPtr, const SharedShadowNodeSharedList &children) { auto yogaNodeChildren = YGVector(); for (const SharedShadowNode &shadowNode : *children) { const SharedYogaLayoutableShadowNode yogaLayoutableShadowNode = std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(shadowNode); if (!yogaLayoutableShadowNode) { continue; } auto &&childYogaNodeRawPtr = &yogaLayoutableShadowNode->yogaNode_; yogaNodeChildren.push_back(childYogaNodeRawPtr); if (childYogaNodeRawPtr->getOwner() == nullptr) { yogaLayoutableShadowNode->ensureUnsealed(); childYogaNodeRawPtr->setOwner(yogaNodeRawPtr); } } yogaNodeRawPtr->setChildren(yogaNodeChildren); }
void YogaLayoutableShadowNode::appendChild(SharedYogaLayoutableShadowNode child) { ensureUnsealed(); auto yogaNodeRawPtr = &yogaNode_; auto childYogaNodeRawPtr = &child->yogaNode_; if (childYogaNodeRawPtr->getOwner() != nullptr) { child = std::static_pointer_cast<const YogaLayoutableShadowNode>(cloneAndReplaceChild(child)); childYogaNodeRawPtr = &child->yogaNode_; } child->ensureUnsealed(); childYogaNodeRawPtr->setOwner(yogaNodeRawPtr); yogaNodeRawPtr->insertChild(childYogaNodeRawPtr, yogaNodeRawPtr->getChildren().size()); }