mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fabric: Introducing ComponentDescriptor::Flavor
Summary: Currently, the same ComponentDescriptor class cannot be registered as a responder for components with different names. However, we have marginal cases where we really need it. The examples are `UnimplementedView` or possible universal interop with the classic RN or any other UI framework. This change adds a special optional argument to ComponentDescript constructor that allows implementing this functionality. Reviewed By: fkgozali Differential Revision: D17211915 fbshipit-source-id: 18f59e09fe06b875a8e8975b7b2ab423489238bb
This commit is contained in:
committed by
Facebook Github Bot
parent
df229590b2
commit
c5cc27f1e9
@@ -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<ImageManager>(contextContainer)){};
|
||||
|
||||
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||
|
||||
@@ -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<ImageManager>(contextContainer)),
|
||||
measurementsManager_(
|
||||
SliderMeasurementsManager::shouldMeasureSlider()
|
||||
|
||||
@@ -27,8 +27,12 @@ class ParagraphComponentDescriptor final
|
||||
public:
|
||||
ParagraphComponentDescriptor(
|
||||
EventDispatcher::Weak eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer)
|
||||
: ConcreteComponentDescriptor<ParagraphShadowNode>(eventDispatcher) {
|
||||
ContextContainer::Shared const &contextContainer,
|
||||
ComponentDescriptor::Flavor const &flavor = {})
|
||||
: ConcreteComponentDescriptor<ParagraphShadowNode>(
|
||||
eventDispatcher,
|
||||
contextContainer,
|
||||
flavor) {
|
||||
// Every single `ParagraphShadowNode` will have a reference to
|
||||
// a shared `TextLayoutManager`.
|
||||
textLayoutManager_ = std::make_shared<TextLayoutManager>(contextContainer);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -33,9 +33,21 @@ class ComponentDescriptor {
|
||||
using Shared = std::shared_ptr<ComponentDescriptor const>;
|
||||
using Unique = std::unique_ptr<ComponentDescriptor const>;
|
||||
|
||||
/*
|
||||
* `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<void const>;
|
||||
|
||||
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
|
||||
|
||||
@@ -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<ConcreteProps>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <typename ComponentDescriptorT>
|
||||
ComponentDescriptor::Unique concreteComponentDescriptorConstructor(
|
||||
EventDispatcher::Weak const &eventDispatcher,
|
||||
ContextContainer::Shared const &contextContainer) {
|
||||
ComponentDescriptorParameters const ¶meters) {
|
||||
static_assert(
|
||||
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
|
||||
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
|
||||
|
||||
return std::make_unique<ComponentDescriptorT const>(
|
||||
eventDispatcher, contextContainer);
|
||||
parameters.eventDispatcher,
|
||||
parameters.contextContainer,
|
||||
parameters.flavor);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -74,7 +79,8 @@ ComponentDescriptorProvider concreteComponentDescriptorProvider() {
|
||||
|
||||
return {ComponentDescriptorT::ConcreteShadowNode::Handle(),
|
||||
ComponentDescriptorT::ConcreteShadowNode::Name(),
|
||||
&concreteComponentDescriptorConstructor<ComponentDescriptorT>};
|
||||
&concreteComponentDescriptorConstructor<ComponentDescriptorT>,
|
||||
nullptr};
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -20,7 +20,9 @@ void ComponentDescriptorRegistry::add(
|
||||
std::unique_lock<better::shared_mutex> lock(mutex_);
|
||||
|
||||
auto componentDescriptor = componentDescriptorProvider.constructor(
|
||||
parameters_.eventDispatcher, parameters_.contextContainer);
|
||||
{parameters_.eventDispatcher,
|
||||
parameters_.contextContainer,
|
||||
componentDescriptorProvider.flavor});
|
||||
assert(
|
||||
componentDescriptor->getComponentHandle() ==
|
||||
componentDescriptorProvider.handle);
|
||||
|
||||
Reference in New Issue
Block a user