mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Introduce FabricUIManager.findShadowNodeByTag_DEPRECATED
Summary: changelog: [internal] Add findShadowNodeByTag_DEPRECATED` to Fabric's UIManager. This API makes it possible to get ShadowNode reference for given native tag. We will leverage this API to make UIManager.measure* calls backwards compatible in the new architecture. Reviewed By: yungsters Differential Revision: D41550734 fbshipit-source-id: a45b6a76634d034eac70603bad8ac60f9135ff24
This commit is contained in:
committed by
Facebook GitHub Bot
parent
913ebd207c
commit
86786f1d22
@@ -52,10 +52,15 @@ bool ShadowTreeRegistry::visit(
|
||||
}
|
||||
|
||||
void ShadowTreeRegistry::enumerate(
|
||||
std::function<void(const ShadowTree &shadowTree)> const &callback) const {
|
||||
std::function<void(const ShadowTree &shadowTree, bool &stop)> const
|
||||
&callback) const {
|
||||
std::shared_lock<butter::shared_mutex> lock(mutex_);
|
||||
auto stop = false;
|
||||
for (auto const &pair : registry_) {
|
||||
callback(*pair.second);
|
||||
callback(*pair.second, stop);
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,10 +54,12 @@ class ShadowTreeRegistry final {
|
||||
|
||||
/*
|
||||
* Enumerates all stored shadow trees.
|
||||
* Set `stop` to `true` to interrupt the enumeration.
|
||||
* Can be called from any thread.
|
||||
*/
|
||||
void enumerate(
|
||||
std::function<void(const ShadowTree &shadowTree)> const &callback) const;
|
||||
std::function<void(const ShadowTree &shadowTree, bool &stop)> const
|
||||
&callback) const;
|
||||
|
||||
private:
|
||||
mutable butter::shared_mutex mutex_;
|
||||
|
||||
@@ -151,7 +151,7 @@ Scheduler::~Scheduler() {
|
||||
// Then, let's verify that the requirement was satisfied.
|
||||
auto surfaceIds = std::vector<SurfaceId>{};
|
||||
uiManager_->getShadowTreeRegistry().enumerate(
|
||||
[&surfaceIds](ShadowTree const &shadowTree) {
|
||||
[&surfaceIds](ShadowTree const &shadowTree, bool &) {
|
||||
surfaceIds.push_back(shadowTree.getSurfaceId());
|
||||
});
|
||||
|
||||
|
||||
@@ -351,6 +351,55 @@ void UIManager::configureNextLayoutAnimation(
|
||||
}
|
||||
}
|
||||
|
||||
static ShadowNode::Shared findShadowNodeByTagRecursively(
|
||||
ShadowNode::Shared 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) {
|
||||
RootShadowNode const *rootShadowNode;
|
||||
// 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.
|
||||
// We don't want to add a way to access a stored pointer to a root node
|
||||
// because this `findShadowNodeByTag` is deprecated. It is only added
|
||||
// to make migration to the new architecture easier.
|
||||
shadowTree.tryCommit([&](RootShadowNode const &oldRootShadowNode) {
|
||||
rootShadowNode = &oldRootShadowNode;
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
if (rootShadowNode != nullptr) {
|
||||
auto const &children = rootShadowNode->getChildren();
|
||||
if (!children.empty()) {
|
||||
auto const &child = children.front();
|
||||
shadowNode = findShadowNodeByTagRecursively(child, tag);
|
||||
if (shadowNode) {
|
||||
stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return shadowNode;
|
||||
}
|
||||
|
||||
void UIManager::setComponentDescriptorRegistry(
|
||||
const SharedComponentDescriptorRegistry &componentDescriptorRegistry) {
|
||||
componentDescriptorRegistry_ = componentDescriptorRegistry;
|
||||
@@ -440,7 +489,7 @@ void UIManager::stopSurfaceForAnimationDelegate(SurfaceId surfaceId) const {
|
||||
void UIManager::animationTick() const {
|
||||
if (animationDelegate_ != nullptr &&
|
||||
animationDelegate_->shouldAnimateFrame()) {
|
||||
shadowTreeRegistry_.enumerate([](ShadowTree const &shadowTree) {
|
||||
shadowTreeRegistry_.enumerate([](ShadowTree const &shadowTree, bool &) {
|
||||
shadowTree.notifyDelegatesOfUpdates();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -166,6 +166,14 @@ class UIManager final : public ShadowTreeDelegate {
|
||||
const ShadowNode::Shared &shadowNode,
|
||||
std::string const &eventType);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
private:
|
||||
|
||||
@@ -675,6 +675,27 @@ jsi::Value UIManagerBinding::get(
|
||||
return {serialize(ReactEventPriority::Discrete)};
|
||||
}
|
||||
|
||||
if (methodName == "findShadowNodeByTag_DEPRECATED") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
name,
|
||||
1,
|
||||
[uiManager](
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &,
|
||||
jsi::Value const *arguments,
|
||||
size_t) -> jsi::Value {
|
||||
auto shadowNode = uiManager->findShadowNodeByTag_DEPRECATED(
|
||||
tagFromValue(arguments[0]));
|
||||
|
||||
if (!shadowNode) {
|
||||
return jsi::Value::null();
|
||||
}
|
||||
|
||||
return valueFromShadowNode(runtime, shadowNode);
|
||||
});
|
||||
}
|
||||
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user