mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Initialise ShadowNodeFamily before ShadowNode is created
Summary: Changelog: [internal] 1. Use `ShadowNode::Shared` instead of `SharedShadowNode`. 2. Initialise `ShadowNodeFamily` before `ShadowNode`. Why? This is a step in order to merge `StateCoordinator` into `ShadowNodeFamily` and use it as target for state updates. Reviewed By: shergin Differential Revision: D19471399 fbshipit-source-id: 2f67901c901349d238c711f9eeaadb19fe7c1110
This commit is contained in:
committed by
Facebook Github Bot
parent
01805636b9
commit
7f79b46bad
@@ -84,6 +84,7 @@ fb_xplat_cxx_test(
|
||||
platforms = (ANDROID, APPLE, CXX),
|
||||
deps = [
|
||||
"fbsource//xplat/folly:molly",
|
||||
"fbsource//xplat/js/react-native-github/ReactCommon/fabric/element:element",
|
||||
"fbsource//xplat/third-party/gmock:gtest",
|
||||
react_native_xplat_target("fabric/components/view:view"),
|
||||
":core",
|
||||
|
||||
@@ -75,9 +75,9 @@ class ComponentDescriptor {
|
||||
/*
|
||||
* Creates a new `ShadowNode` of a particular component type.
|
||||
*/
|
||||
virtual SharedShadowNode createShadowNode(
|
||||
virtual ShadowNode::Shared createShadowNode(
|
||||
const ShadowNodeFragment &fragment,
|
||||
ShadowNodeFamilyFragment const &familyFragment) const = 0;
|
||||
ShadowNodeFamily::Shared const &family) const = 0;
|
||||
|
||||
/*
|
||||
* Clones a `ShadowNode` with optionally new `props` and/or `children`.
|
||||
|
||||
@@ -61,14 +61,10 @@ class ConcreteComponentDescriptor : public ComponentDescriptor {
|
||||
return ShadowNodeT::BaseTraits();
|
||||
}
|
||||
|
||||
SharedShadowNode createShadowNode(
|
||||
ShadowNode::Shared createShadowNode(
|
||||
const ShadowNodeFragment &fragment,
|
||||
ShadowNodeFamilyFragment const &familyFragment) const override {
|
||||
ShadowNodeFamily::Shared const &family) const override {
|
||||
assert(std::dynamic_pointer_cast<const ConcreteProps>(fragment.props));
|
||||
assert(std::dynamic_pointer_cast<const ConcreteEventEmitter>(
|
||||
familyFragment.eventEmitter));
|
||||
|
||||
auto family = std::make_shared<ShadowNodeFamily>(familyFragment, *this);
|
||||
|
||||
auto shadowNode =
|
||||
std::make_shared<ShadowNodeT>(fragment, family, getTraits());
|
||||
|
||||
@@ -39,6 +39,10 @@ ComponentHandle ShadowNodeFamily::getComponentHandle() const {
|
||||
return componentHandle_;
|
||||
}
|
||||
|
||||
SurfaceId ShadowNodeFamily::getSurfaceId() const {
|
||||
return surfaceId_;
|
||||
}
|
||||
|
||||
ComponentName ShadowNodeFamily::getComponentName() const {
|
||||
return componentName_;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ class ShadowNodeFamily {
|
||||
*/
|
||||
AncestorList getAncestors(ShadowNode const &ancestorShadowNode) const;
|
||||
|
||||
SurfaceId getSurfaceId() const;
|
||||
|
||||
private:
|
||||
friend ShadowNode;
|
||||
|
||||
|
||||
@@ -23,16 +23,15 @@ TEST(ComponentDescriptorTest, createShadowNode) {
|
||||
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
SharedProps props = descriptor->cloneProps(nullptr, raw);
|
||||
auto family = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{9, 1, descriptor->createEventEmitter(0, 9)},
|
||||
*descriptor);
|
||||
|
||||
SharedShadowNode node = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ descriptor->createEventEmitter(0, 9),
|
||||
});
|
||||
family);
|
||||
|
||||
EXPECT_EQ(node->getComponentHandle(), TestShadowNode::Handle());
|
||||
EXPECT_STREQ(node->getComponentName(), TestShadowNode::Name());
|
||||
@@ -50,15 +49,14 @@ TEST(ComponentDescriptorTest, cloneShadowNode) {
|
||||
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
SharedProps props = descriptor->cloneProps(nullptr, raw);
|
||||
auto family = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{9, 1, descriptor->createEventEmitter(0, 9)},
|
||||
*descriptor);
|
||||
SharedShadowNode node = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 9,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ descriptor->createEventEmitter(0, 9),
|
||||
});
|
||||
family);
|
||||
SharedShadowNode cloned = descriptor->cloneShadowNode(*node, {});
|
||||
|
||||
EXPECT_STREQ(cloned->getComponentName(), "Test");
|
||||
@@ -75,34 +73,30 @@ TEST(ComponentDescriptorTest, appendChild) {
|
||||
|
||||
const auto &raw = RawProps(folly::dynamic::object("nativeID", "abc"));
|
||||
SharedProps props = descriptor->cloneProps(nullptr, raw);
|
||||
|
||||
auto family1 = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{1, 1, descriptor->createEventEmitter(0, 9)},
|
||||
*descriptor);
|
||||
SharedShadowNode node1 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 1,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ descriptor->createEventEmitter(0, 9),
|
||||
});
|
||||
family1);
|
||||
auto family2 = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{2, 1, descriptor->createEventEmitter(0, 2)},
|
||||
*descriptor);
|
||||
SharedShadowNode node2 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 2,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ descriptor->createEventEmitter(0, 9),
|
||||
});
|
||||
family2);
|
||||
auto family3 = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{3, 1, descriptor->createEventEmitter(0, 3)},
|
||||
*descriptor);
|
||||
SharedShadowNode node3 = descriptor->createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 3,
|
||||
/* .surfaceId = */ 1,
|
||||
/* .eventEmitter = */ descriptor->createEventEmitter(0, 9),
|
||||
});
|
||||
family3);
|
||||
|
||||
descriptor->appendChild(node1, node2);
|
||||
descriptor->appendChild(node1, node3);
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
#include <exception>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "TestComponent.h"
|
||||
|
||||
#include <react/components/view/ViewComponentDescriptor.h>
|
||||
#include <react/element/ComponentBuilder.h>
|
||||
#include <react/element/Element.h>
|
||||
#include <react/uimanager/ComponentDescriptorProviderRegistry.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@@ -21,84 +25,55 @@ TEST(ShadowNodeFamilyTest, sealObjectCorrectly) {
|
||||
* </AA>
|
||||
* </A>
|
||||
*/
|
||||
SurfaceId surfaceId = 1;
|
||||
auto eventDispatcher = std::shared_ptr<EventDispatcher const>();
|
||||
auto componentDescriptor = TestComponentDescriptor({eventDispatcher});
|
||||
auto props = std::make_shared<const TestProps>();
|
||||
ComponentDescriptorProviderRegistry componentDescriptorProviderRegistry{};
|
||||
auto eventDispatcher = EventDispatcher::Shared{};
|
||||
auto componentDescriptorRegistry =
|
||||
componentDescriptorProviderRegistry.createComponentDescriptorRegistry(
|
||||
ComponentDescriptorParameters{eventDispatcher, nullptr, nullptr});
|
||||
|
||||
auto familyAAA = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 12,
|
||||
/* .surfaceId = */ surfaceId,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
componentDescriptor);
|
||||
componentDescriptorProviderRegistry.add(
|
||||
concreteComponentDescriptorProvider<ViewComponentDescriptor>());
|
||||
|
||||
auto nodeAAA = std::make_shared<TestShadowNode>(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
/* .children = */ ShadowNode::emptySharedShadowNodeSharedList(),
|
||||
},
|
||||
familyAAA,
|
||||
ShadowNodeTraits{});
|
||||
auto builder = ComponentBuilder{componentDescriptorRegistry};
|
||||
|
||||
auto nodeAAChildren =
|
||||
std::make_shared<SharedShadowNodeList>(SharedShadowNodeList{nodeAAA});
|
||||
auto familyAA = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 11,
|
||||
/* .surfaceId = */ surfaceId,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
componentDescriptor);
|
||||
auto nodeAA = std::make_shared<TestShadowNode>(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
/* .children = */ nodeAAChildren,
|
||||
},
|
||||
familyAA,
|
||||
ShadowNodeTraits{});
|
||||
auto shadowNodeAAA = std::shared_ptr<ViewShadowNode const>{};
|
||||
auto shadowNodeAA = std::shared_ptr<ViewShadowNode const>{};
|
||||
|
||||
auto nodeAChildren =
|
||||
std::make_shared<SharedShadowNodeList>(SharedShadowNodeList{nodeAA});
|
||||
// clang-format off
|
||||
auto elementA =
|
||||
Element<ViewShadowNode>()
|
||||
.tag(1)
|
||||
.finalize([](ViewShadowNode &shadowNode){
|
||||
shadowNode.sealRecursive();
|
||||
})
|
||||
.children({
|
||||
Element<ViewShadowNode>()
|
||||
.tag(2)
|
||||
.reference(shadowNodeAA)
|
||||
.children({
|
||||
Element<ViewShadowNode>()
|
||||
.reference(shadowNodeAAA)
|
||||
.tag(3)
|
||||
})
|
||||
});
|
||||
auto elementB =
|
||||
Element<ViewShadowNode>()
|
||||
.tag(1)
|
||||
.finalize([](ViewShadowNode &shadowNode){
|
||||
shadowNode.sealRecursive();
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
auto familyA = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 17,
|
||||
/* .surfaceId = */ surfaceId,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
componentDescriptor);
|
||||
auto nodeA = std::make_shared<TestShadowNode>(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
/* .children = */ nodeAChildren,
|
||||
},
|
||||
familyA,
|
||||
ShadowNodeTraits{});
|
||||
|
||||
auto familyZ = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
/* .tag = */ 18,
|
||||
/* .surfaceId = */ surfaceId,
|
||||
/* .eventEmitter = */ nullptr,
|
||||
},
|
||||
componentDescriptor);
|
||||
auto nodeZ = std::make_shared<TestShadowNode>(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
/* .children = */ ShadowNode::emptySharedShadowNodeSharedList(),
|
||||
},
|
||||
familyZ,
|
||||
ShadowNodeTraits{});
|
||||
auto shadowNodeA = builder.build(elementA);
|
||||
auto shadowNodeB = builder.build(elementB);
|
||||
|
||||
// Negative case:
|
||||
auto ancestors1 = nodeZ->getFamily().getAncestors(*nodeA);
|
||||
auto ancestors1 = shadowNodeB->getFamily().getAncestors(*shadowNodeA);
|
||||
EXPECT_EQ(ancestors1.size(), 0);
|
||||
|
||||
// Positive case:
|
||||
auto ancestors2 = nodeAAA->getFamily().getAncestors(*nodeA);
|
||||
auto ancestors2 = shadowNodeAAA->getFamily().getAncestors(*shadowNodeA);
|
||||
EXPECT_EQ(ancestors2.size(), 2);
|
||||
EXPECT_EQ(&ancestors2[0].first.get(), nodeA.get());
|
||||
EXPECT_EQ(&ancestors2[1].first.get(), nodeAA.get());
|
||||
EXPECT_EQ(&ancestors2[0].first.get(), shadowNodeA.get());
|
||||
EXPECT_EQ(&ancestors2[1].first.get(), shadowNodeAA.get());
|
||||
}
|
||||
|
||||
@@ -28,13 +28,17 @@ ShadowNode::Shared ComponentBuilder::build(
|
||||
auto eventEmitter =
|
||||
componentDescriptor.createEventEmitter(nullptr, elementFragment.tag);
|
||||
|
||||
auto family = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
elementFragment.tag, elementFragment.surfaceId, eventEmitter},
|
||||
componentDescriptor);
|
||||
|
||||
auto shadowNode = componentDescriptor.createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
elementFragment.props,
|
||||
std::make_shared<ShadowNode::ListOfShared const>(children),
|
||||
elementFragment.state},
|
||||
ShadowNodeFamilyFragment{
|
||||
elementFragment.tag, elementFragment.surfaceId, eventEmitter});
|
||||
family);
|
||||
|
||||
if (elementFragment.referenceCallback) {
|
||||
elementFragment.referenceCallback(shadowNode);
|
||||
|
||||
@@ -102,12 +102,15 @@ ShadowTree::ShadowTree(
|
||||
const auto props = std::make_shared<const RootProps>(
|
||||
*RootShadowNode::defaultSharedProps(), layoutConstraints, layoutContext);
|
||||
|
||||
auto family = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{surfaceId, surfaceId, noopEventEmitter},
|
||||
rootComponentDescriptor);
|
||||
rootShadowNode_ = std::static_pointer_cast<const RootShadowNode>(
|
||||
rootComponentDescriptor.createShadowNode(
|
||||
ShadowNodeFragment{
|
||||
/* .props = */ props,
|
||||
},
|
||||
{surfaceId, surfaceId, noopEventEmitter}));
|
||||
family));
|
||||
|
||||
mountingCoordinator_ = std::make_shared<MountingCoordinator const>(
|
||||
ShadowTreeRevision{rootShadowNode_, 0, {}});
|
||||
|
||||
@@ -172,8 +172,12 @@ SharedShadowNode ComponentDescriptorRegistry::createNode(
|
||||
auto unifiedComponentName = componentNameByReactViewName(viewName);
|
||||
auto const &componentDescriptor = this->at(unifiedComponentName);
|
||||
|
||||
auto const eventEmitter =
|
||||
componentDescriptor.createEventEmitter(std::move(eventTarget), tag);
|
||||
auto family = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
tag,
|
||||
surfaceId,
|
||||
componentDescriptor.createEventEmitter(std::move(eventTarget), tag)},
|
||||
componentDescriptor);
|
||||
auto const props =
|
||||
componentDescriptor.cloneProps(nullptr, RawProps(propsDynamic));
|
||||
auto const state = componentDescriptor.createInitialState(
|
||||
@@ -185,7 +189,7 @@ SharedShadowNode ComponentDescriptorRegistry::createNode(
|
||||
/* .children = */ ShadowNodeFragment::childrenPlaceholder(),
|
||||
/* .state = */ state,
|
||||
},
|
||||
{tag, surfaceId, eventEmitter});
|
||||
family);
|
||||
}
|
||||
|
||||
void ComponentDescriptorRegistry::setFallbackComponentDescriptor(
|
||||
|
||||
@@ -33,8 +33,12 @@ SharedShadowNode UIManager::createNode(
|
||||
auto fallbackDescriptor =
|
||||
componentDescriptorRegistry_->getFallbackComponentDescriptor();
|
||||
|
||||
auto const eventEmitter =
|
||||
componentDescriptor.createEventEmitter(std::move(eventTarget), tag);
|
||||
auto family = std::make_shared<ShadowNodeFamily>(
|
||||
ShadowNodeFamilyFragment{
|
||||
tag,
|
||||
surfaceId,
|
||||
componentDescriptor.createEventEmitter(std::move(eventTarget), tag)},
|
||||
componentDescriptor);
|
||||
auto const props = componentDescriptor.cloneProps(nullptr, rawProps);
|
||||
auto const state = componentDescriptor.createInitialState(
|
||||
ShadowNodeFragment{props}, surfaceId);
|
||||
@@ -51,7 +55,7 @@ SharedShadowNode UIManager::createNode(
|
||||
/* .children = */ ShadowNodeFragment::childrenPlaceholder(),
|
||||
/* .state = */ state,
|
||||
},
|
||||
ShadowNodeFamilyFragment{tag, surfaceId, eventEmitter});
|
||||
family);
|
||||
|
||||
// state->commit(x) associates a ShadowNode with the State object.
|
||||
// state->commit(x) must be called before calling updateState; updateState
|
||||
|
||||
Reference in New Issue
Block a user