mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Fabric: Introducing ComponentDescriptorProvider
Summary: ComponentDescriptorProvider represents unified way to create a particular descriptor. Now all ComponentViews (which support RCTComponentViewProtocol) expose a `ComponentDescriptorProvider` which will allow creating and registering ComponentDescriptor instances for all visual components automatically as a part of ComponentView registration process. Don't panic, everything is still being as explicit as it always was, no magic involved; we just will have only one registration step instead of two parallel. That also opens a way to register components on the fly. Reviewed By: JoshuaGross Differential Revision: D14963488 fbshipit-source-id: 9e9d9166fabaf7b30b35b8647faa6e3a19cd2435
This commit is contained in:
committed by
Facebook Github Bot
parent
0735873fbc
commit
00eab3d6fb
@@ -7,9 +7,9 @@
|
||||
|
||||
#import "RCTActivityIndicatorViewComponentView.h"
|
||||
|
||||
#import <react/components/rncore/ComponentDescriptors.h>
|
||||
#import <react/components/rncore/EventEmitters.h>
|
||||
#import <react/components/rncore/Props.h>
|
||||
#import <react/components/rncore/ShadowNodes.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@@ -29,9 +29,9 @@ static UIActivityIndicatorViewStyle convertActivityIndicatorViewStyle(const Acti
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return ActivityIndicatorViewShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<ActivityIndicatorViewComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#import "RCTImageComponentView.h"
|
||||
|
||||
#import <React/RCTImageResponseObserverProxy.h>
|
||||
#import <react/components/image/ImageComponentDescriptor.h>
|
||||
#import <react/components/image/ImageEventEmitter.h>
|
||||
#import <react/components/image/ImageLocalData.h>
|
||||
#import <react/components/image/ImageProps.h>
|
||||
#import <react/components/image/ImageShadowNode.h>
|
||||
#import <react/imagemanager/ImageRequest.h>
|
||||
#import <react/imagemanager/RCTImagePrimitivesConversions.h>
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return ImageShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<ImageComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#import "RCTRootComponentView.h"
|
||||
|
||||
#import <react/components/root/RootComponentDescriptor.h>
|
||||
#import <react/components/root/RootProps.h>
|
||||
#import <react/components/root/RootShadowNode.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@@ -24,9 +24,11 @@ using namespace facebook::react;
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return RootShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<RootComponentDescriptor>();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#import "RCTScrollViewComponentView.h"
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <react/components/scrollview/ScrollViewComponentDescriptor.h>
|
||||
#import <react/components/scrollview/ScrollViewEventEmitter.h>
|
||||
#import <react/components/scrollview/ScrollViewLocalData.h>
|
||||
#import <react/components/scrollview/ScrollViewProps.h>
|
||||
#import <react/components/scrollview/ScrollViewShadowNode.h>
|
||||
#import <react/graphics/Geometry.h>
|
||||
|
||||
#import "RCTConversions.h"
|
||||
@@ -51,9 +51,9 @@ using namespace facebook::react;
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return ScrollViewShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<ScrollViewComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#import <React/RCTImageResponseObserverProxy.h>
|
||||
#import <react/components/rncore/EventEmitters.h>
|
||||
#import <react/components/rncore/Props.h>
|
||||
#import <react/components/slider/SliderComponentDescriptor.h>
|
||||
#import <react/components/slider/SliderLocalData.h>
|
||||
#import <react/components/slider/SliderShadowNode.h>
|
||||
|
||||
#import "MainQueueExecutor.h"
|
||||
|
||||
@@ -104,9 +104,9 @@ using namespace facebook::react;
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return SliderShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<SliderComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#import "RCTSwitchComponentView.h"
|
||||
|
||||
#import <react/components/rncore/ComponentDescriptors.h>
|
||||
#import <react/components/rncore/EventEmitters.h>
|
||||
#import <react/components/rncore/Props.h>
|
||||
#import <react/components/rncore/ShadowNodes.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@@ -38,9 +38,9 @@ using namespace facebook::react;
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return SwitchShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<SwitchComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
|
||||
#import "RCTParagraphComponentView.h"
|
||||
|
||||
#import <react/components/text/ParagraphComponentDescriptor.h>
|
||||
#import <react/components/text/ParagraphLocalData.h>
|
||||
#import <react/components/text/ParagraphProps.h>
|
||||
#import <react/components/text/ParagraphShadowNode.h>
|
||||
#import <react/components/text/RawTextComponentDescriptor.h>
|
||||
#import <react/components/text/TextComponentDescriptor.h>
|
||||
#import <react/core/LocalData.h>
|
||||
#import <react/graphics/Geometry.h>
|
||||
#import <react/textlayoutmanager/RCTTextLayoutManager.h>
|
||||
@@ -40,9 +42,15 @@ using namespace facebook::react;
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return ParagraphShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<ParagraphComponentDescriptor>();
|
||||
}
|
||||
|
||||
+ (std::vector<facebook::react::ComponentDescriptorProvider>)supplementalComponentDescriptorProviders
|
||||
{
|
||||
return {concreteComponentDescriptorProvider<RawTextComponentDescriptor>(),
|
||||
concreteComponentDescriptorProvider<TextComponentDescriptor>()};
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#import "RCTUnimplementedNativeComponentView.h"
|
||||
|
||||
#import <react/components/rncore/ComponentDescriptors.h>
|
||||
#import <react/components/rncore/EventEmitters.h>
|
||||
#import <react/components/rncore/Props.h>
|
||||
#import <react/components/rncore/ShadowNodes.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
@@ -17,13 +17,6 @@ using namespace facebook::react;
|
||||
UILabel *_label;
|
||||
}
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
{
|
||||
return UnimplementedNativeViewShadowNode::Handle();
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
@@ -45,6 +38,13 @@ using namespace facebook::react;
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
return concreteComponentDescriptorProvider<UnimplementedNativeViewComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
{
|
||||
const auto &oldViewProps = *std::static_pointer_cast<const UnimplementedNativeViewProps>(oldProps ?: _props);
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTBorderDrawing.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <react/components/view/ViewComponentDescriptor.h>
|
||||
#import <react/components/view/ViewEventEmitter.h>
|
||||
#import <react/components/view/ViewProps.h>
|
||||
#import <react/components/view/ViewShadowNode.h>
|
||||
|
||||
#import "RCTConversions.h"
|
||||
|
||||
@@ -85,13 +85,13 @@ using namespace facebook::react;
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
+ (ComponentHandle)componentHandle
|
||||
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
||||
{
|
||||
RCTAssert(
|
||||
self == [RCTViewComponentView class],
|
||||
@"`+[RCTComponentViewProtocol componentHandle]` must be implemented for all subclasses (and `%@` particularly).",
|
||||
@"`+[RCTComponentViewProtocol componentDescriptorProvider]` must be implemented for all subclasses (and `%@` particularly).",
|
||||
NSStringFromClass([self class]));
|
||||
return ViewShadowNode::Handle();
|
||||
return concreteComponentDescriptorProvider<ViewComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
|
||||
|
||||
@@ -49,7 +49,7 @@ using namespace facebook::react;
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
|
||||
ComponentHandle componentHandle = [componentViewClass componentHandle];
|
||||
auto componentHandle = [componentViewClass componentDescriptorProvider].handle;
|
||||
_registry[componentHandle] = componentViewClass;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import <react/core/LocalData.h>
|
||||
#import <react/core/Props.h>
|
||||
#import <react/core/State.h>
|
||||
#import <react/uimanager/ComponentDescriptorProvider.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -40,10 +41,16 @@ typedef NS_OPTIONS(NSInteger, RNComponentViewUpdateMask) {
|
||||
@protocol RCTComponentViewProtocol <NSObject>
|
||||
|
||||
/*
|
||||
* Returns ComponentHandle of ComponentDescriptor which this ComponentView
|
||||
* Returns a `ComponentDescriptorProvider` of a particular `ComponentDescriptor` which this component view
|
||||
* represents.
|
||||
*/
|
||||
+ (facebook::react::ComponentHandle)componentHandle;
|
||||
+ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider;
|
||||
|
||||
/*
|
||||
* Returns a list of supplemental `ComponentDescriptorProvider`s (with do not have `ComponentView` counterparts) that
|
||||
* require for this component view.
|
||||
*/
|
||||
+ (std::vector<facebook::react::ComponentDescriptorProvider>)supplementalComponentDescriptorProviders;
|
||||
|
||||
/*
|
||||
* Called for mounting (attaching) a child component view inside `self`
|
||||
|
||||
@@ -106,9 +106,9 @@ const NSInteger RCTComponentViewRegistryRecyclePoolMaxSize = 1024;
|
||||
// This data is based on empirical evidence which should represent the reality pretty well.
|
||||
// Regular `<View>` has magnitude equals to `1` by definition.
|
||||
std::vector<std::pair<ComponentHandle, float>> componentMagnitudes = {
|
||||
{[RCTViewComponentView componentHandle], 1},
|
||||
{[RCTImageComponentView componentHandle], 0.3},
|
||||
{[RCTParagraphComponentView componentHandle], 0.3},
|
||||
{[RCTViewComponentView componentDescriptorProvider].handle, 1},
|
||||
{[RCTImageComponentView componentDescriptorProvider].handle, 0.3},
|
||||
{[RCTParagraphComponentView componentDescriptorProvider].handle, 0.3},
|
||||
};
|
||||
|
||||
// `complexity` represents the complexity of a typical surface in a number of `<View>` components (with Flattening
|
||||
|
||||
@@ -16,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface UIView (ComponentViewProtocol)
|
||||
|
||||
+ (std::vector<facebook::react::ComponentDescriptorProvider>)supplementalComponentDescriptorProviders;
|
||||
|
||||
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
|
||||
|
||||
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
|
||||
|
||||
@@ -17,6 +17,11 @@ using namespace facebook::react;
|
||||
|
||||
@implementation UIView (ComponentViewProtocol)
|
||||
|
||||
+ (std::vector<facebook::react::ComponentDescriptorProvider>)supplementalComponentDescriptorProviders
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
||||
{
|
||||
[self insertSubview:childComponentView atIndex:index];
|
||||
|
||||
@@ -175,7 +175,7 @@ using namespace facebook::react;
|
||||
if (componentView == nil) {
|
||||
return NO; // This view probably isn't managed by Fabric
|
||||
}
|
||||
ComponentHandle handle = [[componentView class] componentHandle];
|
||||
ComponentHandle handle = [[componentView class] componentDescriptorProvider].handle;
|
||||
const facebook::react::ComponentDescriptor &componentDescriptor = [self._scheduler getComponentDescriptor:handle];
|
||||
[self->_mountingManager synchronouslyUpdateViewOnUIThread:tag
|
||||
changedProps:props
|
||||
|
||||
@@ -30,6 +30,7 @@ using SharedComponentDescriptor = std::shared_ptr<ComponentDescriptor>;
|
||||
class ComponentDescriptor {
|
||||
public:
|
||||
using Shared = std::shared_ptr<ComponentDescriptor const>;
|
||||
using Unique = std::unique_ptr<ComponentDescriptor const>;
|
||||
|
||||
ComponentDescriptor(
|
||||
EventDispatcher::Shared const &eventDispatcher,
|
||||
|
||||
69
ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h
Normal file
69
ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 <react/core/ComponentDescriptor.h>
|
||||
#include <react/core/EventDispatcher.h>
|
||||
#include <react/utils/ContextContainer.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Callable signature that represents the signature of `ComponentDescriptor`
|
||||
* constructor. The callable returns a unique pointer conveniently represents an
|
||||
* abstract type and ownership of the newly created object.
|
||||
*/
|
||||
using ComponentDescriptorConstructor = ComponentDescriptor::Unique(
|
||||
EventDispatcher::Shared const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer);
|
||||
|
||||
/*
|
||||
* Represents a unified way to construct an instance of a particular stored
|
||||
* `ComponentDescriptor` class. C++ does not allow to create pointers to
|
||||
* constructors, so we have to have such data structure to manipulate a
|
||||
* collection of classes.
|
||||
*/
|
||||
class ComponentDescriptorProvider final {
|
||||
public:
|
||||
ComponentHandle handle;
|
||||
ComponentDescriptorConstructor *constructor;
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a `ComponentDescriptorConstructor` for given `ComponentDescriptor`
|
||||
* class.
|
||||
*/
|
||||
template <typename ComponentDescriptorT>
|
||||
ComponentDescriptor::Unique concreteComponentDescriptorConstructor(
|
||||
EventDispatcher::Shared const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer) {
|
||||
static_assert(
|
||||
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
|
||||
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
|
||||
|
||||
return std::make_unique<ComponentDescriptorT const>(
|
||||
eventDispatcher, contextContainer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a `ComponentDescriptorProvider` for given `ComponentDescriptor`
|
||||
* class.
|
||||
*/
|
||||
template <typename ComponentDescriptorT>
|
||||
ComponentDescriptorProvider concreteComponentDescriptorProvider() {
|
||||
static_assert(
|
||||
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
|
||||
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
|
||||
|
||||
return {ComponentDescriptorT::ConcreteShadowNode::Handle(),
|
||||
&concreteComponentDescriptorConstructor<ComponentDescriptorT>};
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -72,6 +72,11 @@ Scheduler::Scheduler(
|
||||
runtimeExecutor_([=](jsi::Runtime &runtime) {
|
||||
UIManagerBinding::install(runtime, uiManagerBinding_);
|
||||
});
|
||||
|
||||
contextContainer->registerInstance(
|
||||
std::weak_ptr<ComponentDescriptorRegistry const>(
|
||||
componentDescriptorRegistry_),
|
||||
"ComponentDescriptorRegistry_DO_NOT_USE_PRETTY_PLEASE");
|
||||
}
|
||||
|
||||
Scheduler::~Scheduler() {
|
||||
|
||||
Reference in New Issue
Block a user