• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_VIEW_STACK_PROCESSOR_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_VIEW_STACK_PROCESSOR_H
18 
19 #include <memory>
20 #include <stack>
21 #include <unordered_map>
22 #include <vector>
23 
24 #include "base/memory/referenced.h"
25 #include "core/components/common/properties/animation_option.h"
26 #include "core/components_ng/base/frame_node.h"
27 #include "core/components_ng/base/ui_node.h"
28 #include "core/components_ng/event/state_style_manager.h"
29 #include "core/components_ng/layout/layout_property.h"
30 #include "core/components_ng/pattern/custom/custom_node.h"
31 #include "core/gestures/gesture_processor.h"
32 #include "core/pipeline/base/render_context.h"
33 
34 #define ACE_UPDATE_LAYOUT_PROPERTY(target, name, value)                         \
35     do {                                                                        \
36         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
37         CHECK_NULL_VOID(frameNode);                                             \
38         auto cast##target = frameNode->GetLayoutProperty<target>();             \
39         if (cast##target) {                                                     \
40             cast##target->Update##name(value);                                  \
41         }                                                                       \
42     } while (false)
43 #define ACE_UPDATE_PAINT_PROPERTY(target, name, value)                          \
44     do {                                                                        \
45         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
46         CHECK_NULL_VOID(frameNode);                                             \
47         auto cast##target = frameNode->GetPaintProperty<target>();              \
48         if (cast##target) {                                                     \
49             cast##target->Update##name(value);                                  \
50         }                                                                       \
51     } while (false)
52 
53 #define ACE_UPDATE_RENDER_CONTEXT(name, value)                                  \
54     do {                                                                        \
55         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
56         CHECK_NULL_VOID(frameNode);                                             \
57         auto target = frameNode->GetRenderContext();                            \
58         if (target) {                                                           \
59             target->Update##name(value);                                        \
60         }                                                                       \
61     } while (false)
62 
63 #define ACE_RESET_LAYOUT_PROPERTY(target, name)                                 \
64     do {                                                                        \
65         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
66         CHECK_NULL_VOID(frameNode);                                             \
67         auto cast##target = frameNode->GetLayoutProperty<target>();             \
68         CHECK_NULL_VOID(cast##target);                                          \
69         cast##target->Reset##name();                                            \
70     } while (false)
71 
72 #define ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(target, name, changeFlag)           \
73     do {                                                                        \
74         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
75         CHECK_NULL_VOID(frameNode);                                             \
76         auto cast##target = frameNode->GetLayoutProperty<target>();             \
77         CHECK_NULL_VOID(cast##target);                                          \
78         if (cast##target->Has##name()) {                                        \
79             cast##target->Reset##name();                                        \
80             cast##target->UpdatePropertyChangeFlag(changeFlag);                 \
81         }                                                                       \
82     } while (false)
83 
84 #define ACE_RESET_PAINT_PROPERTY(target, name)                                  \
85     do {                                                                        \
86         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
87         CHECK_NULL_VOID(frameNode);                                             \
88         auto cast##target = frameNode->GetPaintProperty<target>();              \
89         CHECK_NULL_VOID(cast##target);                                          \
90         cast##target->Reset##name();                                            \
91     } while (false)
92 
93 #define ACE_RESET_PAINT_PROPERTY_WITH_FLAG(target, name, changeFlag)            \
94     do {                                                                        \
95         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
96         CHECK_NULL_VOID(frameNode);                                             \
97         auto cast##target = frameNode->GetPaintProperty<target>();              \
98         CHECK_NULL_VOID(cast##target);                                          \
99         cast##target->Reset##name();                                            \
100         cast##target->UpdatePropertyChangeFlag(changeFlag);                     \
101     } while (false)
102 
103 #define ACE_RESET_RENDER_CONTEXT(target, name)                                  \
104     do {                                                                        \
105         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
106         CHECK_NULL_VOID(frameNode);                                             \
107         auto cast##target = frameNode->GetRenderContext();                      \
108         CHECK_NULL_VOID(cast##target);                                          \
109         cast##target->Reset##name();                                            \
110     } while (false)
111 
112 namespace OHOS::Ace::NG {
113 class ACE_EXPORT ViewStackProcessor final {
114 public:
115     friend class ScopedViewStackProcessor;
116 
117     ACE_FORCE_EXPORT static ViewStackProcessor* GetInstance();
118     ~ViewStackProcessor() = default;
119 
120     template<typename Pattern>
GetMainFrameNodePattern()121     RefPtr<Pattern> GetMainFrameNodePattern() const
122     {
123         auto frameNode = GetMainFrameNode();
124         if (!frameNode) {
125             return nullptr;
126         }
127         return AceType::DynamicCast<Pattern>(frameNode->GetPattern());
128     }
129 
130     template<typename EventHubType>
GetMainFrameNodeEventHub()131     RefPtr<EventHubType> GetMainFrameNodeEventHub() const
132     {
133         auto frameNode = GetMainFrameNode();
134         if (!frameNode) {
135             return nullptr;
136         }
137         return frameNode->GetEventHub<EventHubType>();
138     }
139 
GetMainFrameNodeGestureEventHub()140     RefPtr<GestureEventHub> GetMainFrameNodeGestureEventHub() const
141     {
142         auto frameNode = GetMainFrameNode();
143         if (!frameNode) {
144             return nullptr;
145         }
146         return frameNode->GetOrCreateGestureEventHub();
147     }
148 
GetMainFrameNodeInputEventHub()149     RefPtr<InputEventHub> GetMainFrameNodeInputEventHub() const
150     {
151         auto frameNode = GetMainFrameNode();
152         if (!frameNode) {
153             return nullptr;
154         }
155         return frameNode->GetOrCreateInputEventHub();
156     }
157 
GetOrCreateMainFrameNodeFocusHub()158     RefPtr<FocusHub> GetOrCreateMainFrameNodeFocusHub() const
159     {
160         auto frameNode = GetMainFrameNode();
161         if (!frameNode) {
162             return nullptr;
163         }
164         return frameNode->GetOrCreateFocusHub();
165     }
166 
GetMainFrameNodeFocusHub()167     RefPtr<FocusHub> GetMainFrameNodeFocusHub() const
168     {
169         auto frameNode = GetMainFrameNode();
170         if (!frameNode) {
171             return nullptr;
172         }
173         return frameNode->GetFocusHub();
174     }
175 
176     ACE_FORCE_EXPORT RefPtr<FrameNode> GetMainFrameNode() const;
177 
178     // Get main component include composed component created by js view.
179     RefPtr<UINode> GetMainElementNode() const;
180 
181     // create wrappingComponentsMap and the component to map and then Push
182     // the map to the render component stack.
183     ACE_FORCE_EXPORT void Push(const RefPtr<UINode>& element, bool isCustomView = false);
184 
185     // Wrap the components map for the stack top and then pop the stack.
186     // Add the wrapped component has child of the new stack top's main component.
187     void Pop();
188 
189     // pop the last container
190     void PopContainer();
191 
192     // End of Render function, create component tree and flush modify task.
193     RefPtr<UINode> Finish();
194 
195     // Set key to be used for next node on the stack
196     void PushKey(const std::string& key);
197 
198     // Returns a key for the node if it has been pushed to the stack. Default is ""
199     std::string GetKey();
200 
201     // Takes care of the viewId wrt to foreach
202     std::string ProcessViewId(const std::string& viewId);
203 
204     // Clear the key pushed to the stack
205     void PopKey();
206 
207     // Prevent predict mark dirty when creating predict node
SetPredict(RefPtr<UINode> predictNode)208     void SetPredict(RefPtr<UINode> predictNode)
209     {
210         predictNode_ = predictNode;
211     }
212 
ResetPredict()213     void ResetPredict() {
214         predictNode_.Reset();
215     }
216 
217     // Check whether the current node is in the corresponding polymorphic style state.
218     // When the polymorphic style is not set on the front end, it returns true regardless of the current node state;
219     // When the polymorphic style is set on the front end, true is returned only if the current node state is the same
220     // as the polymorphic style.
221     bool IsCurrentVisualStateProcess();
222 
223     void SetVisualState(VisualState state);
224 
GetVisualState()225     std::optional<UIState> GetVisualState() const
226     {
227         return visualState_;
228     }
229 
IsVisualStateSet()230     bool IsVisualStateSet()
231     {
232         return visualState_.has_value();
233     }
234 
ClearVisualState()235     void ClearVisualState()
236     {
237         visualState_.reset();
238     }
239 
ClearStack()240     void ClearStack()
241     {
242         auto emptyStack = std::stack<RefPtr<UINode>>();
243         elementsStack_.swap(emptyStack);
244     }
245 
GetOrCreateGestureProcessor()246     RefPtr<GestureProcessor> GetOrCreateGestureProcessor()
247     {
248         if (!gestureStack_) {
249             gestureStack_ = AceType::MakeRefPtr<GestureProcessor>();
250         }
251         return gestureStack_;
252     }
253 
ResetGestureProcessor()254     void ResetGestureProcessor()
255     {
256         return gestureStack_.Reset();
257     }
258 
259     /**
260      * when nesting observeComponentCreation functions, such as in the case of
261      * If, and the if branch creates a Text etc that requires an implicit pop
262      * this function is needed after executing the inner observeComponentCreation
263      * and before read ViewStackProcessor.GetTopMostElementId(); on the outer one
264      */
265     void ImplicitPopBeforeContinue();
266 
267     // End of Rerender function, flush modifier task.
268     void FlushRerenderTask();
269 
270     /**
271      * start 'get' access recording
272      * account all get access to given node id
273      * next node creation will claim the given node id
274      * see ClaimNodeId()
275      */
StartGetAccessRecordingFor(int32_t elmtId)276     void StartGetAccessRecordingFor(int32_t elmtId)
277     {
278         accountGetAccessToNodeId_ = elmtId;
279         reservedNodeId_ = elmtId;
280     }
281 
ClaimNodeId()282     int32_t ClaimNodeId()
283     {
284         const auto result = reservedNodeId_;
285         reservedNodeId_ = ElementRegister::UndefinedElementId;
286         return result;
287     }
288 
289     /**
290      * get the elmtId to which all get access should be accounted
291      * ElementRegister::UndefinedElementId; means no get access recording enabled
292      */
GetNodeIdToAccountFor()293     ElementIdType GetNodeIdToAccountFor() const
294     {
295         return accountGetAccessToNodeId_;
296     }
SetNodeIdToAccountFor(ElementIdType elmtId)297     void SetNodeIdToAccountFor(ElementIdType elmtId)
298     {
299         accountGetAccessToNodeId_ = elmtId;
300     }
301 
302     /**
303      * inverse of StartGetAccessRecordingFor
304      */
StopGetAccessRecording()305     void StopGetAccessRecording()
306     {
307         accountGetAccessToNodeId_ = ElementRegister::UndefinedElementId;
308         reservedNodeId_ = ElementRegister::UndefinedElementId;
309     }
310 
311     void FlushImplicitAnimation();
312 
313     // used for knowing which page node to execute the pageTransitionFunc
SetPageNode(const RefPtr<FrameNode> & pageNode)314     void SetPageNode(const RefPtr<FrameNode>& pageNode)
315     {
316         currentPage_ = pageNode;
317     }
318 
GetPageNode()319     const RefPtr<FrameNode>& GetPageNode() const
320     {
321         return currentPage_;
322     }
323 
324     // Sets the implicit animation option. This is needed for 3D Model View.
325     void SetImplicitAnimationOption(const AnimationOption& option);
326 
327     // Returns implicit animation option.
328     const AnimationOption& GetImplicitAnimationOption() const;
329 
330     RefPtr<UINode> GetNewUINode();
331 
GetAndPushFrameNode(const std::string & tag,int32_t elmtId)332     void GetAndPushFrameNode(const std::string& tag, int32_t elmtId)
333     {
334         LOGD("NG ViewStackProcessor GetAndPushFrameNode() tag: %s, elmtId: %d", tag.c_str(), elmtId);
335         auto frameNode = FrameNode::GetFrameNode(tag, elmtId);
336         if (!frameNode) {
337             LOGE("GetFrameNode feild, tag: %s, elmtId: %d", tag.c_str(), elmtId);
338             return;
339         }
340         Push(frameNode);
341     }
342 
343 private:
344     ViewStackProcessor();
345 
346     bool ShouldPopImmediately();
347 
348     // Singleton instance
349     static thread_local std::unique_ptr<ViewStackProcessor> instance;
350 
351     // render component stack
352     std::stack<RefPtr<UINode>> elementsStack_;
353 
354     RefPtr<FrameNode> currentPage_;
355 
356     RefPtr<GestureProcessor> gestureStack_;
357 
358     std::string viewKey_;
359     std::stack<size_t> keyStack_;
360 
361     RefPtr<UINode> predictNode_;
362 
363     std::stack<int32_t> parentIdStack_;
364 
365     std::optional<UIState> visualState_ = std::nullopt;
366 
367     // elmtId reserved for next component creation
368     ElementIdType reservedNodeId_ = ElementRegister::UndefinedElementId;
369 
370     // elmtId to account get access to
371     ElementIdType accountGetAccessToNodeId_ = ElementRegister::UndefinedElementId;
372 
373     AnimationOption implicitAnimationOption_;
374 
375     ACE_DISALLOW_COPY_AND_MOVE(ViewStackProcessor);
376 };
377 
378 class ACE_EXPORT ScopedViewStackProcessor final {
379 public:
380     ScopedViewStackProcessor();
381     ~ScopedViewStackProcessor();
382 
383 private:
384     std::unique_ptr<ViewStackProcessor> instance_;
385 
386     ACE_DISALLOW_COPY_AND_MOVE(ScopedViewStackProcessor);
387 };
388 } // namespace OHOS::Ace::NG
389 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_VIEW_STACK_PROCESSOR_H
390