Valentin Shergin 2a3025da97 Fabric: Application layer of events infrastructure
Summary: This implements `EventHandlers` abstract class (aka "Events Guy") which encapsulates `eventDispatcher` and `instanceHandle` (and ownership of future `eventTarget`), all of this as part of existing {ShadowNode + Props + LayoutMetrics + LocalData + Descriptor + (and now) EventHandlers} infra. (We don't plan to add anything else to this model. Ever.)

Reviewed By: fkgozali

Differential Revision: D8053351

fbshipit-source-id: 1dd9ccbcbe5a2eb284b59ea351dc8beca645e8bf
2018-05-22 16:31:58 -07:00

108 lines
3.0 KiB
C++

// Copyright 2004-present Facebook. All Rights Reserved.
#include "ShadowTree.h"
#include <fabric/core/LayoutContext.h>
#include <fabric/core/LayoutPrimitives.h>
#include "ShadowTreeDelegate.h"
#include "Differentiator.h"
#include "TreeMutationInstruction.h"
namespace facebook {
namespace react {
ShadowTree::ShadowTree(Tag rootTag):
rootTag_(rootTag) {
auto &&noopEventHandlers = std::make_shared<const ViewEventHandlers>(nullptr, nullptr);
rootShadowNode_ = std::make_shared<RootShadowNode>(
rootTag,
rootTag,
RootShadowNode::defaultSharedProps(),
noopEventHandlers,
ShadowNode::emptySharedShadowNodeSharedList(),
nullptr
);
}
Tag ShadowTree::getRootTag() const {
return rootTag_;
}
#pragma mark - Layout
Size ShadowTree::measure(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const {
auto newRootShadowNode = cloneRootShadowNode(layoutConstraints, layoutContext);
newRootShadowNode->layout();
return newRootShadowNode->getLayoutMetrics().frame.size;
}
void ShadowTree::constraintLayout(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) {
auto newRootShadowNode = cloneRootShadowNode(layoutConstraints, layoutContext);
complete(newRootShadowNode);
}
#pragma mark - Commiting
UnsharedRootShadowNode ShadowTree::cloneRootShadowNode(const LayoutConstraints &layoutConstraints, const LayoutContext &layoutContext) const {
auto oldRootShadowNode = rootShadowNode_;
auto &&props = std::make_shared<const RootProps>(*oldRootShadowNode->getProps(), layoutConstraints, layoutContext);
auto newRootShadowNode = std::make_shared<RootShadowNode>(oldRootShadowNode, props, nullptr, nullptr);
return newRootShadowNode;
}
void ShadowTree::complete(const SharedShadowNodeUnsharedList &rootChildNodes) {
auto oldRootShadowNode = rootShadowNode_;
auto newRootShadowNode =
std::make_shared<RootShadowNode>(oldRootShadowNode, nullptr, nullptr, SharedShadowNodeSharedList(rootChildNodes));
complete(newRootShadowNode);
}
void ShadowTree::complete(UnsharedRootShadowNode newRootShadowNode) {
SharedRootShadowNode oldRootShadowNode = rootShadowNode_;
newRootShadowNode->layout();
newRootShadowNode->sealRecursive();
TreeMutationInstructionList instructions = TreeMutationInstructionList();
calculateMutationInstructions(
instructions,
oldRootShadowNode,
newRootShadowNode
);
if (commit(newRootShadowNode)) {
if (delegate_) {
delegate_->shadowTreeDidCommit(shared_from_this(), instructions);
}
}
}
bool ShadowTree::commit(const SharedRootShadowNode &newRootShadowNode) {
std::lock_guard<std::mutex> lock(commitMutex_);
if (newRootShadowNode->getSourceNode() != rootShadowNode_) {
return false;
}
rootShadowNode_ = newRootShadowNode;
return true;
}
#pragma mark - Delegate
void ShadowTree::setDelegate(ShadowTreeDelegate *delegate) {
delegate_ = delegate;
}
ShadowTreeDelegate *ShadowTree::getDelegate() const {
return delegate_;
}
} // namespace react
} // namespace facebook