コード例 #1
0
YGNode *YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode *oldYogaNode, 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.

  auto &&layoutableChildNodes = parentShadowNodeRawPtr->getLayoutableChildNodes();
  SharedLayoutableShadowNode oldShadowNode = nullptr;

  // We cannot rely on `childIndex` all the time because `childNodes` can
  // contain non-layoutable shadow nodes, however chances are good that
  // `childIndex` points to the right shadow node.

  // Optimistic attempt (in case if `childIndex` is valid):
  if (childIndex < layoutableChildNodes.size()) {
    oldShadowNode = layoutableChildNodes[childIndex];
    if (oldShadowNode.get() == oldShadowNodeRawPtr) {
      goto found;
    } else {
      oldShadowNode = nullptr;
    }
  }

  // General solution:
  for (auto child : layoutableChildNodes) {
    if (child.get() == oldShadowNodeRawPtr) {
      oldShadowNode = child;
      break;
    }
  }

  assert(oldShadowNode);

found:

  // 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);

  return &newShadowNode->yogaNode_;
}