diff --git a/React/Fabric/Mounting/ComponentViews/ActivityIndicator/RCTActivityIndicatorViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ActivityIndicator/RCTActivityIndicatorViewComponentView.mm index 95f21877c..9f103e93c 100644 --- a/React/Fabric/Mounting/ComponentViews/ActivityIndicator/RCTActivityIndicatorViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ActivityIndicator/RCTActivityIndicatorViewComponentView.mm @@ -7,9 +7,9 @@ #import "RCTActivityIndicatorViewComponentView.h" +#import #import #import -#import 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(); } - (instancetype)initWithFrame:(CGRect)frame diff --git a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index fe77fd4a9..cb38882ce 100644 --- a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -8,10 +8,10 @@ #import "RCTImageComponentView.h" #import +#import #import #import #import -#import #import #import @@ -46,9 +46,9 @@ #pragma mark - RCTComponentViewProtocol -+ (ComponentHandle)componentHandle ++ (ComponentDescriptorProvider)componentDescriptorProvider { - return ImageShadowNode::Handle(); + return concreteComponentDescriptorProvider(); } - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps diff --git a/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm b/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm index ebfd680c2..40178a533 100644 --- a/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm @@ -7,8 +7,8 @@ #import "RCTRootComponentView.h" +#import #import -#import 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(); } @end diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index a788f2f7b..1fd734c9d 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -8,10 +8,10 @@ #import "RCTScrollViewComponentView.h" #import +#import #import #import #import -#import #import #import "RCTConversions.h" @@ -51,9 +51,9 @@ using namespace facebook::react; #pragma mark - RCTComponentViewProtocol -+ (ComponentHandle)componentHandle ++ (ComponentDescriptorProvider)componentDescriptorProvider { - return ScrollViewShadowNode::Handle(); + return concreteComponentDescriptorProvider(); } - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps diff --git a/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm b/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm index 2f6f670d8..0850789a0 100644 --- a/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Slider/RCTSliderComponentView.mm @@ -10,8 +10,8 @@ #import #import #import +#import #import -#import #import "MainQueueExecutor.h" @@ -104,9 +104,9 @@ using namespace facebook::react; #pragma mark - RCTComponentViewProtocol -+ (ComponentHandle)componentHandle ++ (ComponentDescriptorProvider)componentDescriptorProvider { - return SliderShadowNode::Handle(); + return concreteComponentDescriptorProvider(); } - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps diff --git a/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm b/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm index 49e8e49d8..2857748da 100644 --- a/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.mm @@ -7,9 +7,9 @@ #import "RCTSwitchComponentView.h" +#import #import #import -#import using namespace facebook::react; @@ -38,9 +38,9 @@ using namespace facebook::react; #pragma mark - RCTComponentViewProtocol -+ (ComponentHandle)componentHandle ++ (ComponentDescriptorProvider)componentDescriptorProvider { - return SwitchShadowNode::Handle(); + return concreteComponentDescriptorProvider(); } - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps diff --git a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm index 430039239..9a64f5c30 100644 --- a/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.mm @@ -7,9 +7,11 @@ #import "RCTParagraphComponentView.h" +#import #import #import -#import +#import +#import #import #import #import @@ -40,9 +42,15 @@ using namespace facebook::react; #pragma mark - RCTComponentViewProtocol -+ (ComponentHandle)componentHandle ++ (ComponentDescriptorProvider)componentDescriptorProvider { - return ParagraphShadowNode::Handle(); + return concreteComponentDescriptorProvider(); +} + ++ (std::vector)supplementalComponentDescriptorProviders +{ + return {concreteComponentDescriptorProvider(), + concreteComponentDescriptorProvider()}; } - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps diff --git a/React/Fabric/Mounting/ComponentViews/UnimplementedComponent/RCTUnimplementedNativeComponentView.mm b/React/Fabric/Mounting/ComponentViews/UnimplementedComponent/RCTUnimplementedNativeComponentView.mm index 2965494db..bf5fdd1e7 100644 --- a/React/Fabric/Mounting/ComponentViews/UnimplementedComponent/RCTUnimplementedNativeComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/UnimplementedComponent/RCTUnimplementedNativeComponentView.mm @@ -7,9 +7,9 @@ #import "RCTUnimplementedNativeComponentView.h" +#import #import #import -#import 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(); +} + - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps { const auto &oldViewProps = *std::static_pointer_cast(oldProps ?: _props); diff --git a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index b5f69d298..07bfcaa6d 100644 --- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -10,9 +10,9 @@ #import #import #import +#import #import #import -#import #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(); } - (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps diff --git a/React/Fabric/Mounting/RCTComponentViewFactory.mm b/React/Fabric/Mounting/RCTComponentViewFactory.mm index 215bebbb6..0f1f8c8e1 100644 --- a/React/Fabric/Mounting/RCTComponentViewFactory.mm +++ b/React/Fabric/Mounting/RCTComponentViewFactory.mm @@ -49,7 +49,7 @@ using namespace facebook::react; { RCTAssertMainQueue(); - ComponentHandle componentHandle = [componentViewClass componentHandle]; + auto componentHandle = [componentViewClass componentDescriptorProvider].handle; _registry[componentHandle] = componentViewClass; } diff --git a/React/Fabric/Mounting/RCTComponentViewProtocol.h b/React/Fabric/Mounting/RCTComponentViewProtocol.h index 4e398cb6a..e5e1c6a5c 100644 --- a/React/Fabric/Mounting/RCTComponentViewProtocol.h +++ b/React/Fabric/Mounting/RCTComponentViewProtocol.h @@ -13,6 +13,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -40,10 +41,16 @@ typedef NS_OPTIONS(NSInteger, RNComponentViewUpdateMask) { @protocol RCTComponentViewProtocol /* - * 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)supplementalComponentDescriptorProviders; /* * Called for mounting (attaching) a child component view inside `self` diff --git a/React/Fabric/Mounting/RCTComponentViewRegistry.mm b/React/Fabric/Mounting/RCTComponentViewRegistry.mm index c1e18b7be..80ed859e4 100644 --- a/React/Fabric/Mounting/RCTComponentViewRegistry.mm +++ b/React/Fabric/Mounting/RCTComponentViewRegistry.mm @@ -106,9 +106,9 @@ const NSInteger RCTComponentViewRegistryRecyclePoolMaxSize = 1024; // This data is based on empirical evidence which should represent the reality pretty well. // Regular `` has magnitude equals to `1` by definition. std::vector> 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 `` components (with Flattening diff --git a/React/Fabric/Mounting/UIView+ComponentViewProtocol.h b/React/Fabric/Mounting/UIView+ComponentViewProtocol.h index e19b04024..b0ff68685 100644 --- a/React/Fabric/Mounting/UIView+ComponentViewProtocol.h +++ b/React/Fabric/Mounting/UIView+ComponentViewProtocol.h @@ -16,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN */ @interface UIView (ComponentViewProtocol) ++ (std::vector)supplementalComponentDescriptorProviders; + - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index; - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index; diff --git a/React/Fabric/Mounting/UIView+ComponentViewProtocol.mm b/React/Fabric/Mounting/UIView+ComponentViewProtocol.mm index ecbe4e132..c5285a316 100644 --- a/React/Fabric/Mounting/UIView+ComponentViewProtocol.mm +++ b/React/Fabric/Mounting/UIView+ComponentViewProtocol.mm @@ -17,6 +17,11 @@ using namespace facebook::react; @implementation UIView (ComponentViewProtocol) ++ (std::vector)supplementalComponentDescriptorProviders +{ + return {}; +} + - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { [self insertSubview:childComponentView atIndex:index]; diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index eebbb84be..86cbcd105 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -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 diff --git a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h index 11546c284..a1640f548 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h +++ b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h @@ -30,6 +30,7 @@ using SharedComponentDescriptor = std::shared_ptr; class ComponentDescriptor { public: using Shared = std::shared_ptr; + using Unique = std::unique_ptr; ComponentDescriptor( EventDispatcher::Shared const &eventDispatcher, diff --git a/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h b/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h new file mode 100644 index 000000000..2dd7787b1 --- /dev/null +++ b/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h @@ -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 +#include +#include + +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 +ComponentDescriptor::Unique concreteComponentDescriptorConstructor( + EventDispatcher::Shared const &eventDispatcher, + ContextContainer::Shared const &contextContainer) { + static_assert( + std::is_base_of::value, + "ComponentDescriptorT must be a descendant of ComponentDescriptor"); + + return std::make_unique( + eventDispatcher, contextContainer); +} + +/* + * Creates a `ComponentDescriptorProvider` for given `ComponentDescriptor` + * class. + */ +template +ComponentDescriptorProvider concreteComponentDescriptorProvider() { + static_assert( + std::is_base_of::value, + "ComponentDescriptorT must be a descendant of ComponentDescriptor"); + + return {ComponentDescriptorT::ConcreteShadowNode::Handle(), + &concreteComponentDescriptorConstructor}; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index c12719c52..be018de2b 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -72,6 +72,11 @@ Scheduler::Scheduler( runtimeExecutor_([=](jsi::Runtime &runtime) { UIManagerBinding::install(runtime, uiManagerBinding_); }); + + contextContainer->registerInstance( + std::weak_ptr( + componentDescriptorRegistry_), + "ComponentDescriptorRegistry_DO_NOT_USE_PRETTY_PLEASE"); } Scheduler::~Scheduler() {