#ifdef RCT_NEW_ARCH_ENABLED #include "ShadowTreeCloner.h" namespace reanimated { ShadowNode::Unshared cloneShadowTreeWithNewProps( const ShadowNode::Shared &oldRootNode, const ShadowNodeFamily &family, RawProps &&rawProps) { // adapted from ShadowNode::cloneTree auto ancestors = family.getAncestors(*oldRootNode); if (ancestors.empty()) { return ShadowNode::Unshared{nullptr}; } auto &parent = ancestors.back(); auto &source = parent.first.get().getChildren().at(parent.second); PropsParserContext propsParserContext{ source->getSurfaceId(), *source->getContextContainer()}; const auto props = source->getComponentDescriptor().cloneProps( propsParserContext, source->getProps(), rawProps); auto newChildNode = source->clone({/* .props = */ props}); for (auto it = ancestors.rbegin(); it != ancestors.rend(); ++it) { auto &parentNode = it->first.get(); auto childIndex = it->second; auto children = parentNode.getChildren(); const auto &oldChildNode = *children.at(childIndex); react_native_assert(ShadowNode::sameFamily(oldChildNode, *newChildNode)); if (!parentNode.getSealed()) { // Optimization: if a ShadowNode is unsealed, we can directly update its // children instead of cloning the whole path to the root node. auto &parentNodeNonConst = const_cast(parentNode); parentNodeNonConst.replaceChild(oldChildNode, newChildNode, childIndex); // Unfortunately, `replaceChild` does not update Yoga nodes, so we need to // update them manually here. static_cast(&parentNodeNonConst) ->updateYogaChildren(); return std::const_pointer_cast(oldRootNode); } children[childIndex] = newChildNode; newChildNode = parentNode.clone({ ShadowNodeFragment::propsPlaceholder(), std::make_shared(children), }); } return std::const_pointer_cast(newChildNode); } } // namespace reanimated #endif // RCT_NEW_ARCH_ENABLED