mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
1e4ebf2531
Summary: Calculation of TransformedFrames was a method introduced by D37994809 (https://github.com/facebook/react-native/commit/64528e5faa445907b8287b412c344f30c20fca61) to fix rendering of inverted flat lists. We found that this operation is crashing in fb4a causing the UBN T127619309 This diff creates a feature flag to disable the calculation of TransformedFrames in Layoutable ShadowNodes. **The goal of this diff is to revert the behavior introduced by D37994809 (https://github.com/facebook/react-native/commit/64528e5faa445907b8287b412c344f30c20fca61)** The featureFlag is disabled in fb4a and enabled in react AR (because ReactAr apps relies on the calculation of TransformedFrames and these apps are not affected) The root cause of the bug will be fixed by D38280674 (which still requires more testing and investigation) changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D38286857 fbshipit-source-id: 721cd0554ae6a6b369b3f8dbb584160a270d0f18
245 lines
7.1 KiB
C++
245 lines
7.1 KiB
C++
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <butter/small_vector.h>
|
|
#include <react/renderer/core/EventEmitter.h>
|
|
#include <react/renderer/core/Props.h>
|
|
#include <react/renderer/core/ReactPrimitives.h>
|
|
#include <react/renderer/core/Sealable.h>
|
|
#include <react/renderer/core/ShadowNodeFamily.h>
|
|
#include <react/renderer/core/ShadowNodeTraits.h>
|
|
#include <react/renderer/core/State.h>
|
|
#include <react/renderer/debug/DebugStringConvertible.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
static constexpr const int kShadowNodeChildrenSmallVectorSize = 8;
|
|
|
|
class ComponentDescriptor;
|
|
struct ShadowNodeFragment;
|
|
|
|
class ShadowNode : public Sealable, public DebugStringConvertible {
|
|
public:
|
|
using Shared = std::shared_ptr<ShadowNode const>;
|
|
using Weak = std::weak_ptr<ShadowNode const>;
|
|
using Unshared = std::shared_ptr<ShadowNode>;
|
|
using ListOfShared =
|
|
butter::small_vector<Shared, kShadowNodeChildrenSmallVectorSize>;
|
|
using ListOfWeak =
|
|
butter::small_vector<Weak, kShadowNodeChildrenSmallVectorSize>;
|
|
using SharedListOfShared = std::shared_ptr<ListOfShared const>;
|
|
using UnsharedListOfShared = std::shared_ptr<ListOfShared>;
|
|
using UnsharedListOfWeak = std::shared_ptr<ListOfWeak>;
|
|
|
|
using AncestorList = butter::small_vector<
|
|
std::pair<
|
|
std::reference_wrapper<ShadowNode const> /* parentNode */,
|
|
int /* childIndex */>,
|
|
64>;
|
|
|
|
static SharedListOfShared emptySharedShadowNodeSharedList();
|
|
|
|
/*
|
|
* Returns `true` if nodes belong to the same family (they were cloned one
|
|
* from each other or from the same source node).
|
|
*/
|
|
static bool sameFamily(const ShadowNode &first, const ShadowNode &second);
|
|
|
|
/*
|
|
* A set of traits associated with a particular class.
|
|
* Reimplement in subclasses to declare class-specific traits.
|
|
*/
|
|
static ShadowNodeTraits BaseTraits() {
|
|
return ShadowNodeTraits{};
|
|
}
|
|
|
|
#pragma mark - Constructors
|
|
|
|
/*
|
|
* Creates a Shadow Node based on fields specified in a `fragment`.
|
|
*/
|
|
ShadowNode(
|
|
ShadowNodeFragment const &fragment,
|
|
ShadowNodeFamily::Shared family,
|
|
ShadowNodeTraits traits);
|
|
|
|
/*
|
|
* Creates a Shadow Node via cloning given `sourceShadowNode` and
|
|
* applying fields from given `fragment`.
|
|
* Note: `tag`, `surfaceId`, and `eventEmitter` cannot be changed.
|
|
*/
|
|
ShadowNode(
|
|
const ShadowNode &sourceShadowNode,
|
|
const ShadowNodeFragment &fragment);
|
|
|
|
/*
|
|
* Not copyable.
|
|
*/
|
|
ShadowNode(ShadowNode const &shadowNode) noexcept = delete;
|
|
ShadowNode &operator=(ShadowNode const &other) noexcept = delete;
|
|
|
|
virtual ~ShadowNode() = default;
|
|
|
|
/*
|
|
* Clones the shadow node using stored `cloneFunction`.
|
|
*/
|
|
Unshared clone(const ShadowNodeFragment &fragment) const;
|
|
|
|
/*
|
|
* Clones the node (and partially the tree starting from the node) by
|
|
* replacing a `oldShadowNode` (which corresponds to a given
|
|
* `shadowNodeFamily`) with a node that `callback` returns.
|
|
*
|
|
* Returns `nullptr` if the operation cannot be performed successfully.
|
|
*/
|
|
Unshared cloneTree(
|
|
ShadowNodeFamily const &shadowNodeFamily,
|
|
std::function<Unshared(ShadowNode const &oldShadowNode)> const &callback)
|
|
const;
|
|
|
|
#pragma mark - Getters
|
|
|
|
ComponentName getComponentName() const;
|
|
ComponentHandle getComponentHandle() const;
|
|
|
|
/*
|
|
* Returns a stored traits.
|
|
*/
|
|
ShadowNodeTraits getTraits() const;
|
|
|
|
Props::Shared const &getProps() const;
|
|
ListOfShared const &getChildren() const;
|
|
SharedEventEmitter const &getEventEmitter() const;
|
|
Tag getTag() const;
|
|
SurfaceId getSurfaceId() const;
|
|
|
|
/*
|
|
* Returns a concrete `ComponentDescriptor` that manages nodes of this type.
|
|
*/
|
|
const ComponentDescriptor &getComponentDescriptor() const;
|
|
|
|
/*
|
|
* Returns the `ContextContainer` used by this ShadowNode.
|
|
*/
|
|
ContextContainer::Shared getContextContainer() const;
|
|
|
|
/*
|
|
* Returns a state associated with the particular node.
|
|
*/
|
|
const State::Shared &getState() const;
|
|
|
|
/*
|
|
* Returns a momentary value of the most recently created or committed state
|
|
* associated with a family of nodes which this node belongs to.
|
|
* Sequential calls might return different values.
|
|
* The method may return null pointer in case if the particular `ShadowNode`
|
|
* does not use `State`.
|
|
*/
|
|
State::Shared getMostRecentState() const;
|
|
|
|
/*
|
|
* Returns a number that specifies the order of the node.
|
|
* A view generated from a node with a greater order index is placed before a
|
|
* view generated from a node with a lower order index.
|
|
*/
|
|
int getOrderIndex() const;
|
|
|
|
void sealRecursive() const;
|
|
|
|
ShadowNodeFamily const &getFamily() const;
|
|
|
|
#pragma mark - Mutating Methods
|
|
|
|
void appendChild(Shared const &child);
|
|
void replaceChild(
|
|
ShadowNode const &oldChild,
|
|
Shared const &newChild,
|
|
int suggestedIndex = -1);
|
|
|
|
/*
|
|
* Performs all side effects associated with mounting/unmounting in one place.
|
|
* This is not `virtual` on purpose, do not override this.
|
|
* `EventEmitter::DispatchMutex()` must be acquired before calling.
|
|
*/
|
|
void setMounted(bool mounted) const;
|
|
|
|
#pragma mark - DebugStringConvertible
|
|
|
|
#if RN_DEBUG_STRING_CONVERTIBLE
|
|
std::string getDebugName() const override;
|
|
std::string getDebugValue() const override;
|
|
SharedDebugStringConvertibleList getDebugChildren() const override;
|
|
SharedDebugStringConvertibleList getDebugProps() const override;
|
|
|
|
/*
|
|
* A number of the generation of the ShadowNode instance;
|
|
* is used and useful for debug-printing purposes *only*.
|
|
* Do not access this value in any circumstances.
|
|
*/
|
|
int const revision_;
|
|
#endif
|
|
|
|
protected:
|
|
Props::Shared props_;
|
|
SharedListOfShared children_;
|
|
State::Shared state_;
|
|
int orderIndex_;
|
|
|
|
private:
|
|
friend ShadowNodeFamily;
|
|
|
|
/*
|
|
* Clones the list of children (and creates a new `shared_ptr` to it) if
|
|
* `childrenAreShared_` flag is `true`.
|
|
*/
|
|
void cloneChildrenIfShared();
|
|
|
|
/*
|
|
* Pointer to a family object that this shadow node belongs to.
|
|
*/
|
|
ShadowNodeFamily::Shared family_;
|
|
|
|
mutable std::atomic<bool> hasBeenMounted_{false};
|
|
|
|
static Props::Shared propsForClonedShadowNode(
|
|
ShadowNode const &sourceShadowNode,
|
|
Props::Shared const &props);
|
|
|
|
protected:
|
|
/*
|
|
* Traits associated with the particular `ShadowNode` class and an instance of
|
|
* that class.
|
|
*/
|
|
ShadowNodeTraits traits_;
|
|
};
|
|
|
|
/*
|
|
* Template declarations for future specializations in concrete classes.
|
|
* `traitCast` checks for a trait that corresponds to the provided type and
|
|
* performs `static_cast`. Practically, the behavior is identical to
|
|
* `dynamic_cast` with very little runtime overhead.
|
|
*/
|
|
template <typename ShadowNodeReferenceT>
|
|
ShadowNodeReferenceT traitCast(ShadowNode const &shadowNode);
|
|
|
|
template <typename ShadowNodePointerT>
|
|
ShadowNodePointerT traitCast(ShadowNode const *shadowNode);
|
|
|
|
template <typename ShadowNodePointerT>
|
|
std::shared_ptr<ShadowNodePointerT const> traitCast(
|
|
std::shared_ptr<ShadowNode const> shadowNode);
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|