mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
c22b874fd6
Summary: Previously, `ShadowViewNodePair::List` owned each `ShadowViewNodePair` but whenever we put `ShadowViewNodePair` into a TinyMap, those were unowned pointer references. This worked... 99% of the time. But in some marginal cases, it would cause dangling pointers, leading to difficult-to-track-down issues. So, I'm moving both of these to be unowned pointers and keeping a `std::deque` that owns all `ShadowViewNodePair`s and is itself owned by the main differ function. See comments for more implementation details. I'm moderately concerned about memory usage regressions, but practically speaking this will contain many items when a tree is created for the first time, and then very few items after that (space complexity should be similar to `O(n)` where `n` is the number of changed nodes after the last diff). See comments as to why I believe `std::deque` is the right choice. Long-term there might be data-structures that are even more optimal, but std::deque has the right tradeoffs compared to other built-in STL structures like std::list and std::vector, and is probably better than std::forward_list too. Long-term we may want a custom data-structure that fits our needs exactly, but std::deque comes close and is possibly optimal. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D27730952 fbshipit-source-id: 2194b535439bd309803a221188da5db75242005a
98 lines
2.9 KiB
C++
98 lines
2.9 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 "ShadowView.h"
|
|
|
|
#include <react/renderer/core/LayoutMetrics.h>
|
|
#include <react/renderer/core/LayoutableShadowNode.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
static LayoutMetrics layoutMetricsFromShadowNode(ShadowNode const &shadowNode) {
|
|
auto layoutableShadowNode =
|
|
traitCast<LayoutableShadowNode const *>(&shadowNode);
|
|
return layoutableShadowNode ? layoutableShadowNode->getLayoutMetrics()
|
|
: EmptyLayoutMetrics;
|
|
}
|
|
|
|
ShadowView::ShadowView(const ShadowNode &shadowNode)
|
|
: componentName(shadowNode.getComponentName()),
|
|
componentHandle(shadowNode.getComponentHandle()),
|
|
surfaceId(shadowNode.getSurfaceId()),
|
|
tag(shadowNode.getTag()),
|
|
props(shadowNode.getProps()),
|
|
eventEmitter(shadowNode.getEventEmitter()),
|
|
layoutMetrics(layoutMetricsFromShadowNode(shadowNode)),
|
|
state(shadowNode.getState()) {}
|
|
|
|
bool ShadowView::operator==(const ShadowView &rhs) const {
|
|
return std::tie(
|
|
this->surfaceId,
|
|
this->tag,
|
|
this->componentName,
|
|
this->props,
|
|
this->eventEmitter,
|
|
this->layoutMetrics,
|
|
this->state) ==
|
|
std::tie(
|
|
rhs.surfaceId,
|
|
rhs.tag,
|
|
rhs.componentName,
|
|
rhs.props,
|
|
rhs.eventEmitter,
|
|
rhs.layoutMetrics,
|
|
rhs.state);
|
|
}
|
|
|
|
bool ShadowView::operator!=(const ShadowView &rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
#ifdef RN_DEBUG_STRING_CONVERTIBLE
|
|
|
|
std::string getDebugName(ShadowView const &object) {
|
|
return object.componentHandle == 0 ? "Invalid" : object.componentName;
|
|
}
|
|
|
|
std::vector<DebugStringConvertibleObject> getDebugProps(
|
|
ShadowView const &object,
|
|
DebugStringConvertibleOptions options) {
|
|
return {
|
|
{"surfaceId", getDebugDescription(object.surfaceId, options)},
|
|
{"tag", getDebugDescription(object.tag, options)},
|
|
{"componentName", object.componentName},
|
|
{"props", getDebugDescription(object.props, options)},
|
|
{"eventEmitter", getDebugDescription(object.eventEmitter, options)},
|
|
{"layoutMetrics", getDebugDescription(object.layoutMetrics, options)},
|
|
{"state", getDebugDescription(object.state, options)},
|
|
};
|
|
}
|
|
|
|
#endif
|
|
|
|
bool ShadowViewNodePair::operator==(const ShadowViewNodePair &rhs) const {
|
|
return this->shadowNode == rhs.shadowNode;
|
|
}
|
|
|
|
bool ShadowViewNodePair::operator!=(const ShadowViewNodePair &rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
bool ShadowViewNodePairLegacy::operator==(
|
|
const ShadowViewNodePairLegacy &rhs) const {
|
|
return this->shadowNode == rhs.shadowNode;
|
|
}
|
|
|
|
bool ShadowViewNodePairLegacy::operator!=(
|
|
const ShadowViewNodePairLegacy &rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|