diff --git a/ReactCommon/fabric/components/image/ImageComponentDescriptor.h b/ReactCommon/fabric/components/image/ImageComponentDescriptor.h index 6ff78abc6de..f3e556c5cb4 100644 --- a/ReactCommon/fabric/components/image/ImageComponentDescriptor.h +++ b/ReactCommon/fabric/components/image/ImageComponentDescriptor.h @@ -23,8 +23,9 @@ class ImageComponentDescriptor final public: ImageComponentDescriptor( EventDispatcher::Weak eventDispatcher, - ContextContainer::Shared const &contextContainer) - : ConcreteComponentDescriptor(eventDispatcher), + ContextContainer::Shared const &contextContainer, + ComponentDescriptor::Flavor const &flavor = {}) + : ConcreteComponentDescriptor(eventDispatcher, contextContainer, flavor), imageManager_(std::make_shared(contextContainer)){}; void adopt(UnsharedShadowNode shadowNode) const override { diff --git a/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h b/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h index 7374df65a1e..2a0a4d3584e 100644 --- a/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h +++ b/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h @@ -22,8 +22,9 @@ class SliderComponentDescriptor final public: SliderComponentDescriptor( EventDispatcher::Weak eventDispatcher, - ContextContainer::Shared const &contextContainer) - : ConcreteComponentDescriptor(eventDispatcher), + ContextContainer::Shared const &contextContainer, + ComponentDescriptor::Flavor const &flavor = {}) + : ConcreteComponentDescriptor(eventDispatcher, contextContainer, flavor), imageManager_(std::make_shared(contextContainer)), measurementsManager_( SliderMeasurementsManager::shouldMeasureSlider() diff --git a/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h b/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h index b42ae6d93f1..6ac16e56303 100644 --- a/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h +++ b/ReactCommon/fabric/components/text/paragraph/ParagraphComponentDescriptor.h @@ -27,8 +27,12 @@ class ParagraphComponentDescriptor final public: ParagraphComponentDescriptor( EventDispatcher::Weak eventDispatcher, - ContextContainer::Shared const &contextContainer) - : ConcreteComponentDescriptor(eventDispatcher) { + ContextContainer::Shared const &contextContainer, + ComponentDescriptor::Flavor const &flavor = {}) + : ConcreteComponentDescriptor( + eventDispatcher, + contextContainer, + flavor) { // Every single `ParagraphShadowNode` will have a reference to // a shared `TextLayoutManager`. textLayoutManager_ = std::make_shared(contextContainer); diff --git a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.cpp b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.cpp index 37671c2981a..34e2f0b6027 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.cpp +++ b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.cpp @@ -12,8 +12,11 @@ namespace react { ComponentDescriptor::ComponentDescriptor( EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer) - : eventDispatcher_(eventDispatcher), contextContainer_(contextContainer) {} + ContextContainer::Shared const &contextContainer, + ComponentDescriptor::Flavor const &flavor) + : eventDispatcher_(eventDispatcher), + contextContainer_(contextContainer), + flavor_(flavor) {} ContextContainer::Shared const &ComponentDescriptor::getContextContainer() const { diff --git a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h index 6fd7d26a5f7..6649ac1bad1 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h +++ b/ReactCommon/fabric/core/componentdescriptor/ComponentDescriptor.h @@ -33,9 +33,21 @@ class ComponentDescriptor { using Shared = std::shared_ptr; using Unique = std::unique_ptr; + /* + * `Flavor` is a special concept designed to allow registering instances of + * the exact same `ComponentDescriptor` class with different `ComponentName` + * and `ComponentHandle` (the particular custom implementation might use + * stored `flavor` to return different values from those virtual methods). + * Since it's a very niche requirement (e.g. we plan to use it for + * an interoperability layer with Paper), we are thinking about removing this + * feature completely after it's no longer needed. + */ + using Flavor = std::shared_ptr; + ComponentDescriptor( EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer); + ContextContainer::Shared const &contextContainer, + ComponentDescriptor::Flavor const &flavor); virtual ~ComponentDescriptor() = default; @@ -114,6 +126,7 @@ class ComponentDescriptor { EventDispatcher::Weak eventDispatcher_; ContextContainer::Shared contextContainer_; RawPropsParser rawPropsParser_{}; + Flavor flavor_; }; } // namespace react diff --git a/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h b/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h index e5a3912a2f6..7d3999b6df8 100644 --- a/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h +++ b/ReactCommon/fabric/core/componentdescriptor/ConcreteComponentDescriptor.h @@ -47,8 +47,9 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { ConcreteComponentDescriptor( EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer = {}) - : ComponentDescriptor(eventDispatcher, contextContainer) { + ContextContainer::Shared const &contextContainer = {}, + ComponentDescriptor::Flavor const &flavor = {}) + : ComponentDescriptor(eventDispatcher, contextContainer, flavor) { rawPropsParser_.prepare(); } diff --git a/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h b/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h index 54c697c5013..1f3df8f4b0b 100644 --- a/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h +++ b/ReactCommon/fabric/uimanager/ComponentDescriptorProvider.h @@ -22,6 +22,7 @@ class ComponentDescriptorParameters { public: EventDispatcher::Weak eventDispatcher; ContextContainer::Shared contextContainer; + ComponentDescriptor::Flavor flavor; }; /* @@ -30,36 +31,40 @@ class ComponentDescriptorParameters { * abstract type and ownership of the newly created object. */ using ComponentDescriptorConstructor = ComponentDescriptor::Unique( - EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer); + ComponentDescriptorParameters const ¶meters); /* * 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. + * + * Note: The actual values of `handle` and `name` for some components depend on + * `flavor`. The provider is valid if instantiated by `constructor` object with + * given `flavor` exposes the same values of `handle` and `name`. */ class ComponentDescriptorProvider final { public: ComponentHandle handle; ComponentName name; + ComponentDescriptor::Flavor flavor; ComponentDescriptorConstructor *constructor; }; /* - * Creates a `ComponentDescriptorConstructor` for given `ComponentDescriptor` - * class. + * Creates a `ComponentDescriptor` for given `ComponentDescriptorParameters`. */ template ComponentDescriptor::Unique concreteComponentDescriptorConstructor( - EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer) { + ComponentDescriptorParameters const ¶meters) { static_assert( std::is_base_of::value, "ComponentDescriptorT must be a descendant of ComponentDescriptor"); return std::make_unique( - eventDispatcher, contextContainer); + parameters.eventDispatcher, + parameters.contextContainer, + parameters.flavor); } /* @@ -74,7 +79,8 @@ ComponentDescriptorProvider concreteComponentDescriptorProvider() { return {ComponentDescriptorT::ConcreteShadowNode::Handle(), ComponentDescriptorT::ConcreteShadowNode::Name(), - &concreteComponentDescriptorConstructor}; + &concreteComponentDescriptorConstructor, + nullptr}; } } // namespace react diff --git a/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp b/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp index 63e23428619..2c95fc8152a 100644 --- a/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp +++ b/ReactCommon/fabric/uimanager/ComponentDescriptorRegistry.cpp @@ -20,7 +20,9 @@ void ComponentDescriptorRegistry::add( std::unique_lock lock(mutex_); auto componentDescriptor = componentDescriptorProvider.constructor( - parameters_.eventDispatcher, parameters_.contextContainer); + {parameters_.eventDispatcher, + parameters_.contextContainer, + componentDescriptorProvider.flavor}); assert( componentDescriptor->getComponentHandle() == componentDescriptorProvider.handle);