mirror of
https://github.com/status-im/react-native.git
synced 2025-01-14 11:34:23 +00:00
Fabric/Text: ConcreteViewShadowNode - base class for all View
-like shadow nodes
Summary: Quite trivial split ViewShadowNode into concrete class and templace class. Reviewed By: fkgozali Differential Revision: D7595017 fbshipit-source-id: b1ac1dfa187e5cfd0a34fbf84b3e1ae308bb0c99
This commit is contained in:
parent
bd91eaf664
commit
f72df7a6e7
167
ReactCommon/fabric/view/ConcreteViewShadowNode.h
Normal file
167
ReactCommon/fabric/view/ConcreteViewShadowNode.h
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/**
|
||||||
|
* 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/ConcreteShadowNode.h>
|
||||||
|
#include <fabric/core/LayoutableShadowNode.h>
|
||||||
|
#include <fabric/core/ShadowNode.h>
|
||||||
|
#include <fabric/debug/DebugStringConvertibleItem.h>
|
||||||
|
#include <fabric/view/AccessibleShadowNode.h>
|
||||||
|
#include <fabric/view/ViewProps.h>
|
||||||
|
#include <fabric/view/YogaLayoutableShadowNode.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Template for all <View>-like classes (classes which have all same props
|
||||||
|
* as <View> and similar basic behaviour).
|
||||||
|
* For example: <Paragraph>, <Image>, but not <Text>, <RawText>.
|
||||||
|
*/
|
||||||
|
template <typename ViewPropsT>
|
||||||
|
class ConcreteViewShadowNode:
|
||||||
|
public ConcreteShadowNode<ViewPropsT>,
|
||||||
|
public AccessibleShadowNode,
|
||||||
|
public YogaLayoutableShadowNode {
|
||||||
|
|
||||||
|
static_assert(std::is_base_of<ViewProps, ViewPropsT>::value, "ViewPropsT must be a descendant of ViewProps");
|
||||||
|
static_assert(std::is_base_of<YogaStylableProps, ViewPropsT>::value, "ViewPropsT must be a descendant of YogaStylableProps");
|
||||||
|
static_assert(std::is_base_of<AccessibilityProps, ViewPropsT>::value, "ViewPropsT must be a descendant of AccessibilityProps");
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using ConcreteViewProps = ViewPropsT;
|
||||||
|
using SharedConcreteViewProps = std::shared_ptr<const ViewPropsT>;
|
||||||
|
using SharedConcreteViewShadowNode = std::shared_ptr<const ConcreteViewShadowNode>;
|
||||||
|
|
||||||
|
ConcreteViewShadowNode(
|
||||||
|
const Tag &tag,
|
||||||
|
const Tag &rootTag,
|
||||||
|
const InstanceHandle &instanceHandle,
|
||||||
|
const SharedViewProps &props = ConcreteViewShadowNode::defaultSharedProps(),
|
||||||
|
const SharedShadowNodeSharedList &children = ShadowNode::emptySharedShadowNodeSharedList(),
|
||||||
|
const ShadowNodeCloneFunction &cloneFunction = nullptr
|
||||||
|
):
|
||||||
|
ConcreteShadowNode<ViewPropsT>(
|
||||||
|
tag,
|
||||||
|
rootTag,
|
||||||
|
instanceHandle,
|
||||||
|
props,
|
||||||
|
children,
|
||||||
|
cloneFunction
|
||||||
|
),
|
||||||
|
AccessibleShadowNode(
|
||||||
|
props
|
||||||
|
),
|
||||||
|
YogaLayoutableShadowNode(
|
||||||
|
props,
|
||||||
|
children
|
||||||
|
) {};
|
||||||
|
|
||||||
|
ConcreteViewShadowNode(
|
||||||
|
const SharedConcreteViewShadowNode &shadowNode,
|
||||||
|
const SharedViewProps &props = nullptr,
|
||||||
|
const SharedShadowNodeSharedList &children = nullptr
|
||||||
|
):
|
||||||
|
ConcreteShadowNode<ViewPropsT>(
|
||||||
|
shadowNode,
|
||||||
|
props,
|
||||||
|
children
|
||||||
|
),
|
||||||
|
AccessibleShadowNode(
|
||||||
|
shadowNode,
|
||||||
|
props
|
||||||
|
),
|
||||||
|
YogaLayoutableShadowNode(
|
||||||
|
shadowNode,
|
||||||
|
props,
|
||||||
|
children
|
||||||
|
) {};
|
||||||
|
|
||||||
|
void appendChild(const SharedShadowNode &child) {
|
||||||
|
ensureUnsealed();
|
||||||
|
|
||||||
|
ShadowNode::appendChild(child);
|
||||||
|
|
||||||
|
auto yogaLayoutableChild = std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(child);
|
||||||
|
if (yogaLayoutableChild) {
|
||||||
|
YogaLayoutableShadowNode::appendChild(yogaLayoutableChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedLayoutableShadowNode cloneAndReplaceChild(const SharedLayoutableShadowNode &child) override {
|
||||||
|
ensureUnsealed();
|
||||||
|
|
||||||
|
auto childShadowNode = std::dynamic_pointer_cast<const ShadowNode>(child);
|
||||||
|
assert(childShadowNode);
|
||||||
|
auto childShadowNodeClone = childShadowNode->clone();
|
||||||
|
|
||||||
|
// This is overloading of `SharedLayoutableShadowNode::cloneAndReplaceChild`,
|
||||||
|
// the method is used to clone some node as a preparation for future mutation
|
||||||
|
// caused by relayout.
|
||||||
|
// Because those changes are not requested by UIManager, they add a layer
|
||||||
|
// of node generation (between the committed stage and new proposed stage).
|
||||||
|
// That additional layer confuses the Diffing algorithm which uses
|
||||||
|
// `sourceNode` for referencing the previous (aka committed) stage
|
||||||
|
// of the tree to produce mutation instructions.
|
||||||
|
// In other words, if we don't compensate this change here,
|
||||||
|
// the Diffing algorithm will compare wrong trees
|
||||||
|
// ("new-but-not-laid-out-yet vs. new" instead of "committed vs. new").
|
||||||
|
auto nonConstChildShadowNodeClone = std::const_pointer_cast<ShadowNode>(childShadowNodeClone);
|
||||||
|
nonConstChildShadowNodeClone->shallowSourceNode();
|
||||||
|
|
||||||
|
ShadowNode::replaceChild(childShadowNode, childShadowNodeClone);
|
||||||
|
return std::dynamic_pointer_cast<const LayoutableShadowNode>(childShadowNodeClone);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Equality
|
||||||
|
|
||||||
|
bool operator==(const ShadowNode& rhs) const override {
|
||||||
|
if (!ShadowNode::operator==(rhs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &&other = static_cast<const ConcreteViewShadowNode&>(rhs);
|
||||||
|
return getLayoutMetrics() == other.getLayoutMetrics();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - DebugStringConvertible
|
||||||
|
|
||||||
|
SharedDebugStringConvertibleList getDebugProps() const override {
|
||||||
|
SharedDebugStringConvertibleList list = {};
|
||||||
|
|
||||||
|
auto basePropsList = ShadowNode::getDebugProps();
|
||||||
|
std::move(basePropsList.begin(), basePropsList.end(), std::back_inserter(list));
|
||||||
|
|
||||||
|
list.push_back(std::make_shared<DebugStringConvertibleItem>("layout", "", YogaLayoutableShadowNode::getDebugProps()));
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#pragma mark - LayoutableShadowNode
|
||||||
|
|
||||||
|
SharedLayoutableShadowNodeList getLayoutableChildNodes() const override {
|
||||||
|
SharedLayoutableShadowNodeList sharedLayoutableShadowNodeList = {};
|
||||||
|
for (auto child : *ShadowNode::children_) {
|
||||||
|
const SharedLayoutableShadowNode layoutableShadowNode = std::dynamic_pointer_cast<const LayoutableShadowNode>(child);
|
||||||
|
if (!layoutableShadowNode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedLayoutableShadowNodeList.push_back(layoutableShadowNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sharedLayoutableShadowNodeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
@ -7,138 +7,12 @@
|
|||||||
|
|
||||||
#include "ViewShadowNode.h"
|
#include "ViewShadowNode.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <fabric/debug/DebugStringConvertibleItem.h>
|
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
#pragma mark - Constructors
|
|
||||||
|
|
||||||
ViewShadowNode::ViewShadowNode(
|
|
||||||
const Tag &tag,
|
|
||||||
const Tag &rootTag,
|
|
||||||
const InstanceHandle &instanceHandle,
|
|
||||||
const SharedViewProps &props,
|
|
||||||
const SharedShadowNodeSharedList &children,
|
|
||||||
const ShadowNodeCloneFunction &cloneFunction
|
|
||||||
):
|
|
||||||
ConcreteShadowNode(
|
|
||||||
tag,
|
|
||||||
rootTag,
|
|
||||||
instanceHandle,
|
|
||||||
props,
|
|
||||||
children,
|
|
||||||
cloneFunction
|
|
||||||
),
|
|
||||||
AccessibleShadowNode(
|
|
||||||
props
|
|
||||||
),
|
|
||||||
YogaLayoutableShadowNode(
|
|
||||||
props,
|
|
||||||
children
|
|
||||||
) {};
|
|
||||||
|
|
||||||
ViewShadowNode::ViewShadowNode(
|
|
||||||
const SharedViewShadowNode &shadowNode,
|
|
||||||
const SharedViewProps &props,
|
|
||||||
const SharedShadowNodeSharedList &children
|
|
||||||
):
|
|
||||||
ConcreteShadowNode(
|
|
||||||
shadowNode,
|
|
||||||
props,
|
|
||||||
children
|
|
||||||
),
|
|
||||||
AccessibleShadowNode(
|
|
||||||
shadowNode,
|
|
||||||
props
|
|
||||||
),
|
|
||||||
YogaLayoutableShadowNode(
|
|
||||||
shadowNode,
|
|
||||||
props,
|
|
||||||
children
|
|
||||||
) {};
|
|
||||||
|
|
||||||
ComponentName ViewShadowNode::getComponentName() const {
|
ComponentName ViewShadowNode::getComponentName() const {
|
||||||
return ComponentName("View");
|
return ComponentName("View");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewShadowNode::appendChild(const SharedShadowNode &child) {
|
|
||||||
ensureUnsealed();
|
|
||||||
|
|
||||||
ShadowNode::appendChild(child);
|
|
||||||
|
|
||||||
auto yogaLayoutableChild = std::dynamic_pointer_cast<const YogaLayoutableShadowNode>(child);
|
|
||||||
if (yogaLayoutableChild) {
|
|
||||||
YogaLayoutableShadowNode::appendChild(yogaLayoutableChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - YogaLayoutableShadowNode
|
|
||||||
|
|
||||||
SharedLayoutableShadowNodeList ViewShadowNode::getLayoutableChildNodes() const {
|
|
||||||
SharedLayoutableShadowNodeList sharedLayoutableShadowNodeList = {};
|
|
||||||
for (auto child : *children_) {
|
|
||||||
const SharedLayoutableShadowNode layoutableShadowNode = std::dynamic_pointer_cast<const LayoutableShadowNode>(child);
|
|
||||||
if (!layoutableShadowNode) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedLayoutableShadowNodeList.push_back(layoutableShadowNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sharedLayoutableShadowNodeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedLayoutableShadowNode ViewShadowNode::cloneAndReplaceChild(const SharedLayoutableShadowNode &child) {
|
|
||||||
ensureUnsealed();
|
|
||||||
|
|
||||||
auto childShadowNode = std::dynamic_pointer_cast<const ShadowNode>(child);
|
|
||||||
assert(childShadowNode);
|
|
||||||
auto childShadowNodeClone = childShadowNode->clone();
|
|
||||||
|
|
||||||
// This is overloading of `SharedLayoutableShadowNode::cloneAndReplaceChild`,
|
|
||||||
// the method is used to clone some node as a preparation for future mutation
|
|
||||||
// caused by relayout.
|
|
||||||
// Because those changes are not requested by UIManager, they add a layer
|
|
||||||
// of node generation (between the committed stage and new proposed stage).
|
|
||||||
// That additional layer confuses the Diffing algorithm which uses
|
|
||||||
// `sourceNode` for referencing the previous (aka committed) stage
|
|
||||||
// of the tree to produce mutation instructions.
|
|
||||||
// In other words, if we don't compensate this change here,
|
|
||||||
// the Diffing algorithm will compare wrong trees
|
|
||||||
// ("new-but-not-laid-out-yet vs. new" instead of "committed vs. new").
|
|
||||||
auto nonConstChildShadowNodeClone = std::const_pointer_cast<ShadowNode>(childShadowNodeClone);
|
|
||||||
nonConstChildShadowNodeClone->shallowSourceNode();
|
|
||||||
|
|
||||||
ShadowNode::replaceChild(childShadowNode, childShadowNodeClone);
|
|
||||||
return std::dynamic_pointer_cast<const LayoutableShadowNode>(childShadowNodeClone);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Equality
|
|
||||||
|
|
||||||
bool ViewShadowNode::operator==(const ShadowNode& rhs) const {
|
|
||||||
if (!ShadowNode::operator==(rhs)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &&other = static_cast<const ViewShadowNode&>(rhs);
|
|
||||||
return getLayoutMetrics() == other.getLayoutMetrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - DebugStringConvertible
|
|
||||||
|
|
||||||
SharedDebugStringConvertibleList ViewShadowNode::getDebugProps() const {
|
|
||||||
SharedDebugStringConvertibleList list = {};
|
|
||||||
|
|
||||||
auto basePropsList = ShadowNode::getDebugProps();
|
|
||||||
std::move(basePropsList.begin(), basePropsList.end(), std::back_inserter(list));
|
|
||||||
|
|
||||||
list.push_back(std::make_shared<DebugStringConvertibleItem>("layout", "", YogaLayoutableShadowNode::getDebugProps()));
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace react
|
} // namespace react
|
||||||
} // namespace facebook
|
} // namespace facebook
|
||||||
|
@ -7,12 +7,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fabric/core/ConcreteShadowNode.h>
|
#include <memory>
|
||||||
#include <fabric/core/LayoutableShadowNode.h>
|
|
||||||
#include <fabric/core/ShadowNode.h>
|
|
||||||
#include <fabric/view/AccessibleShadowNode.h>
|
|
||||||
#include <fabric/view/ViewProps.h>
|
#include <fabric/view/ViewProps.h>
|
||||||
#include <fabric/view/YogaLayoutableShadowNode.h>
|
#include <fabric/view/ConcreteViewShadowNode.h>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
@ -21,48 +19,14 @@ class ViewShadowNode;
|
|||||||
|
|
||||||
using SharedViewShadowNode = std::shared_ptr<const ViewShadowNode>;
|
using SharedViewShadowNode = std::shared_ptr<const ViewShadowNode>;
|
||||||
|
|
||||||
class ViewShadowNode:
|
class ViewShadowNode final:
|
||||||
public ConcreteShadowNode<ViewProps>,
|
public ConcreteViewShadowNode<ViewProps> {
|
||||||
public AccessibleShadowNode,
|
|
||||||
public YogaLayoutableShadowNode {
|
|
||||||
|
|
||||||
static_assert(std::is_base_of<YogaStylableProps, ViewProps>::value, "ViewProps must be a descendant of YogaStylableProps");
|
|
||||||
static_assert(std::is_base_of<AccessibilityProps, ViewProps>::value, "ViewProps must be a descendant of AccessibilityProps");
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ViewShadowNode(
|
|
||||||
const Tag &tag,
|
|
||||||
const Tag &rootTag,
|
|
||||||
const InstanceHandle &instanceHandle,
|
|
||||||
const SharedViewProps &props = ViewShadowNode::defaultSharedProps(),
|
|
||||||
const SharedShadowNodeSharedList &children = ShadowNode::emptySharedShadowNodeSharedList(),
|
|
||||||
const ShadowNodeCloneFunction &cloneFunction = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
ViewShadowNode(
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
||||||
const SharedViewShadowNode &shadowNode,
|
|
||||||
const SharedViewProps &props = nullptr,
|
|
||||||
const SharedShadowNodeSharedList &children = nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
ComponentName getComponentName() const override;
|
ComponentName getComponentName() const override;
|
||||||
|
|
||||||
void appendChild(const SharedShadowNode &child);
|
|
||||||
|
|
||||||
#pragma mark - Equality
|
|
||||||
|
|
||||||
bool operator==(const ShadowNode& rhs) const override;
|
|
||||||
|
|
||||||
#pragma mark - DebugStringConvertible
|
|
||||||
|
|
||||||
SharedDebugStringConvertibleList getDebugProps() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
#pragma mark - LayoutableShadowNode
|
|
||||||
|
|
||||||
SharedLayoutableShadowNodeList getLayoutableChildNodes() const override;
|
|
||||||
SharedLayoutableShadowNode cloneAndReplaceChild(const SharedLayoutableShadowNode &child) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace react
|
} // namespace react
|
||||||
|
Loading…
x
Reference in New Issue
Block a user