2018-03-19 05:04:16 +03:00
|
|
|
/**
|
2018-09-12 01:27:47 +03:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2018-03-19 05:04:16 +03:00
|
|
|
*
|
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2018-04-27 03:51:27 +03:00
|
|
|
#include <functional>
|
2018-10-10 02:25:13 +03:00
|
|
|
#include <memory>
|
2018-03-19 05:04:16 +03:00
|
|
|
|
2018-11-11 01:19:08 +03:00
|
|
|
#include <react/core/ComponentDescriptor.h>
|
|
|
|
#include <react/core/Props.h>
|
|
|
|
#include <react/core/ShadowNode.h>
|
|
|
|
#include <react/core/ShadowNodeFragment.h>
|
|
|
|
#include <react/events/EventDispatcher.h>
|
2018-03-19 05:04:16 +03:00
|
|
|
|
|
|
|
namespace facebook {
|
|
|
|
namespace react {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Default template-based implementation of ComponentDescriptor.
|
|
|
|
* Use your `ShadowNode` type as a template argument and override any methods
|
|
|
|
* if necessary.
|
|
|
|
*/
|
|
|
|
template <typename ShadowNodeT>
|
2018-10-10 02:25:13 +03:00
|
|
|
class ConcreteComponentDescriptor : public ComponentDescriptor {
|
|
|
|
static_assert(
|
|
|
|
std::is_base_of<ShadowNode, ShadowNodeT>::value,
|
|
|
|
"ShadowNodeT must be a descendant of ShadowNode");
|
2018-03-19 05:04:16 +03:00
|
|
|
|
|
|
|
using SharedShadowNodeT = std::shared_ptr<const ShadowNodeT>;
|
2018-04-16 17:43:22 +03:00
|
|
|
using ConcreteProps = typename ShadowNodeT::ConcreteProps;
|
2018-03-19 05:04:16 +03:00
|
|
|
using SharedConcreteProps = typename ShadowNodeT::SharedConcreteProps;
|
2018-06-09 23:02:55 +03:00
|
|
|
using ConcreteEventEmitter = typename ShadowNodeT::ConcreteEventEmitter;
|
2018-10-10 02:25:13 +03:00
|
|
|
using SharedConcreteEventEmitter =
|
|
|
|
typename ShadowNodeT::SharedConcreteEventEmitter;
|
2018-03-19 05:04:16 +03:00
|
|
|
|
2018-10-10 02:25:13 +03:00
|
|
|
public:
|
|
|
|
ConcreteComponentDescriptor(SharedEventDispatcher eventDispatcher)
|
|
|
|
: eventDispatcher_(eventDispatcher) {}
|
2018-05-23 01:48:19 +03:00
|
|
|
|
2018-03-19 05:04:16 +03:00
|
|
|
ComponentHandle getComponentHandle() const override {
|
2018-08-04 19:30:13 +03:00
|
|
|
return ShadowNodeT::Handle();
|
2018-03-19 05:04:16 +03:00
|
|
|
}
|
|
|
|
|
2018-05-18 06:03:46 +03:00
|
|
|
ComponentName getComponentName() const override {
|
2018-08-04 19:30:13 +03:00
|
|
|
return ShadowNodeT::Name();
|
2018-05-18 06:03:46 +03:00
|
|
|
}
|
|
|
|
|
2018-03-19 05:04:16 +03:00
|
|
|
SharedShadowNode createShadowNode(
|
2018-10-10 02:25:13 +03:00
|
|
|
const ShadowNodeFragment &fragment) const override {
|
2018-08-04 19:30:30 +03:00
|
|
|
assert(std::dynamic_pointer_cast<const ConcreteProps>(fragment.props));
|
2018-10-10 02:25:13 +03:00
|
|
|
assert(std::dynamic_pointer_cast<const ConcreteEventEmitter>(
|
|
|
|
fragment.eventEmitter));
|
2018-08-04 19:30:30 +03:00
|
|
|
|
2018-10-10 02:25:13 +03:00
|
|
|
auto shadowNode =
|
|
|
|
std::make_shared<ShadowNodeT>(fragment, getCloneFunction());
|
2018-05-23 01:48:19 +03:00
|
|
|
|
2018-04-27 03:51:54 +03:00
|
|
|
adopt(shadowNode);
|
2018-08-04 19:30:13 +03:00
|
|
|
|
2018-04-27 03:51:54 +03:00
|
|
|
return shadowNode;
|
2018-03-19 05:04:16 +03:00
|
|
|
}
|
|
|
|
|
2018-07-18 08:41:31 +03:00
|
|
|
UnsharedShadowNode cloneShadowNode(
|
2018-10-10 02:25:13 +03:00
|
|
|
const ShadowNode &sourceShadowNode,
|
|
|
|
const ShadowNodeFragment &fragment) const override {
|
|
|
|
auto shadowNode = std::make_shared<ShadowNodeT>(sourceShadowNode, fragment);
|
2018-05-23 01:48:19 +03:00
|
|
|
|
2018-04-27 03:51:54 +03:00
|
|
|
adopt(shadowNode);
|
|
|
|
return shadowNode;
|
2018-03-19 05:04:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void appendChild(
|
2018-10-10 02:25:13 +03:00
|
|
|
const SharedShadowNode &parentShadowNode,
|
|
|
|
const SharedShadowNode &childShadowNode) const override {
|
|
|
|
auto concreteParentShadowNode =
|
|
|
|
std::static_pointer_cast<const ShadowNodeT>(parentShadowNode);
|
|
|
|
auto concreteNonConstParentShadowNode =
|
|
|
|
std::const_pointer_cast<ShadowNodeT>(concreteParentShadowNode);
|
2018-03-19 05:04:16 +03:00
|
|
|
concreteNonConstParentShadowNode->appendChild(childShadowNode);
|
|
|
|
}
|
|
|
|
|
2018-04-16 17:43:22 +03:00
|
|
|
virtual SharedProps cloneProps(
|
2018-10-10 02:25:13 +03:00
|
|
|
const SharedProps &props,
|
|
|
|
const RawProps &rawProps) const override {
|
2018-04-16 17:43:22 +03:00
|
|
|
return ShadowNodeT::Props(rawProps, props);
|
|
|
|
};
|
|
|
|
|
2018-06-09 23:02:55 +03:00
|
|
|
virtual SharedEventEmitter createEventEmitter(
|
2018-10-10 02:25:13 +03:00
|
|
|
SharedEventTarget eventTarget,
|
|
|
|
const Tag &tag) const override {
|
|
|
|
return std::make_shared<ConcreteEventEmitter>(
|
|
|
|
std::move(eventTarget), tag, eventDispatcher_);
|
2018-05-23 01:48:19 +03:00
|
|
|
}
|
|
|
|
|
2018-10-10 02:25:13 +03:00
|
|
|
protected:
|
2018-04-27 03:51:54 +03:00
|
|
|
virtual void adopt(UnsharedShadowNode shadowNode) const {
|
|
|
|
// Default implementation does nothing.
|
2018-08-04 19:30:13 +03:00
|
|
|
assert(shadowNode->getComponentHandle() == getComponentHandle());
|
2018-04-27 03:51:54 +03:00
|
|
|
}
|
|
|
|
|
2018-10-10 02:25:13 +03:00
|
|
|
private:
|
|
|
|
mutable SharedEventDispatcher eventDispatcher_{nullptr};
|
2018-05-23 01:48:19 +03:00
|
|
|
|
2018-04-27 03:51:27 +03:00
|
|
|
mutable ShadowNodeCloneFunction cloneFunction_;
|
|
|
|
|
|
|
|
ShadowNodeCloneFunction getCloneFunction() const {
|
|
|
|
if (!cloneFunction_) {
|
2018-10-10 02:25:13 +03:00
|
|
|
cloneFunction_ = [this](
|
|
|
|
const ShadowNode &shadowNode,
|
|
|
|
const ShadowNodeFragment &fragment) {
|
2018-08-04 19:30:37 +03:00
|
|
|
return this->cloneShadowNode(shadowNode, fragment);
|
2018-04-27 03:51:27 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return cloneFunction_;
|
|
|
|
}
|
2018-03-19 05:04:16 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace react
|
|
|
|
} // namespace facebook
|