ShadowViewMutationList calculateShadowViewMutations( const ShadowNode &oldRootShadowNode, const ShadowNode &newRootShadowNode ) { // Root shadow nodes must have same tag. assert(oldRootShadowNode.getTag() == newRootShadowNode.getTag()); ShadowViewMutationList mutations; if (oldRootShadowNode != newRootShadowNode) { mutations.push_back( ShadowViewMutation::UpdateMutation( ShadowView(), ShadowView(oldRootShadowNode), ShadowView(newRootShadowNode), -1 ) ); } calculateShadowViewMutations( mutations, ShadowView(oldRootShadowNode), sliceChildShadowNodeViewPairs(oldRootShadowNode), sliceChildShadowNodeViewPairs(newRootShadowNode) ); return mutations; }
LayoutMetrics UIManager::getRelativeLayoutMetrics( const ShadowNode &shadowNode, const ShadowNode *ancestorShadowNode) const { SystraceSection s("UIManager::getRelativeLayoutMetrics"); if (!ancestorShadowNode) { shadowTreeRegistry_->visit( shadowNode.getSurfaceId(), [&](const ShadowTree &shadowTree) { shadowTree.tryCommit( [&](const SharedRootShadowNode &oldRootShadowNode) { ancestorShadowNode = oldRootShadowNode.get(); return nullptr; }); }); } auto layoutableShadowNode = dynamic_cast<const LayoutableShadowNode *>(&shadowNode); auto layoutableAncestorShadowNode = dynamic_cast<const LayoutableShadowNode *>(ancestorShadowNode); if (!layoutableShadowNode || !layoutableAncestorShadowNode) { return EmptyLayoutMetrics; } return layoutableShadowNode->getRelativeLayoutMetrics( *layoutableAncestorShadowNode); }
ShadowView::ShadowView(const ShadowNode &shadowNode): componentName(shadowNode.getComponentName()), componentHandle(shadowNode.getComponentHandle()), tag(shadowNode.getTag()), props(shadowNode.getProps()), eventEmitter(shadowNode.getEventEmitter()), layoutMetrics(layoutMetricsFromShadowNode(shadowNode)), localData(shadowNode.getLocalData()) {}
static void sliceChildShadowNodeViewPairsRecursively(ShadowViewNodePairList &pairList, Point layoutOffset, const ShadowNode &shadowNode) { for (const auto &childShadowNode : shadowNode.getChildren()) { auto shadowView = ShadowView(*childShadowNode); const auto layoutableShadowNode = dynamic_cast<const LayoutableShadowNode *>(childShadowNode.get()); if (layoutableShadowNode && layoutableShadowNode->isLayoutOnly()) { sliceChildShadowNodeViewPairsRecursively( pairList, layoutOffset + shadowView.layoutMetrics.frame.origin, *childShadowNode ); } else { shadowView.layoutMetrics.frame.origin += layoutOffset; pairList.push_back({shadowView, *childShadowNode}); } } }