Fabric: `Element<>` now returns (and accepts) mutable (non const) shared pointers

Summary:
It makes perfect sense because `Builder` builds totally new shadow trees, so those are not sealed or used by anyone yet.
Assigning it to const shared pointer will do logical sealing (and it does not requires const-cast).
Fewer const-casts in the code, fewer bugs.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D19596284

fbshipit-source-id: 75d1c706034958ba7e4bc80a68af75a57c46eb6f
This commit is contained in:
Valentin Shergin 2020-01-30 19:43:33 -08:00 коммит произвёл Facebook Github Bot
Родитель d64bf2c4f8
Коммит b39c75f20e
6 изменённых файлов: 22 добавлений и 21 удалений

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

@ -36,8 +36,8 @@ TEST(ShadowNodeFamilyTest, sealObjectCorrectly) {
auto builder = ComponentBuilder{componentDescriptorRegistry};
auto shadowNodeAAA = std::shared_ptr<ViewShadowNode const>{};
auto shadowNodeAA = std::shared_ptr<ViewShadowNode const>{};
auto shadowNodeAAA = std::shared_ptr<ViewShadowNode>{};
auto shadowNodeAA = std::shared_ptr<ViewShadowNode>{};
// clang-format off
auto elementA =

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

@ -14,7 +14,7 @@ ComponentBuilder::ComponentBuilder(
ComponentDescriptorRegistry::Shared const &componentDescriptorRegistry)
: componentDescriptorRegistry_(componentDescriptorRegistry){};
ShadowNode::Shared ComponentBuilder::build(
ShadowNode::Unshared ComponentBuilder::build(
ElementFragment const &elementFragment) const {
auto &componentDescriptor =
componentDescriptorRegistry_->at(elementFragment.componentHandle);
@ -30,19 +30,21 @@ ShadowNode::Shared ComponentBuilder::build(
elementFragment.tag, elementFragment.surfaceId, nullptr},
nullptr);
auto shadowNode = componentDescriptor.createShadowNode(
auto constShadowNode = componentDescriptor.createShadowNode(
ShadowNodeFragment{
elementFragment.props,
std::make_shared<ShadowNode::ListOfShared const>(children),
elementFragment.state},
family);
auto shadowNode = std::const_pointer_cast<ShadowNode>(constShadowNode);
if (elementFragment.referenceCallback) {
elementFragment.referenceCallback(shadowNode);
}
if (elementFragment.finalizeCallback) {
elementFragment.finalizeCallback(const_cast<ShadowNode &>(*shadowNode));
elementFragment.finalizeCallback(*shadowNode);
}
return shadowNode;

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

@ -42,16 +42,15 @@ class ComponentBuilder final {
* `ComponentDescriptorRegistry`.
*/
template <typename ShadowNodeT>
std::shared_ptr<ShadowNodeT const> build(Element<ShadowNodeT> element) const {
return std::static_pointer_cast<ShadowNodeT const>(
build(element.fragment_));
std::shared_ptr<ShadowNodeT> build(Element<ShadowNodeT> element) const {
return std::static_pointer_cast<ShadowNodeT>(build(element.fragment_));
}
private:
/*
* Internal, type-erased version of `build`.
*/
ShadowNode::Shared build(ElementFragment const &elementFragment) const;
ShadowNode::Unshared build(ElementFragment const &elementFragment) const;
ComponentDescriptorRegistry::Shared componentDescriptorRegistry_;
};

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

@ -31,10 +31,10 @@ template <typename ShadowNodeT>
class Element final {
public:
using ConcreteProps = typename ShadowNodeT::ConcreteProps;
using SharedConcreteProps = typename ShadowNodeT::SharedConcreteProps;
using ConcreteEventEmitter = typename ShadowNodeT::ConcreteEventEmitter;
using SharedConcreteProps = std::shared_ptr<ConcreteProps const>;
using UnsharedConcreteProps = std::shared_ptr<ConcreteProps>;
using ConcreteShadowNode = ShadowNodeT;
using ConcreteSharedShadowNode = std::shared_ptr<ConcreteShadowNode const>;
using ConcreteUnsharedShadowNode = std::shared_ptr<ConcreteShadowNode>;
using ConcreteReferenceCallback =
std::function<void(std::shared_ptr<ShadowNodeT const> const &shadowNode)>;
@ -105,7 +105,7 @@ class Element final {
* component which is being constructed.
*/
Element &reference(
std::function<void(ConcreteSharedShadowNode const &shadowNode)>
std::function<void(ConcreteUnsharedShadowNode const &shadowNode)>
callback) {
fragment_.referenceCallback = callback;
return *this;
@ -115,10 +115,10 @@ class Element final {
* During component construction, assigns a given pointer to a component
* that is being constructed.
*/
Element &reference(ConcreteSharedShadowNode &inShadowNode) {
Element &reference(ConcreteUnsharedShadowNode &outShadowNode) {
fragment_.referenceCallback = [&](ShadowNode::Shared const &shadowNode) {
inShadowNode =
std::static_pointer_cast<ConcreteShadowNode const>(shadowNode);
outShadowNode = std::const_pointer_cast<ConcreteShadowNode>(
std::static_pointer_cast<ConcreteShadowNode const>(shadowNode));
};
return *this;
}

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

@ -28,7 +28,7 @@ class ElementFragment final {
using List = std::vector<ElementFragment>;
using ListOfShared = std::vector<Shared>;
using ReferenceCallback =
std::function<void(ShadowNode::Shared const &shadowNode)>;
std::function<void(ShadowNode::Unshared const &shadowNode)>;
using FinalizeCallback = std::function<void(ShadowNode &shadowNode)>;
/*

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

@ -21,10 +21,10 @@ using namespace facebook::react;
TEST(ElementTest, testNormalCases) {
auto builder = simpleComponentBuilder();
auto shadowNodeA = std::shared_ptr<RootShadowNode const>{};
auto shadowNodeAA = std::shared_ptr<ViewShadowNode const>{};
auto shadowNodeAB = std::shared_ptr<ViewShadowNode const>{};
auto shadowNodeABA = std::shared_ptr<ViewShadowNode const>{};
auto shadowNodeA = std::shared_ptr<RootShadowNode>{};
auto shadowNodeAA = std::shared_ptr<ViewShadowNode>{};
auto shadowNodeAB = std::shared_ptr<ViewShadowNode>{};
auto shadowNodeABA = std::shared_ptr<ViewShadowNode>{};
auto propsAA = std::make_shared<ViewProps>();
propsAA->nativeId = "node AA";