2018-03-19 05:04:16 +03:00
|
|
|
/**
|
|
|
|
* 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 <memory>
|
2018-04-27 03:51:27 +03:00
|
|
|
#include <functional>
|
2018-03-19 05:04:16 +03:00
|
|
|
|
2018-03-24 02:46:10 +03:00
|
|
|
#include <fabric/core/ComponentDescriptor.h>
|
2018-03-19 05:04:16 +03:00
|
|
|
#include <fabric/core/Props.h>
|
2018-03-24 02:46:10 +03:00
|
|
|
#include <fabric/core/ShadowNode.h>
|
2018-08-04 19:30:32 +03:00
|
|
|
#include <fabric/core/ShadowNodeFragment.h>
|
|
|
|
#include <fabric/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>
|
|
|
|
class ConcreteComponentDescriptor: public ComponentDescriptor {
|
|
|
|
static_assert(std::is_base_of<ShadowNode, ShadowNodeT>::value, "ShadowNodeT must be a descendant of ShadowNode");
|
|
|
|
|
|
|
|
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;
|
|
|
|
using SharedConcreteEventEmitter = typename ShadowNodeT::SharedConcreteEventEmitter;
|
2018-03-19 05:04:16 +03:00
|
|
|
|
|
|
|
public:
|
2018-05-23 01:48:19 +03:00
|
|
|
ConcreteComponentDescriptor(SharedEventDispatcher eventDispatcher):
|
|
|
|
eventDispatcher_(eventDispatcher) {}
|
|
|
|
|
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-08-04 19:30:30 +03:00
|
|
|
const ShadowNodeFragment &fragment
|
2018-03-19 05:04:16 +03:00
|
|
|
) const override {
|
2018-08-04 19:30:30 +03:00
|
|
|
assert(std::dynamic_pointer_cast<const ConcreteProps>(fragment.props));
|
|
|
|
assert(std::dynamic_pointer_cast<const ConcreteEventEmitter>(fragment.eventEmitter));
|
|
|
|
|
|
|
|
auto shadowNode = std::make_shared<ShadowNodeT>(
|
|
|
|
fragment,
|
2018-04-27 03:51:27 +03:00
|
|
|
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-08-04 19:30:30 +03:00
|
|
|
const ShadowNode &sourceShadowNode,
|
|
|
|
const ShadowNodeFragment &fragment
|
2018-03-19 05:04:16 +03:00
|
|
|
) const override {
|
2018-08-04 19:30:30 +03:00
|
|
|
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(
|
|
|
|
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);
|
|
|
|
concreteNonConstParentShadowNode->appendChild(childShadowNode);
|
|
|
|
}
|
|
|
|
|
2018-04-16 17:43:22 +03:00
|
|
|
virtual SharedProps cloneProps(
|
|
|
|
const SharedProps &props,
|
|
|
|
const RawProps &rawProps
|
|
|
|
) const override {
|
|
|
|
return ShadowNodeT::Props(rawProps, props);
|
|
|
|
};
|
|
|
|
|
2018-06-09 23:02:55 +03:00
|
|
|
virtual SharedEventEmitter createEventEmitter(
|
2018-06-30 01:30:30 +03:00
|
|
|
const EventTarget &eventTarget,
|
2018-06-01 19:36:19 +03:00
|
|
|
const Tag &tag
|
2018-05-23 01:48:19 +03:00
|
|
|
) const override {
|
2018-06-30 01:30:30 +03:00
|
|
|
return std::make_shared<ConcreteEventEmitter>(eventTarget, tag, eventDispatcher_);
|
2018-05-23 01:48:19 +03:00
|
|
|
}
|
|
|
|
|
2018-04-27 03:51:54 +03:00
|
|
|
protected:
|
|
|
|
|
|
|
|
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-04-27 03:51:27 +03:00
|
|
|
private:
|
2018-04-27 03:51:54 +03:00
|
|
|
|
2018-05-23 01:48:19 +03:00
|
|
|
mutable SharedEventDispatcher eventDispatcher_ {nullptr};
|
|
|
|
|
2018-04-27 03:51:27 +03:00
|
|
|
mutable ShadowNodeCloneFunction cloneFunction_;
|
|
|
|
|
|
|
|
ShadowNodeCloneFunction getCloneFunction() const {
|
|
|
|
if (!cloneFunction_) {
|
2018-08-04 19:30:37 +03:00
|
|
|
cloneFunction_ = [this](const ShadowNode &shadowNode, const ShadowNodeFragment &fragment) {
|
|
|
|
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
|