Fabric: Implementing cloneAndReplaceChild() for ViewShadowNode

Summary:
First, LayoutableShadowNode::cloneAndReplaceChild() is now pure virtual. The default implementation was useless and confusing.
Second, cloneAndReplaceChild() is now fully implemented for ViewShadowNode, so fancy Yoga Concurrent layout *should* work now.

Reviewed By: mdvacca

Differential Revision: D7376352

fbshipit-source-id: 1199a37e64535c8592a2a5480e60139f61d02006
This commit is contained in:
Valentin Shergin 2018-03-25 22:43:33 -07:00 коммит произвёл Facebook Github Bot
Родитель 8f9212b839
Коммит ee0cc6bbe7
4 изменённых файлов: 29 добавлений и 6 удалений

Просмотреть файл

@ -93,9 +93,5 @@ void LayoutableShadowNode::layoutChildren(LayoutContext layoutContext) {
// Default implementation does nothing. // Default implementation does nothing.
} }
SharedLayoutableShadowNode LayoutableShadowNode::cloneAndReplaceChild(const SharedLayoutableShadowNode &child) {
return child;
}
} // namespace react } // namespace react
} // namespace facebook } // namespace facebook

Просмотреть файл

@ -93,9 +93,8 @@ protected:
/* /*
* In case layout algorithm needs to mutate this (probably sealed) node, * In case layout algorithm needs to mutate this (probably sealed) node,
* it has to clone and replace it in the hierarchy before to do so. * it has to clone and replace it in the hierarchy before to do so.
* Default implementation does nothing and returns `child`.
*/ */
virtual SharedLayoutableShadowNode cloneAndReplaceChild(const SharedLayoutableShadowNode &child); virtual SharedLayoutableShadowNode cloneAndReplaceChild(const SharedLayoutableShadowNode &child) = 0;
/* /*
* Sets layout metrics for the shadow node. * Sets layout metrics for the shadow node.

Просмотреть файл

@ -7,6 +7,8 @@
#include "ViewShadowNode.h" #include "ViewShadowNode.h"
#include <algorithm>
#include <fabric/debug/DebugStringConvertibleItem.h> #include <fabric/debug/DebugStringConvertibleItem.h>
namespace facebook { namespace facebook {
@ -87,6 +89,31 @@ SharedLayoutableShadowNodeList ViewShadowNode::getChildren() const {
return sharedLayoutableShadowNodeList; return sharedLayoutableShadowNodeList;
} }
SharedLayoutableShadowNode ViewShadowNode::cloneAndReplaceChild(const SharedLayoutableShadowNode &child) {
ensureUnsealed();
// We cannot mutate `children_` in place here because it is a *shared*
// data structure which means other `ShadowNodes` might refer to its old value.
// So, we have to clone this and only then mutate.
auto nonConstChildrenCopy = SharedShadowNodeList(*children_);
auto viewShadowNodeChild = std::dynamic_pointer_cast<const ViewShadowNode>(child);
assert(viewShadowNodeChild);
auto viewShadowNodeChildClone = std::make_shared<const ViewShadowNode>(viewShadowNodeChild);
std::replace(
nonConstChildrenCopy.begin(),
nonConstChildrenCopy.end(),
std::static_pointer_cast<const ShadowNode>(viewShadowNodeChild),
std::static_pointer_cast<const ShadowNode>(viewShadowNodeChildClone)
);
children_ = std::make_shared<const SharedShadowNodeList>(nonConstChildrenCopy);
return std::static_pointer_cast<const LayoutableShadowNode>(viewShadowNodeChildClone);
}
#pragma mark - DebugStringConvertible #pragma mark - DebugStringConvertible
SharedDebugStringConvertibleList ViewShadowNode::getDebugProps() const { SharedDebugStringConvertibleList ViewShadowNode::getDebugProps() const {

Просмотреть файл

@ -57,6 +57,7 @@ private:
#pragma mark - LayoutableShadowNode #pragma mark - LayoutableShadowNode
SharedLayoutableShadowNodeList getChildren() const override; SharedLayoutableShadowNodeList getChildren() const override;
SharedLayoutableShadowNode cloneAndReplaceChild(const SharedLayoutableShadowNode &child) override;
}; };
} // namespace react } // namespace react