Files
react-native/ReactCommon/fabric/core/shadownode/ShadowNode.cpp
empyrical ddd5b25768 Fabric: Remove null coalescing operators in ShadowNode (#23438)
Summary:
This pull request removes the use of the GCC extension null coalescing operators (`?:`) and replaces them with ternary operators. This improves the portability of `ShadowNode.cpp` (and enables MSVC to build it)

[General] [Fixed] - Fabric: Removed null coalescing operators in `ShadowNode`
Pull Request resolved: https://github.com/facebook/react-native/pull/23438

Differential Revision: D14304958

Pulled By: shergin

fbshipit-source-id: 7d8e6778a72dabf09b1d99bc091a7578598b79c3
2019-03-04 14:47:28 -08:00

230 lines
6.0 KiB
C++

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "ShadowNode.h"
#include <string>
#include <react/core/ComponentDescriptor.h>
#include <react/core/ShadowNodeFragment.h>
#include <react/debug/DebugStringConvertible.h>
#include <react/debug/debugStringConvertibleUtils.h>
namespace facebook {
namespace react {
SharedShadowNodeSharedList ShadowNode::emptySharedShadowNodeSharedList() {
static const auto emptySharedShadowNodeSharedList =
std::make_shared<SharedShadowNodeList>();
return emptySharedShadowNodeSharedList;
}
#pragma mark - Constructors
ShadowNode::ShadowNode(
const ShadowNodeFragment &fragment,
const ComponentDescriptor &componentDescriptor)
: tag_(fragment.tag),
rootTag_(fragment.rootTag),
props_(fragment.props),
eventEmitter_(fragment.eventEmitter),
children_(
fragment.children ? fragment.children
: emptySharedShadowNodeSharedList()),
state_(fragment.state),
componentDescriptor_(componentDescriptor),
childrenAreShared_(true),
revision_(1) {
assert(props_);
assert(children_);
}
ShadowNode::ShadowNode(
const ShadowNode &sourceShadowNode,
const ShadowNodeFragment &fragment)
: tag_(fragment.tag ? fragment.tag : sourceShadowNode.tag_),
rootTag_(fragment.rootTag ? fragment.rootTag : sourceShadowNode.rootTag_),
props_(fragment.props ? fragment.props : sourceShadowNode.props_),
eventEmitter_(
fragment.eventEmitter ? fragment.eventEmitter
: sourceShadowNode.eventEmitter_),
children_(
fragment.children ? fragment.children : sourceShadowNode.children_),
localData_(
fragment.localData ? fragment.localData
: sourceShadowNode.localData_),
state_(
fragment.state ? fragment.state
: sourceShadowNode.getCommitedState()),
componentDescriptor_(sourceShadowNode.componentDescriptor_),
childrenAreShared_(true),
revision_(sourceShadowNode.revision_ + 1) {
assert(props_);
assert(children_);
}
UnsharedShadowNode ShadowNode::clone(const ShadowNodeFragment &fragment) const {
return componentDescriptor_.cloneShadowNode(*this, fragment);
}
#pragma mark - Getters
const SharedShadowNodeList &ShadowNode::getChildren() const {
return *children_;
}
SharedProps ShadowNode::getProps() const {
return props_;
}
SharedEventEmitter ShadowNode::getEventEmitter() const {
return eventEmitter_;
}
Tag ShadowNode::getTag() const {
return tag_;
}
Tag ShadowNode::getRootTag() const {
return rootTag_;
}
const State::Shared &ShadowNode::getState() const {
return state_;
}
const State::Shared &ShadowNode::getCommitedState() const {
return state_ ? state_->getCommitedState()
: ShadowNodeFragment::statePlaceholder();
}
SharedLocalData ShadowNode::getLocalData() const {
return localData_;
}
void ShadowNode::sealRecursive() const {
if (getSealed()) {
return;
}
seal();
props_->seal();
for (auto child : *children_) {
child->sealRecursive();
}
}
#pragma mark - Mutating Methods
void ShadowNode::appendChild(const SharedShadowNode &child) {
ensureUnsealed();
cloneChildrenIfShared();
auto nonConstChildren =
std::const_pointer_cast<SharedShadowNodeList>(children_);
nonConstChildren->push_back(child);
}
void ShadowNode::replaceChild(
const SharedShadowNode &oldChild,
const SharedShadowNode &newChild,
int suggestedIndex) {
ensureUnsealed();
cloneChildrenIfShared();
auto nonConstChildren =
std::const_pointer_cast<SharedShadowNodeList>(children_);
if (suggestedIndex != -1 && suggestedIndex < nonConstChildren->size()) {
if (nonConstChildren->at(suggestedIndex) == oldChild) {
(*nonConstChildren)[suggestedIndex] = newChild;
return;
}
}
std::replace(
nonConstChildren->begin(), nonConstChildren->end(), oldChild, newChild);
}
void ShadowNode::setLocalData(const SharedLocalData &localData) {
ensureUnsealed();
localData_ = localData;
}
void ShadowNode::cloneChildrenIfShared() {
if (!childrenAreShared_) {
return;
}
childrenAreShared_ = false;
children_ = std::make_shared<SharedShadowNodeList>(*children_);
}
void ShadowNode::setMounted(bool mounted) const {
eventEmitter_->setEnabled(mounted);
if (mounted && state_) {
state_->commit(*this);
}
}
bool ShadowNode::constructAncestorPath(
const ShadowNode &ancestorShadowNode,
std::vector<std::reference_wrapper<const ShadowNode>> &ancestors) const {
// Note: We have a decent idea of how to make it reasonable performant.
// This is not implemented yet though. See T36620537 for more details.
if (this == &ancestorShadowNode) {
return true;
}
for (const auto &childShadowNode : *ancestorShadowNode.children_) {
if (constructAncestorPath(*childShadowNode, ancestors)) {
ancestors.push_back(std::ref(ancestorShadowNode));
return true;
}
}
return false;
}
#pragma mark - DebugStringConvertible
#if RN_DEBUG_STRING_CONVERTIBLE
std::string ShadowNode::getDebugName() const {
return getComponentName();
}
std::string ShadowNode::getDebugValue() const {
return "r" + folly::to<std::string>(revision_) +
(getSealed() ? "/sealed" : "");
}
SharedDebugStringConvertibleList ShadowNode::getDebugChildren() const {
auto debugChildren = SharedDebugStringConvertibleList{};
for (auto child : *children_) {
auto debugChild =
std::dynamic_pointer_cast<const DebugStringConvertible>(child);
if (debugChild) {
debugChildren.push_back(debugChild);
}
}
return debugChildren;
}
SharedDebugStringConvertibleList ShadowNode::getDebugProps() const {
return props_->getDebugProps() +
SharedDebugStringConvertibleList{
debugStringConvertibleItem("tag", folly::to<std::string>(tag_))};
}
#endif
} // namespace react
} // namespace facebook