From 79ef5f9b0f7d48bf029a5b2b8dc7ef63fbe82fc0 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Wed, 4 Sep 2019 23:14:49 -0700 Subject: [PATCH] Fabric: `UIManager::findShadowNodeByTag_DEPRECATED` Summary: The mehtod implements the core functionality of finding a shadow node by given tag. Reviewed By: zackargyle, JoshuaGross, mdvacca Differential Revision: D17175955 fbshipit-source-id: 5cfbb80b2d4e54a33ca9c20a21988df4de54c800 --- ReactCommon/fabric/uimanager/UIManager.cpp | 41 ++++++++++++++++++++++ ReactCommon/fabric/uimanager/UIManager.h | 8 +++++ 2 files changed, 49 insertions(+) diff --git a/ReactCommon/fabric/uimanager/UIManager.cpp b/ReactCommon/fabric/uimanager/UIManager.cpp index ee0e812eb5a..d0ed76dbd73 100644 --- a/ReactCommon/fabric/uimanager/UIManager.cpp +++ b/ReactCommon/fabric/uimanager/UIManager.cpp @@ -191,6 +191,47 @@ void UIManager::dispatchCommand( } } +static ShadowNode::Shared findShadowNodeByTagRecursively( + ShadowNode::Shared const &parentShadowNode, + Tag tag) { + if (parentShadowNode->getTag() == tag) { + return parentShadowNode; + } + + for (ShadowNode::Shared const &shadowNode : parentShadowNode->getChildren()) { + auto result = findShadowNodeByTagRecursively(shadowNode, tag); + if (result) { + return result; + } + } + + return nullptr; +} + +ShadowNode::Shared UIManager::findShadowNodeByTag_DEPRECATED(Tag tag) const { + auto shadowNode = ShadowNode::Shared{}; + + shadowTreeRegistry_.enumerate([&](ShadowTree const &shadowTree, bool &stop) { + auto rootShadowNode = ShadowNode::Shared{}; + // This is tricky. + // The public interface of `ShadowTree` discourages accessing a stored + // pointer to a root node because of the possible data race. + // To work around this, we ask for a commit and immediately cancel it + // returning `nullptr` instead of a new shadow tree. + shadowTree.tryCommit([&](SharedRootShadowNode const &oldRootShadowNode) { + rootShadowNode = oldRootShadowNode; + return nullptr; + }); + + shadowNode = findShadowNodeByTagRecursively(rootShadowNode, tag); + if (shadowNode) { + stop = true; + } + }); + + return shadowNode; +} + void UIManager::setComponentDescriptorRegistry( const SharedComponentDescriptorRegistry &componentDescriptorRegistry) { componentDescriptorRegistry_ = componentDescriptorRegistry; diff --git a/ReactCommon/fabric/uimanager/UIManager.h b/ReactCommon/fabric/uimanager/UIManager.h index 5ba848f87ce..781ac4bd1a3 100644 --- a/ReactCommon/fabric/uimanager/UIManager.h +++ b/ReactCommon/fabric/uimanager/UIManager.h @@ -97,6 +97,14 @@ class UIManager { std::string const &commandName, folly::dynamic const args) const; + /* + * Iterates over all shadow nodes which are parts of all registered surfaces + * and find the one that has given `tag`. Returns `nullptr` if the node wasn't + * found. This is a temporary workaround that should not be used in any core + * functionality. + */ + ShadowNode::Shared findShadowNodeByTag_DEPRECATED(Tag tag) const; + ShadowTreeRegistry const &getShadowTreeRegistry() const; SharedComponentDescriptorRegistry componentDescriptorRegistry_;