1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8 #pragma once 9 10 #include <memory> 11 #include <shared_mutex> 12 13 #include <ABI49_0_0butter/ABI49_0_0small_vector.h> 14 15 #include <ABI49_0_0React/renderer/core/ABI49_0_0EventEmitter.h> 16 #include <ABI49_0_0React/renderer/core/ABI49_0_0ReactPrimitives.h> 17 #include <ABI49_0_0React/renderer/core/ABI49_0_0ShadowNodeFamilyFragment.h> 18 19 namespace ABI49_0_0facebook { 20 namespace ABI49_0_0React { 21 22 class ComponentDescriptor; 23 class ShadowNode; 24 class State; 25 26 /* 27 * Represents all things that shadow nodes from the same family have in common. 28 * To be used inside `ShadowNode` class *only*. 29 */ 30 class ShadowNodeFamily final { 31 public: 32 using Shared = std::shared_ptr<ShadowNodeFamily const>; 33 using Weak = std::weak_ptr<ShadowNodeFamily const>; 34 35 using AncestorList = butter::small_vector< 36 std::pair< 37 std::reference_wrapper<ShadowNode const> /* parentNode */, 38 int /* childIndex */>, 39 64>; 40 41 ShadowNodeFamily( 42 ShadowNodeFamilyFragment const &fragment, 43 EventDispatcher::Weak eventDispatcher, 44 ComponentDescriptor const &componentDescriptor); 45 46 /* 47 * Sets the parent. 48 * This is not technically thread-safe, but practically it mutates the object 49 * only once (and the model enforces that this first call is not concurrent). 50 */ 51 void setParent(ShadowNodeFamily::Shared const &parent) const; 52 53 /* 54 * Returns a handle (or name) associated with the component. 55 */ 56 ComponentHandle getComponentHandle() const; 57 ComponentName getComponentName() const; 58 59 /* 60 * Returns a concrete `ComponentDescriptor` that manages nodes of this type. 61 */ 62 const ComponentDescriptor &getComponentDescriptor() const; 63 64 /* 65 * Returns a list of all ancestors of the node relative to the given ancestor. 66 * The list starts from the given ancestor node and ends with the parent node 67 * of `this` node. The elements of the list have a reference to some parent 68 * node and an index of the child of the parent node. 69 * Returns an empty array if there is no ancestor-descendant relationship. 70 * Can be called from any thread. 71 * The theoretical complexity of the algorithm is `O(ln(n))`. Use it wisely. 72 */ 73 AncestorList getAncestors(ShadowNode const &ancestorShadowNode) const; 74 75 SurfaceId getSurfaceId() const; 76 77 /* 78 * Sets and gets the most recent state. 79 */ 80 std::shared_ptr<State const> getMostRecentState() const; 81 void setMostRecentState(std::shared_ptr<State const> const &state) const; 82 83 /* 84 * Dispatches a state update with given priority. 85 */ 86 void dispatchRawState(StateUpdate &&stateUpdate, EventPriority priority) 87 const; 88 89 /* 90 * Holds currently applied native props. `nullptr` if setNativeProps API is 91 * not used. It is used to backport setNativeProps API from the old 92 * architecture and will be removed in the future. 93 */ 94 mutable std::unique_ptr<folly::dynamic> nativeProps_DEPRECATED; 95 96 private: 97 friend ShadowNode; 98 friend ShadowNodeFamilyFragment; 99 friend State; 100 101 /* 102 * Returns the most recent state if the given `state` is obsolete, 103 * otherwise returns `nullptr`. 104 * To be used by `State` only. 105 */ 106 std::shared_ptr<State const> getMostRecentStateIfObsolete( 107 State const &state) const; 108 109 EventDispatcher::Weak eventDispatcher_; 110 mutable std::shared_ptr<State const> mostRecentState_; 111 mutable std::shared_mutex mutex_; 112 113 /* 114 * Deprecated. 115 */ 116 Tag const tag_; 117 118 /* 119 * Identifier of a running Surface instance. 120 */ 121 SurfaceId const surfaceId_; 122 123 /* 124 * `EventEmitter` associated with all nodes of the family. 125 */ 126 SharedEventEmitter const eventEmitter_; 127 128 /* 129 * Reference to a concrete `ComponentDescriptor` that manages nodes of this 130 * type. 131 */ 132 ComponentDescriptor const &componentDescriptor_; 133 134 /* 135 * ComponentHandle and ComponentName must be stored (cached) inside the object 136 * to allow retrieving these values without accessing a `ComponentDescriptor` 137 * object (because it can be already deallocated). 138 */ 139 ComponentHandle componentHandle_; 140 ComponentName componentName_; 141 142 /* 143 * Points to a family of all parent nodes of all nodes of the family. 144 */ 145 mutable ShadowNodeFamily::Weak parent_{}; 146 147 /* 148 * Represents a case where `parent_` is `nullptr`. 149 * For optimization purposes only. 150 */ 151 mutable bool hasParent_{false}; 152 }; 153 154 } // namespace ABI49_0_0React 155 } // namespace ABI49_0_0facebook 156