Skip to content

Commit

Permalink
Fabric: Implementing cloneAndReplaceChild() for ViewShadowNode
Browse files Browse the repository at this point in the history
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
  • Loading branch information
shergin authored and facebook-github-bot committed Mar 26, 2018
1 parent 8f9212b commit ee0cc6b
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 6 deletions.
4 changes: 0 additions & 4 deletions ReactCommon/fabric/core/layout/LayoutableShadowNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,5 @@ void LayoutableShadowNode::layoutChildren(LayoutContext layoutContext) {
// Default implementation does nothing.
}

SharedLayoutableShadowNode LayoutableShadowNode::cloneAndReplaceChild(const SharedLayoutableShadowNode &child) {
return child;
}

} // namespace react
} // namespace facebook
3 changes: 1 addition & 2 deletions ReactCommon/fabric/core/layout/LayoutableShadowNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ class LayoutableShadowNode:
/*
* 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.
* 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.
Expand Down
27 changes: 27 additions & 0 deletions ReactCommon/fabric/view/ViewShadowNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "ViewShadowNode.h"

#include <algorithm>

#include <fabric/debug/DebugStringConvertibleItem.h>

namespace facebook {
Expand Down Expand Up @@ -87,6 +89,31 @@ SharedLayoutableShadowNodeList ViewShadowNode::getChildren() const {
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

SharedDebugStringConvertibleList ViewShadowNode::getDebugProps() const {
Expand Down
1 change: 1 addition & 0 deletions ReactCommon/fabric/view/ViewShadowNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class ViewShadowNode:
#pragma mark - LayoutableShadowNode

SharedLayoutableShadowNodeList getChildren() const override;
SharedLayoutableShadowNode cloneAndReplaceChild(const SharedLayoutableShadowNode &child) override;
};

} // namespace react
Expand Down

0 comments on commit ee0cc6b

Please sign in to comment.