mirror of
https://github.com/status-im/react-native.git
synced 2025-02-02 20:53:56 +00:00
67a79010ca
Summary: @public Previously, all ConcreteShadowNode subclasses had to override `getComponentName()` function to specialize a name of the component. And often it was all that those subclasses do. Now, it's a template argument; and many ShadowNode classes can be created as oneliners via *just* specializing ConcreteShadowNode template. Unfortunately, C++ does not allow to use `std::string`s or string literals as template arguments, but it allows to use pointers. Moreover, those pointers must point to some linked data, hence, those values must be declared in .cpp (not .h) files. For simplicity, we put those constants in Props classes, (but this is not a strong requirement). Reviewed By: mdvacca Differential Revision: D8942826 fbshipit-source-id: 4fd517e2485eb8f8c20a51df9b3496941856d8a5
115 lines
3.3 KiB
C++
115 lines
3.3 KiB
C++
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
*
|
|
* 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 <fabric/core/Props.h>
|
|
#include <fabric/core/ShadowNode.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
/*
|
|
* Base templace class for all `ShadowNode`s which connects exact `ShadowNode`
|
|
* type with exact `Props` type.
|
|
* `ConcreteShadowNode` is a default implementation of `ShadowNode` interface
|
|
* with many handy features.
|
|
*/
|
|
template <
|
|
const char *concreteComponentName,
|
|
typename PropsT,
|
|
typename EventEmitterT = EventEmitter
|
|
>
|
|
class ConcreteShadowNode: public ShadowNode {
|
|
static_assert(std::is_base_of<Props, PropsT>::value, "PropsT must be a descendant of Props");
|
|
|
|
public:
|
|
using ConcreteProps = PropsT;
|
|
using SharedConcreteProps = std::shared_ptr<const PropsT>;
|
|
using ConcreteEventEmitter = EventEmitterT;
|
|
using SharedConcreteEventEmitter = std::shared_ptr<const EventEmitterT>;
|
|
using SharedConcreteShadowNode = std::shared_ptr<const ConcreteShadowNode>;
|
|
|
|
static ComponentName Name() {
|
|
return ComponentName(concreteComponentName);
|
|
}
|
|
|
|
static ComponentHandle Handle() {
|
|
return ComponentHandle(concreteComponentName);
|
|
}
|
|
|
|
static SharedConcreteProps Props(const RawProps &rawProps, const SharedProps &baseProps = nullptr) {
|
|
return std::make_shared<const PropsT>(baseProps ? *std::static_pointer_cast<const PropsT>(baseProps) : PropsT(), rawProps);
|
|
}
|
|
|
|
static SharedConcreteProps defaultSharedProps() {
|
|
static const SharedConcreteProps defaultSharedProps = std::make_shared<const PropsT>();
|
|
return defaultSharedProps;
|
|
}
|
|
|
|
ConcreteShadowNode(
|
|
const Tag &tag,
|
|
const Tag &rootTag,
|
|
const SharedConcreteProps &props,
|
|
const SharedConcreteEventEmitter &eventEmitter,
|
|
const SharedShadowNodeSharedList &children,
|
|
const ShadowNodeCloneFunction &cloneFunction
|
|
):
|
|
ShadowNode(
|
|
tag,
|
|
rootTag,
|
|
(SharedProps)props,
|
|
eventEmitter,
|
|
children,
|
|
cloneFunction
|
|
) {};
|
|
|
|
ConcreteShadowNode(
|
|
const SharedConcreteShadowNode &shadowNode,
|
|
const SharedProps &props,
|
|
const SharedEventEmitter &eventEmitter,
|
|
const SharedShadowNodeSharedList &children
|
|
):
|
|
ShadowNode(
|
|
shadowNode,
|
|
(SharedProps)props,
|
|
eventEmitter,
|
|
children
|
|
) {}
|
|
|
|
ComponentName getComponentName() const override {
|
|
return ComponentName(concreteComponentName);
|
|
}
|
|
|
|
ComponentHandle getComponentHandle() const override {
|
|
return reinterpret_cast<ComponentHandle>(concreteComponentName);
|
|
}
|
|
|
|
const SharedConcreteProps getProps() const {
|
|
assert(std::dynamic_pointer_cast<const PropsT>(props_));
|
|
return std::static_pointer_cast<const PropsT>(props_);
|
|
}
|
|
|
|
/*
|
|
* Returns subset of children that are inherited from `SpecificShadowNodeT`.
|
|
*/
|
|
template<typename SpecificShadowNodeT>
|
|
std::vector<SpecificShadowNodeT *> getChildrenSlice() const {
|
|
std::vector<SpecificShadowNodeT *> children;
|
|
for (const auto &childShadowNode : *getChildren()) {
|
|
auto specificChildShadowNode = dynamic_cast<const SpecificShadowNodeT *>(childShadowNode.get());
|
|
if (specificChildShadowNode) {
|
|
children.push_back(const_cast<SpecificShadowNodeT *>(specificChildShadowNode));
|
|
}
|
|
}
|
|
return children;
|
|
}
|
|
};
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|