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