mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Expose instance handles from shadow nodes directly, instead of from event emitters/targets (#37553)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37553 ## Context I added some getters in EventTarget/EventEmitter to access the React instance handle for a given shadow node/shadow node family in https://github.com/facebook/react-native/commit/43864a1d6025bfc4483dded115d51f7613018199 (D44022477), so I could implement DOM traversal methods easily. I wanted to reuse that method to implement `MutationObserver` and `IntersectionObserver`, but unfortunately `EventEmitter`/`EventTarget` only allow access to the instance handle as long as the shadow node is mounted. That makes sense for events, but not for this use case, as with `MutationObserver` we intentionally want to have access to unmounted nodes when creating the list of `addedNodes` and `removedNodes` for the `MutationRecord` (depending on when exactly we generate this list, either `addedNodes` or `removedNodes` wouldn't be mounted). ## Changes This reverts my original change and adds a new field in `ShadowNodeFamily` to provide access to the `InstanceHandle` at any point (even if the node isn't mounted). This provides the same guarantees as the original method, keeping weak references to the handles to avoid memory leaks. Changelog: [internal] Reviewed By: sammy-SC Differential Revision: D46149084 fbshipit-source-id: f76abae50134a5d55a98cab42eebeb62084024f9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a88c0edbd3
commit
325072575a
+1
-3
@@ -56,8 +56,6 @@ static void testShadowNodeTreeLifeCycleLayoutAnimations(
|
||||
ViewComponentDescriptor(componentDescriptorParameters);
|
||||
auto rootComponentDescriptor =
|
||||
RootComponentDescriptor(componentDescriptorParameters);
|
||||
auto noopEventEmitter =
|
||||
std::make_shared<ViewEventEmitter const>(nullptr, -1, eventDispatcher);
|
||||
|
||||
PropsParserContext parserContext{-1, *contextContainer};
|
||||
|
||||
@@ -95,7 +93,7 @@ static void testShadowNodeTreeLifeCycleLayoutAnimations(
|
||||
auto surfaceId = SurfaceId(surfaceIdInt);
|
||||
|
||||
auto family = rootComponentDescriptor.createFamily(
|
||||
{Tag(surfaceIdInt), surfaceId, nullptr}, nullptr);
|
||||
{Tag(surfaceIdInt), surfaceId, nullptr});
|
||||
|
||||
// Creating an initial root shadow node.
|
||||
auto emptyRootNode = std::const_pointer_cast<RootShadowNode>(
|
||||
|
||||
+4
-3
@@ -126,12 +126,13 @@ ShadowNode::Shared ComponentDescriptorRegistry::createNode(
|
||||
std::string const &viewName,
|
||||
SurfaceId surfaceId,
|
||||
folly::dynamic const &propsDynamic,
|
||||
SharedEventTarget const &eventTarget) const {
|
||||
InstanceHandle::Shared const &instanceHandle) const {
|
||||
auto unifiedComponentName = componentNameByReactViewName(viewName);
|
||||
auto const &componentDescriptor = this->at(unifiedComponentName);
|
||||
|
||||
auto const fragment = ShadowNodeFamilyFragment{tag, surfaceId, nullptr};
|
||||
auto family = componentDescriptor.createFamily(fragment, eventTarget);
|
||||
auto const fragment =
|
||||
ShadowNodeFamilyFragment{tag, surfaceId, instanceHandle};
|
||||
auto family = componentDescriptor.createFamily(fragment);
|
||||
auto const props = componentDescriptor.cloneProps(
|
||||
PropsParserContext{surfaceId, *contextContainer_.get()},
|
||||
nullptr,
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
|
||||
#include <react/renderer/core/ComponentDescriptor.h>
|
||||
#include <react/renderer/core/InstanceHandle.h>
|
||||
#include <react/utils/ContextContainer.h>
|
||||
|
||||
namespace facebook::react {
|
||||
@@ -59,7 +60,7 @@ class ComponentDescriptorRegistry {
|
||||
std::string const &viewName,
|
||||
SurfaceId surfaceId,
|
||||
folly::dynamic const &props,
|
||||
SharedEventTarget const &eventTarget) const;
|
||||
InstanceHandle::Shared const &instanceHandle) const;
|
||||
|
||||
void setFallbackComponentDescriptor(
|
||||
const SharedComponentDescriptor &descriptor);
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/core/EventDispatcher.h>
|
||||
#include <react/renderer/core/EventEmitter.h>
|
||||
#include <react/renderer/core/InstanceHandle.h>
|
||||
#include <react/renderer/core/Props.h>
|
||||
#include <react/renderer/core/PropsParserContext.h>
|
||||
#include <react/renderer/core/RawPropsParser.h>
|
||||
@@ -136,8 +138,13 @@ class ComponentDescriptor {
|
||||
* Creates a shadow node family for particular node.
|
||||
*/
|
||||
virtual ShadowNodeFamily::Shared createFamily(
|
||||
ShadowNodeFamilyFragment const &fragment,
|
||||
SharedEventTarget eventTarget) const = 0;
|
||||
ShadowNodeFamilyFragment const &fragment) const = 0;
|
||||
|
||||
/*
|
||||
* Creates an event emitter for particular node.
|
||||
*/
|
||||
virtual SharedEventEmitter createEventEmitter(
|
||||
InstanceHandle::Shared const &instanceHandle) const = 0;
|
||||
|
||||
protected:
|
||||
EventDispatcher::Weak eventDispatcher_;
|
||||
|
||||
@@ -180,17 +180,20 @@ class ConcreteComponentDescriptor : public ComponentDescriptor {
|
||||
}
|
||||
|
||||
ShadowNodeFamily::Shared createFamily(
|
||||
ShadowNodeFamilyFragment const &fragment,
|
||||
SharedEventTarget eventTarget) const override {
|
||||
auto eventEmitter = std::make_shared<ConcreteEventEmitter const>(
|
||||
std::move(eventTarget), fragment.tag, eventDispatcher_);
|
||||
ShadowNodeFamilyFragment const &fragment) const override {
|
||||
return std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
fragment.tag, fragment.surfaceId, eventEmitter},
|
||||
fragment.tag, fragment.surfaceId, fragment.instanceHandle},
|
||||
eventDispatcher_,
|
||||
*this);
|
||||
}
|
||||
|
||||
SharedEventEmitter createEventEmitter(
|
||||
InstanceHandle::Shared const &instanceHandle) const override {
|
||||
return std::make_shared<ConcreteEventEmitter const>(
|
||||
std::make_shared<EventTarget>(instanceHandle), eventDispatcher_);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Called immediately after `ShadowNode` is created or cloned.
|
||||
|
||||
@@ -43,7 +43,6 @@ ValueFactory EventEmitter::defaultPayloadFactory() {
|
||||
|
||||
EventEmitter::EventEmitter(
|
||||
SharedEventTarget eventTarget,
|
||||
Tag /*tag*/,
|
||||
EventDispatcher::Weak eventDispatcher)
|
||||
: eventTarget_(std::move(eventTarget)),
|
||||
eventDispatcher_(std::move(eventDispatcher)) {}
|
||||
@@ -131,8 +130,4 @@ void EventEmitter::setEnabled(bool enabled) const {
|
||||
}
|
||||
}
|
||||
|
||||
const SharedEventTarget &EventEmitter::getEventTarget() const {
|
||||
return eventTarget_;
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -38,7 +38,6 @@ class EventEmitter {
|
||||
|
||||
EventEmitter(
|
||||
SharedEventTarget eventTarget,
|
||||
Tag tag,
|
||||
EventDispatcher::Weak eventDispatcher);
|
||||
|
||||
virtual ~EventEmitter() = default;
|
||||
@@ -55,8 +54,6 @@ class EventEmitter {
|
||||
*/
|
||||
void setEnabled(bool enabled) const;
|
||||
|
||||
SharedEventTarget const &getEventTarget() const;
|
||||
|
||||
protected:
|
||||
#ifdef ANDROID
|
||||
// We need this temporarily due to lack of Java-counterparts for particular
|
||||
|
||||
@@ -13,14 +13,9 @@ namespace facebook::react {
|
||||
|
||||
using Tag = EventTarget::Tag;
|
||||
|
||||
EventTarget::EventTarget(
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &instanceHandle,
|
||||
Tag tag)
|
||||
: weakInstanceHandle_(
|
||||
jsi::WeakObject(runtime, instanceHandle.asObject(runtime))),
|
||||
strongInstanceHandle_(jsi::Value::null()),
|
||||
tag_(tag) {}
|
||||
EventTarget::EventTarget(InstanceHandle::Shared instanceHandle)
|
||||
: instanceHandle_(std::move(instanceHandle)),
|
||||
strongInstanceHandle_(jsi::Value::null()) {}
|
||||
|
||||
void EventTarget::setEnabled(bool enabled) const {
|
||||
enabled_ = enabled;
|
||||
@@ -31,7 +26,7 @@ void EventTarget::retain(jsi::Runtime &runtime) const {
|
||||
return;
|
||||
}
|
||||
|
||||
strongInstanceHandle_ = weakInstanceHandle_.lock(runtime);
|
||||
strongInstanceHandle_ = instanceHandle_->getInstanceHandle(runtime);
|
||||
|
||||
// Having a `null` or `undefined` object here indicates that
|
||||
// `weakInstanceHandle_` was already deallocated. This should *not* happen by
|
||||
@@ -62,7 +57,7 @@ jsi::Value EventTarget::getInstanceHandle(jsi::Runtime &runtime) const {
|
||||
}
|
||||
|
||||
Tag EventTarget::getTag() const {
|
||||
return tag_;
|
||||
return instanceHandle_->getTag();
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/core/InstanceHandle.h>
|
||||
#include <memory>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
@@ -34,7 +34,7 @@ class EventTarget {
|
||||
/*
|
||||
* Constructs an EventTarget from a weak instance handler and a tag.
|
||||
*/
|
||||
EventTarget(jsi::Runtime &runtime, jsi::Value const &instanceHandle, Tag tag);
|
||||
explicit EventTarget(InstanceHandle::Shared instanceHandle);
|
||||
|
||||
/*
|
||||
* Sets the `enabled` flag that allows creating a strong instance handle from
|
||||
@@ -65,10 +65,9 @@ class EventTarget {
|
||||
Tag getTag() const;
|
||||
|
||||
private:
|
||||
const InstanceHandle::Shared instanceHandle_;
|
||||
mutable bool enabled_{false}; // Protected by `EventEmitter::DispatchMutex()`.
|
||||
mutable jsi::WeakObject weakInstanceHandle_; // Protected by `jsi::Runtime &`.
|
||||
mutable jsi::Value strongInstanceHandle_; // Protected by `jsi::Runtime &`.
|
||||
Tag tag_;
|
||||
};
|
||||
|
||||
using SharedEventTarget = std::shared_ptr<const EventTarget>;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "InstanceHandle.h"
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
InstanceHandle::InstanceHandle(
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &instanceHandle,
|
||||
Tag tag)
|
||||
: weakInstanceHandle_(
|
||||
jsi::WeakObject(runtime, instanceHandle.asObject(runtime))),
|
||||
tag_(tag) {}
|
||||
|
||||
jsi::Value InstanceHandle::getInstanceHandle(jsi::Runtime &runtime) const {
|
||||
return weakInstanceHandle_.lock(runtime);
|
||||
}
|
||||
|
||||
Tag InstanceHandle::getTag() const {
|
||||
return tag_;
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/core/ReactPrimitives.h>
|
||||
#include <memory>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class InstanceHandle {
|
||||
public:
|
||||
using Shared = std::shared_ptr<const InstanceHandle>;
|
||||
|
||||
InstanceHandle(
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &instanceHandle,
|
||||
Tag tag);
|
||||
|
||||
/*
|
||||
* Creates and returns the `instanceHandle`.
|
||||
* Returns `null` if the `instanceHandle` is not retained at this moment.
|
||||
*/
|
||||
jsi::Value getInstanceHandle(jsi::Runtime &runtime) const;
|
||||
|
||||
/*
|
||||
* Deprecated. Do not use.
|
||||
*/
|
||||
Tag getTag() const;
|
||||
|
||||
private:
|
||||
const jsi::WeakObject weakInstanceHandle_; // Protected by `jsi::Runtime &`.
|
||||
const Tag tag_;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -17,8 +17,6 @@ namespace facebook::react {
|
||||
* `Tag` and `InstanceHandle` are used to address React Native components.
|
||||
*/
|
||||
using Tag = int32_t;
|
||||
using InstanceHandle = struct InstanceHandleDummyStruct {
|
||||
} *;
|
||||
|
||||
/*
|
||||
* An id of a running Surface instance that is used to refer to the instance.
|
||||
|
||||
@@ -174,6 +174,15 @@ const SharedEventEmitter &ShadowNode::getEventEmitter() const {
|
||||
return family_->eventEmitter_;
|
||||
}
|
||||
|
||||
jsi::Value ShadowNode::getInstanceHandle(jsi::Runtime &runtime) const {
|
||||
auto instanceHandle = family_->instanceHandle_;
|
||||
if (instanceHandle == nullptr) {
|
||||
return jsi::Value::null();
|
||||
}
|
||||
|
||||
return instanceHandle->getInstanceHandle(runtime);
|
||||
}
|
||||
|
||||
Tag ShadowNode::getTag() const {
|
||||
return family_->tag_;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ class ShadowNode : public Sealable,
|
||||
Props::Shared const &getProps() const;
|
||||
ListOfShared const &getChildren() const;
|
||||
SharedEventEmitter const &getEventEmitter() const;
|
||||
jsi::Value getInstanceHandle(jsi::Runtime &runtime) const;
|
||||
Tag getTag() const;
|
||||
SurfaceId getSurfaceId() const;
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ ShadowNodeFamily::ShadowNodeFamily(
|
||||
: eventDispatcher_(std::move(eventDispatcher)),
|
||||
tag_(fragment.tag),
|
||||
surfaceId_(fragment.surfaceId),
|
||||
eventEmitter_(fragment.eventEmitter),
|
||||
instanceHandle_(fragment.instanceHandle),
|
||||
eventEmitter_(
|
||||
componentDescriptor.createEventEmitter(fragment.instanceHandle)),
|
||||
componentDescriptor_(componentDescriptor),
|
||||
componentHandle_(componentDescriptor.getComponentHandle()),
|
||||
componentName_(componentDescriptor.getComponentName()) {}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <butter/small_vector.h>
|
||||
|
||||
#include <react/renderer/core/EventEmitter.h>
|
||||
#include <react/renderer/core/InstanceHandle.h>
|
||||
#include <react/renderer/core/ReactPrimitives.h>
|
||||
|
||||
namespace facebook::react {
|
||||
@@ -36,7 +37,7 @@ class State;
|
||||
struct ShadowNodeFamilyFragment {
|
||||
Tag const tag;
|
||||
SurfaceId const surfaceId;
|
||||
EventEmitter::Shared const &eventEmitter;
|
||||
InstanceHandle::Shared const &instanceHandle;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -137,6 +138,11 @@ class ShadowNodeFamily final {
|
||||
*/
|
||||
SurfaceId const surfaceId_;
|
||||
|
||||
/*
|
||||
* Weak reference to the React instance handle
|
||||
*/
|
||||
InstanceHandle::Shared const instanceHandle_;
|
||||
|
||||
/*
|
||||
* `EventEmitter` associated with all nodes of the family.
|
||||
*/
|
||||
|
||||
+25
-35
@@ -29,13 +29,11 @@ TEST(ComponentDescriptorTest, createShadowNode) {
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
Props::Shared props = descriptor->cloneProps(parserContext, nullptr, raw);
|
||||
|
||||
auto family = descriptor->createFamily(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
nullptr);
|
||||
auto family = descriptor->createFamily(ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
});
|
||||
|
||||
ShadowNode::Shared node = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
@@ -62,13 +60,11 @@ TEST(ComponentDescriptorTest, cloneShadowNode) {
|
||||
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
Props::Shared props = descriptor->cloneProps(parserContext, nullptr, raw);
|
||||
auto family = descriptor->createFamily(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
nullptr);
|
||||
auto family = descriptor->createFamily(ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
});
|
||||
ShadowNode::Shared node = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
@@ -97,37 +93,31 @@ TEST(ComponentDescriptorTest, appendChild) {
|
||||
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
Props::Shared props = descriptor->cloneProps(parserContext, nullptr, raw);
|
||||
auto family1 = descriptor->createFamily(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 1,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
nullptr);
|
||||
auto family1 = descriptor->createFamily(ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 1,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
});
|
||||
ShadowNode::Shared node1 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
family1);
|
||||
auto family2 = descriptor->createFamily(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 2,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
nullptr);
|
||||
auto family2 = descriptor->createFamily(ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 2,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
});
|
||||
ShadowNode::Shared node2 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
family2);
|
||||
auto family3 = descriptor->createFamily(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 3,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
nullptr);
|
||||
auto family3 = descriptor->createFamily(ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 3,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
});
|
||||
ShadowNode::Shared node3 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
|
||||
@@ -41,7 +41,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 11,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -57,7 +57,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 12,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -73,7 +73,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 13,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -92,7 +92,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 15,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -108,7 +108,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 16,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -127,7 +127,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 17,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -143,7 +143,7 @@ class ShadowNodeTest : public ::testing::Test {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 18,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
@@ -174,7 +174,7 @@ TEST_F(ShadowNodeTest, handleShadowNodeCreation) {
|
||||
EXPECT_STREQ(nodeZ_->getComponentName(), "Test");
|
||||
EXPECT_EQ(nodeZ_->getTag(), 18);
|
||||
EXPECT_EQ(nodeZ_->getSurfaceId(), surfaceId_);
|
||||
EXPECT_EQ(nodeZ_->getEventEmitter(), nullptr);
|
||||
EXPECT_NE(nodeZ_->getEventEmitter(), nullptr);
|
||||
EXPECT_EQ(nodeZ_->getChildren().size(), 0);
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ TEST_F(ShadowNodeTest, handleState) {
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ surfaceId_,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
/* .instanceHandle = */ nullptr,
|
||||
},
|
||||
eventDispatcher_,
|
||||
componentDescriptor_);
|
||||
|
||||
@@ -26,10 +26,8 @@ ShadowNode::Unshared ComponentBuilder::build(
|
||||
children.push_back(build(childFragment));
|
||||
}
|
||||
|
||||
auto family = componentDescriptor.createFamily(
|
||||
ShadowNodeFamilyFragment{
|
||||
elementFragment.tag, elementFragment.surfaceId, nullptr},
|
||||
nullptr);
|
||||
auto family = componentDescriptor.createFamily(ShadowNodeFamilyFragment{
|
||||
elementFragment.tag, elementFragment.surfaceId, nullptr});
|
||||
|
||||
auto initialState =
|
||||
componentDescriptor.createInitialState(elementFragment.props, family);
|
||||
|
||||
@@ -225,9 +225,6 @@ ShadowTree::ShadowTree(
|
||||
ShadowTreeDelegate const &delegate,
|
||||
ContextContainer const &contextContainer)
|
||||
: surfaceId_(surfaceId), delegate_(delegate) {
|
||||
const auto noopEventEmitter = std::make_shared<const ViewEventEmitter>(
|
||||
nullptr, -1, std::shared_ptr<const EventDispatcher>());
|
||||
|
||||
static auto globalRootComponentDescriptor =
|
||||
std::make_unique<RootComponentDescriptor const>(
|
||||
ComponentDescriptorParameters{
|
||||
@@ -239,9 +236,8 @@ ShadowTree::ShadowTree(
|
||||
layoutConstraints,
|
||||
layoutContext);
|
||||
|
||||
auto const fragment =
|
||||
ShadowNodeFamilyFragment{surfaceId, surfaceId, noopEventEmitter};
|
||||
auto family = globalRootComponentDescriptor->createFamily(fragment, nullptr);
|
||||
auto const fragment = ShadowNodeFamilyFragment{surfaceId, surfaceId, nullptr};
|
||||
auto family = globalRootComponentDescriptor->createFamily(fragment);
|
||||
|
||||
auto rootShadowNode = std::static_pointer_cast<const RootShadowNode>(
|
||||
globalRootComponentDescriptor->createShadowNode(
|
||||
|
||||
@@ -53,7 +53,7 @@ static ShadowNode::Shared makeNode(
|
||||
return componentDescriptor.createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
props, std::make_shared<ShadowNode::ListOfShared>(children)},
|
||||
componentDescriptor.createFamily({tag, SurfaceId(1), nullptr}, nullptr));
|
||||
componentDescriptor.createFamily({tag, SurfaceId(1), nullptr}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,8 +79,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
||||
auto rootComponentDescriptor =
|
||||
RootComponentDescriptor(componentDescriptorParameters);
|
||||
|
||||
auto rootFamily = rootComponentDescriptor.createFamily(
|
||||
{Tag(1), SurfaceId(1), nullptr}, nullptr);
|
||||
auto rootFamily =
|
||||
rootComponentDescriptor.createFamily({Tag(1), SurfaceId(1), nullptr});
|
||||
|
||||
// Creating an initial root shadow node.
|
||||
auto emptyRootNode = std::const_pointer_cast<RootShadowNode>(
|
||||
@@ -110,8 +110,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
||||
auto childJ = makeNode(viewComponentDescriptor, 109, {});
|
||||
auto childK = makeNode(viewComponentDescriptor, 110, {});
|
||||
|
||||
auto family = viewComponentDescriptor.createFamily(
|
||||
{10, SurfaceId(1), nullptr}, nullptr);
|
||||
auto family =
|
||||
viewComponentDescriptor.createFamily({10, SurfaceId(1), nullptr});
|
||||
|
||||
// Construct "identical" shadow nodes: they differ only in children.
|
||||
auto shadowNodeV1 = viewComponentDescriptor.createShadowNode(
|
||||
@@ -390,8 +390,8 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
||||
auto rootComponentDescriptor =
|
||||
RootComponentDescriptor(componentDescriptorParameters);
|
||||
|
||||
auto rootFamily = rootComponentDescriptor.createFamily(
|
||||
{Tag(1), SurfaceId(1), nullptr}, nullptr);
|
||||
auto rootFamily =
|
||||
rootComponentDescriptor.createFamily({Tag(1), SurfaceId(1), nullptr});
|
||||
|
||||
// Creating an initial root shadow node.
|
||||
auto emptyRootNode = std::const_pointer_cast<RootShadowNode>(
|
||||
@@ -422,8 +422,8 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
||||
auto childJ = makeNode(viewComponentDescriptor, 109, {});
|
||||
auto childK = makeNode(viewComponentDescriptor, 110, {});
|
||||
|
||||
auto family = viewComponentDescriptor.createFamily(
|
||||
{10, SurfaceId(1), nullptr}, nullptr);
|
||||
auto family =
|
||||
viewComponentDescriptor.createFamily({10, SurfaceId(1), nullptr});
|
||||
|
||||
auto reparentedViewA = makeNode(
|
||||
viewComponentDescriptor,
|
||||
|
||||
+4
-8
@@ -42,8 +42,6 @@ static void testShadowNodeTreeLifeCycle(
|
||||
ViewComponentDescriptor(componentDescriptorParameters);
|
||||
auto rootComponentDescriptor =
|
||||
RootComponentDescriptor(componentDescriptorParameters);
|
||||
auto noopEventEmitter =
|
||||
std::make_shared<ViewEventEmitter const>(nullptr, -1, eventDispatcher);
|
||||
|
||||
PropsParserContext parserContext{-1, *contextContainer};
|
||||
|
||||
@@ -52,8 +50,8 @@ static void testShadowNodeTreeLifeCycle(
|
||||
for (int i = 0; i < repeats; i++) {
|
||||
allNodes.clear();
|
||||
|
||||
auto family = rootComponentDescriptor.createFamily(
|
||||
{Tag(1), SurfaceId(1), nullptr}, nullptr);
|
||||
auto family =
|
||||
rootComponentDescriptor.createFamily({Tag(1), SurfaceId(1), nullptr});
|
||||
|
||||
// Creating an initial root shadow node.
|
||||
auto emptyRootNode = std::const_pointer_cast<RootShadowNode>(
|
||||
@@ -195,8 +193,6 @@ static void testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening(
|
||||
ViewComponentDescriptor(componentDescriptorParameters);
|
||||
auto rootComponentDescriptor =
|
||||
RootComponentDescriptor(componentDescriptorParameters);
|
||||
auto noopEventEmitter =
|
||||
std::make_shared<ViewEventEmitter const>(nullptr, -1, eventDispatcher);
|
||||
|
||||
PropsParserContext parserContext{-1, *contextContainer};
|
||||
|
||||
@@ -205,8 +201,8 @@ static void testShadowNodeTreeLifeCycleExtensiveFlatteningUnflattening(
|
||||
for (int i = 0; i < repeats; i++) {
|
||||
allNodes.clear();
|
||||
|
||||
auto family = rootComponentDescriptor.createFamily(
|
||||
{Tag(1), SurfaceId(1), nullptr}, nullptr);
|
||||
auto family =
|
||||
rootComponentDescriptor.createFamily({Tag(1), SurfaceId(1), nullptr});
|
||||
|
||||
// Creating an initial root shadow node.
|
||||
auto emptyRootNode = std::const_pointer_cast<RootShadowNode>(
|
||||
|
||||
@@ -68,7 +68,7 @@ ShadowNode::Shared UIManager::createNode(
|
||||
std::string const &name,
|
||||
SurfaceId surfaceId,
|
||||
const RawProps &rawProps,
|
||||
SharedEventTarget eventTarget) const {
|
||||
const InstanceHandle::Shared &instanceHandle) const {
|
||||
SystraceSection s("UIManager::createNode");
|
||||
|
||||
auto &componentDescriptor = componentDescriptorRegistry_->at(name);
|
||||
@@ -77,9 +77,9 @@ ShadowNode::Shared UIManager::createNode(
|
||||
|
||||
PropsParserContext propsParserContext{surfaceId, *contextContainer_.get()};
|
||||
|
||||
auto const fragment = ShadowNodeFamilyFragment{tag, surfaceId, nullptr};
|
||||
auto family =
|
||||
componentDescriptor.createFamily(fragment, std::move(eventTarget));
|
||||
auto const fragment =
|
||||
ShadowNodeFamilyFragment{tag, surfaceId, instanceHandle};
|
||||
auto family = componentDescriptor.createFamily(fragment);
|
||||
auto const props =
|
||||
componentDescriptor.cloneProps(propsParserContext, nullptr, rawProps);
|
||||
auto const state = componentDescriptor.createInitialState(props, family);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <shared_mutex>
|
||||
|
||||
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||
#include <react/renderer/core/InstanceHandle.h>
|
||||
#include <react/renderer/core/RawValue.h>
|
||||
#include <react/renderer/core/ShadowNode.h>
|
||||
#include <react/renderer/core/StateData.h>
|
||||
@@ -134,7 +135,7 @@ class UIManager final : public ShadowTreeDelegate {
|
||||
std::string const &componentName,
|
||||
SurfaceId surfaceId,
|
||||
const RawProps &props,
|
||||
SharedEventTarget eventTarget) const;
|
||||
const InstanceHandle::Shared &instanceHandle) const;
|
||||
|
||||
ShadowNode::Shared cloneNode(
|
||||
ShadowNode const &shadowNode,
|
||||
|
||||
@@ -186,12 +186,13 @@ jsi::Value UIManagerBinding::get(
|
||||
jsi::Value const & /*thisValue*/,
|
||||
jsi::Value const *arguments,
|
||||
size_t /*count*/) noexcept -> jsi::Value {
|
||||
auto eventTarget =
|
||||
eventTargetFromValue(runtime, arguments[4], arguments[0]);
|
||||
if (!eventTarget) {
|
||||
auto instanceHandle =
|
||||
instanceHandleFromValue(runtime, arguments[4], arguments[0]);
|
||||
if (!instanceHandle) {
|
||||
react_native_assert(false);
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
return valueFromShadowNode(
|
||||
runtime,
|
||||
uiManager->createNode(
|
||||
@@ -199,7 +200,7 @@ jsi::Value UIManagerBinding::get(
|
||||
stringFromValue(runtime, arguments[1]),
|
||||
surfaceIdFromValue(runtime, arguments[2]),
|
||||
RawProps(runtime, arguments[3]),
|
||||
eventTarget));
|
||||
instanceHandle));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -798,7 +799,7 @@ jsi::Value UIManagerBinding::get(
|
||||
return jsi::Value::null();
|
||||
}
|
||||
|
||||
return getInstanceHandleFromShadowNode(parentShadowNode, runtime);
|
||||
return (*parentShadowNode).getInstanceHandle(runtime);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1006,8 +1007,7 @@ jsi::Value UIManagerBinding::get(
|
||||
|
||||
return jsi::Array::createWithElements(
|
||||
runtime,
|
||||
getInstanceHandleFromShadowNode(
|
||||
newestParentOfShadowNode, runtime),
|
||||
(*newestParentOfShadowNode).getInstanceHandle(runtime),
|
||||
jsi::Value{runtime, (double)offsetTop},
|
||||
jsi::Value{runtime, (double)offsetLeft});
|
||||
});
|
||||
|
||||
@@ -142,16 +142,16 @@ inline static Tag tagFromValue(jsi::Value const &value) {
|
||||
return (Tag)value.getNumber();
|
||||
}
|
||||
|
||||
inline static SharedEventTarget eventTargetFromValue(
|
||||
inline static InstanceHandle::Shared instanceHandleFromValue(
|
||||
jsi::Runtime &runtime,
|
||||
jsi::Value const &eventTargetValue,
|
||||
jsi::Value const &instanceHandleValue,
|
||||
jsi::Value const &tagValue) {
|
||||
react_native_assert(!eventTargetValue.isNull());
|
||||
if (eventTargetValue.isNull()) {
|
||||
react_native_assert(!instanceHandleValue.isNull());
|
||||
if (instanceHandleValue.isNull()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<EventTarget>(
|
||||
runtime, eventTargetValue, tagFromValue(tagValue));
|
||||
return std::make_shared<InstanceHandle>(
|
||||
runtime, instanceHandleValue, tagFromValue(tagValue));
|
||||
}
|
||||
|
||||
inline static SurfaceId surfaceIdFromValue(
|
||||
@@ -185,21 +185,6 @@ inline static folly::dynamic commandArgsFromValue(
|
||||
return jsi::dynamicFromValue(runtime, value);
|
||||
}
|
||||
|
||||
inline static jsi::Value getInstanceHandleFromShadowNode(
|
||||
ShadowNode::Shared shadowNode,
|
||||
jsi::Runtime &runtime) {
|
||||
auto eventTarget = shadowNode->getEventEmitter()->getEventTarget();
|
||||
// shadowNode is probably a RootShadowNode and they don't have
|
||||
// event targets.
|
||||
if (eventTarget == nullptr) {
|
||||
return jsi::Value::null();
|
||||
}
|
||||
eventTarget->retain(runtime);
|
||||
auto instanceHandle = eventTarget->getInstanceHandle(runtime);
|
||||
eventTarget->release(runtime);
|
||||
return instanceHandle;
|
||||
}
|
||||
|
||||
inline static jsi::Value getArrayOfInstanceHandlesFromShadowNodes(
|
||||
ShadowNode::ListOfShared const &nodes,
|
||||
jsi::Runtime &runtime) {
|
||||
@@ -209,7 +194,7 @@ inline static jsi::Value getArrayOfInstanceHandlesFromShadowNodes(
|
||||
std::vector<jsi::Value> nonNullInstanceHandles;
|
||||
nonNullInstanceHandles.reserve(nodes.size());
|
||||
for (auto const &shadowNode : nodes) {
|
||||
auto instanceHandle = getInstanceHandleFromShadowNode(shadowNode, runtime);
|
||||
auto instanceHandle = (*shadowNode).getInstanceHandle(runtime);
|
||||
if (!instanceHandle.isNull()) {
|
||||
nonNullInstanceHandles.push_back(std::move(instanceHandle));
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ static inline ShadowNode::Shared generateShadowNodeTree(
|
||||
int deviation = 3) {
|
||||
if (size <= 1) {
|
||||
auto family = componentDescriptor.createFamily(
|
||||
{generateReactTag(), SurfaceId(1), nullptr}, nullptr);
|
||||
{generateReactTag(), SurfaceId(1), nullptr});
|
||||
return componentDescriptor.createShadowNode(
|
||||
ShadowNodeFragment{generateDefaultProps(componentDescriptor)}, family);
|
||||
}
|
||||
@@ -306,7 +306,7 @@ static inline ShadowNode::Shared generateShadowNodeTree(
|
||||
}
|
||||
|
||||
auto family = componentDescriptor.createFamily(
|
||||
{generateReactTag(), SurfaceId(1), nullptr}, nullptr);
|
||||
{generateReactTag(), SurfaceId(1), nullptr});
|
||||
return componentDescriptor.createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
generateDefaultProps(componentDescriptor),
|
||||
|
||||
Reference in New Issue
Block a user