• 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/gestures/gesture_processor.h"
31 #include "core/pipeline/base/render_context.h"
32 
33 #define ACE_UPDATE_LAYOUT_PROPERTY(target, name, value)                         \
34     do {                                                                        \
35         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
36         ACE_UPDATE_NODE_LAYOUT_PROPERTY(target, name, value, frameNode);        \
37     } while (false)
38 #define ACE_UPDATE_NODE_LAYOUT_PROPERTY(target, name, value, frameNode)         \
39     do {                                                                        \
40         CHECK_NULL_VOID(frameNode);                                             \
41         auto cast##target = frameNode->GetLayoutProperty<target>();             \
42         if (cast##target) {                                                     \
43             cast##target->Update##name(value);                                  \
44         }                                                                       \
45     } while (false)
46 
47 #define ACE_UPDATE_PAINT_PROPERTY(target, name, value)                          \
48     do {                                                                        \
49         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
50         ACE_UPDATE_NODE_PAINT_PROPERTY(target, name, value, frameNode);         \
51     } while (false)
52 #define ACE_UPDATE_NODE_PAINT_PROPERTY(target, name, value, frameNode)          \
53     do {                                                                        \
54         CHECK_NULL_VOID(frameNode);                                             \
55         auto cast##target = frameNode->GetPaintProperty<target>();              \
56         if (cast##target) {                                                     \
57             cast##target->Update##name(value);                                  \
58         }                                                                       \
59     } while (false)
60 
61 #define ACE_UPDATE_RENDER_CONTEXT(name, value)                                  \
62     do {                                                                        \
63         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
64         ACE_UPDATE_NODE_RENDER_CONTEXT(name, value, frameNode);                 \
65     } while (false)
66 #define ACE_UPDATE_NODE_RENDER_CONTEXT(name, value, frameNode)                  \
67     do {                                                                        \
68         CHECK_NULL_VOID(frameNode);                                             \
69         const auto& target = frameNode->GetRenderContext();                     \
70         if (target) {                                                           \
71             target->Update##name(value);                                        \
72         }                                                                       \
73     } while (false)
74 
75 #define ACE_RESET_LAYOUT_PROPERTY(target, name)                                 \
76     do {                                                                        \
77         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
78         ACE_RESET_NODE_LAYOUT_PROPERTY(target, name, frameNode);                \
79     } while (false)
80 #define ACE_RESET_NODE_LAYOUT_PROPERTY(target, name, frameNode)                 \
81     do {                                                                        \
82         CHECK_NULL_VOID(frameNode);                                             \
83         auto cast##target = frameNode->GetLayoutProperty<target>();             \
84         CHECK_NULL_VOID(cast##target);                                          \
85         cast##target->Reset##name();                                            \
86     } while (false)
87 
88 #define ACE_RESET_LAYOUT_PROPERTY_WITH_FLAG(target, name, changeFlag)                      \
89     do {                                                                                   \
90         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();            \
91         ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(target, name, changeFlag, frameNode);     \
92     } while (false)
93 #define ACE_RESET_NODE_LAYOUT_PROPERTY_WITH_FLAG(target, name, changeFlag, frameNode)      \
94     do {                                                                                   \
95         CHECK_NULL_VOID(frameNode);                                                        \
96         auto cast##target = frameNode->GetLayoutProperty<target>();                        \
97         CHECK_NULL_VOID(cast##target);                                                     \
98         if (cast##target->Has##name()) {                                                   \
99             cast##target->Reset##name();                                                   \
100             cast##target->UpdatePropertyChangeFlag(changeFlag);                            \
101         }                                                                                  \
102     } while (false)
103 
104 #define ACE_RESET_PAINT_PROPERTY(target, name)                                  \
105     do {                                                                        \
106         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
107         ACE_RESET_NODE_PAINT_PROPERTY(target, name, frameNode);                 \
108     } while (false)
109 #define ACE_RESET_NODE_PAINT_PROPERTY(target, name, frameNode)                  \
110     do {                                                                        \
111         CHECK_NULL_VOID(frameNode);                                             \
112         auto cast##target = frameNode->GetPaintProperty<target>();              \
113         CHECK_NULL_VOID(cast##target);                                          \
114         cast##target->Reset##name();                                            \
115     } while (false)
116 
117 #define ACE_RESET_PAINT_PROPERTY_WITH_FLAG(target, name, changeFlag)                      \
118     do {                                                                                  \
119         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();           \
120         ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG(target, name, changeFlag, frameNode);     \
121     } while (false)
122 #define ACE_RESET_NODE_PAINT_PROPERTY_WITH_FLAG(target, name, changeFlag, frameNode)      \
123     do {                                                                                  \
124         CHECK_NULL_VOID(frameNode);                                                       \
125         auto cast##target = frameNode->GetPaintProperty<target>();                        \
126         CHECK_NULL_VOID(cast##target);                                                    \
127         cast##target->Reset##name();                                                      \
128         cast##target->UpdatePropertyChangeFlag(changeFlag);                               \
129     } while (false)
130 
131 #define ACE_RESET_RENDER_CONTEXT(target, name)                                  \
132     do {                                                                        \
133         auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); \
134         ACE_RESET_NODE_RENDER_CONTEXT(target, name, frameNode);                 \
135     } while (false)
136 #define ACE_RESET_NODE_RENDER_CONTEXT(target, name, frameNode)                  \
137     do {                                                                        \
138         CHECK_NULL_VOID(frameNode);                                             \
139         auto cast##target = frameNode->GetRenderContext();                      \
140         CHECK_NULL_VOID(cast##target);                                          \
141         cast##target->Reset##name();                                            \
142     } while (false)
143 
144 namespace OHOS::Ace::NG {
145 class ACE_EXPORT ViewStackProcessor final {
146 public:
147     friend class ScopedViewStackProcessor;
148 
149     ACE_FORCE_EXPORT static ViewStackProcessor* GetInstance();
150     ~ViewStackProcessor() = default;
151 
152     template<typename Pattern>
GetMainFrameNodePattern()153     RefPtr<Pattern> GetMainFrameNodePattern() const
154     {
155         auto frameNode = GetMainFrameNode();
156         if (!frameNode) {
157             return nullptr;
158         }
159         return AceType::DynamicCast<Pattern>(frameNode->GetPattern());
160     }
161 
162     template<typename Pattern>
GetMainFrameNodePattern(FrameNode * frameNode)163     RefPtr<Pattern> GetMainFrameNodePattern(FrameNode* frameNode) const
164     {
165         if (!frameNode) {
166             return nullptr;
167         }
168         return AceType::DynamicCast<Pattern>(frameNode->GetPattern());
169     }
170 
171     template<typename EventHubType>
GetMainFrameNodeEventHub()172     RefPtr<EventHubType> GetMainFrameNodeEventHub() const
173     {
174         auto frameNode = GetMainFrameNode();
175         if (!frameNode) {
176             return nullptr;
177         }
178         return frameNode->GetEventHub<EventHubType>();
179     }
180 
GetMainFrameNodeGestureEventHub()181     RefPtr<GestureEventHub> GetMainFrameNodeGestureEventHub() const
182     {
183         auto frameNode = GetMainFrameNode();
184         if (!frameNode) {
185             return nullptr;
186         }
187         return frameNode->GetOrCreateGestureEventHub();
188     }
189 
GetMainFrameNodeInputEventHub()190     RefPtr<InputEventHub> GetMainFrameNodeInputEventHub() const
191     {
192         auto frameNode = GetMainFrameNode();
193         if (!frameNode) {
194             return nullptr;
195         }
196         return frameNode->GetOrCreateInputEventHub();
197     }
198 
GetOrCreateMainFrameNodeFocusHub()199     RefPtr<FocusHub> GetOrCreateMainFrameNodeFocusHub() const
200     {
201         auto frameNode = GetMainFrameNode();
202         if (!frameNode) {
203             return nullptr;
204         }
205         return frameNode->GetOrCreateFocusHub();
206     }
207 
GetMainFrameNodeFocusHub()208     RefPtr<FocusHub> GetMainFrameNodeFocusHub() const
209     {
210         auto frameNode = GetMainFrameNode();
211         if (!frameNode) {
212             return nullptr;
213         }
214         return frameNode->GetFocusHub();
215     }
216 
217     ACE_FORCE_EXPORT RefPtr<FrameNode> GetMainFrameNode() const;
218 
219     // Get main component include composed component created by js view.
220     RefPtr<UINode> GetMainElementNode() const;
221 
222     // create wrappingComponentsMap and the component to map and then Push
223     // the map to the render component stack.
224     ACE_FORCE_EXPORT void Push(const RefPtr<UINode>& element, bool isCustomView = false);
225 
226     // Wrap the components map for the stack top and then pop the stack.
227     // Add the wrapped component has child of the new stack top's main component.
228     void Pop();
229 
230     // pop the last container
231     void PopContainer();
232 
233     // End of Render function, create component tree and flush modify task.
234     RefPtr<UINode> Finish();
235 
236     // Set key to be used for next node on the stack
237     void PushKey(const std::string& key);
238 
239     // Returns a key for the node if it has been pushed to the stack. Default is ""
240     std::string GetKey();
241 
242     // Takes care of the viewId wrt to foreach
243     std::string ProcessViewId(const std::string& viewId);
244 
245     // Clear the key pushed to the stack
246     void PopKey();
247 
248     // Prevent predict mark dirty when creating predict node
SetPredict(RefPtr<UINode> predictNode)249     void SetPredict(RefPtr<UINode> predictNode)
250     {
251         predictNode_ = predictNode;
252     }
253 
ResetPredict()254     void ResetPredict() {
255         predictNode_.Reset();
256     }
257 
258     // Check whether the current node is in the corresponding polymorphic style state.
259     // When the polymorphic style is not set on the front end, it returns true regardless of the current node state;
260     // When the polymorphic style is set on the front end, true is returned only if the current node state is the same
261     // as the polymorphic style.
262     bool IsCurrentVisualStateProcess();
263 
264     void SetVisualState(VisualState state);
265 
GetVisualState()266     std::optional<UIState> GetVisualState() const
267     {
268         return visualState_;
269     }
270 
IsVisualStateSet()271     bool IsVisualStateSet()
272     {
273         return visualState_.has_value();
274     }
275 
ClearVisualState()276     void ClearVisualState()
277     {
278         visualState_.reset();
279     }
280 
ClearStack()281     void ClearStack()
282     {
283         auto emptyStack = std::stack<RefPtr<UINode>>();
284         elementsStack_.swap(emptyStack);
285     }
286 
GetOrCreateGestureProcessor()287     RefPtr<GestureProcessor> GetOrCreateGestureProcessor()
288     {
289         if (!gestureStack_) {
290             gestureStack_ = AceType::MakeRefPtr<GestureProcessor>();
291         }
292         return gestureStack_;
293     }
294 
ResetGestureProcessor()295     void ResetGestureProcessor()
296     {
297         return gestureStack_.Reset();
298     }
299 
300     /**
301      * when nesting observeComponentCreation functions, such as in the case of
302      * If, and the if branch creates a Text etc that requires an implicit pop
303      * this function is needed after executing the inner observeComponentCreation
304      * and before read ViewStackProcessor.GetTopMostElementId(); on the outer one
305      */
306     void ImplicitPopBeforeContinue();
307 
308     // End of Rerender function, flush modifier task.
309     void FlushRerenderTask();
310 
311     /**
312      * start 'get' access recording
313      * account all get access to given node id
314      * next node creation will claim the given node id
315      * see ClaimNodeId()
316      */
StartGetAccessRecordingFor(int32_t elmtId)317     void StartGetAccessRecordingFor(int32_t elmtId)
318     {
319         accountGetAccessToNodeId_ = elmtId;
320         reservedNodeId_ = elmtId;
321     }
322 
ClaimNodeId()323     int32_t ClaimNodeId()
324     {
325         const auto result = reservedNodeId_;
326         reservedNodeId_ = ElementRegister::UndefinedElementId;
327         return result;
328     }
329 
330     /**
331      * get the elmtId to which all get access should be accounted
332      * ElementRegister::UndefinedElementId; means no get access recording enabled
333      */
GetNodeIdToAccountFor()334     ElementIdType GetNodeIdToAccountFor() const
335     {
336         return accountGetAccessToNodeId_;
337     }
SetNodeIdToAccountFor(ElementIdType elmtId)338     void SetNodeIdToAccountFor(ElementIdType elmtId)
339     {
340         accountGetAccessToNodeId_ = elmtId;
341     }
342 
343     /**
344      * inverse of StartGetAccessRecordingFor
345      */
StopGetAccessRecording()346     void StopGetAccessRecording()
347     {
348         accountGetAccessToNodeId_ = ElementRegister::UndefinedElementId;
349         reservedNodeId_ = ElementRegister::UndefinedElementId;
350     }
351 
352     void FlushImplicitAnimation();
353 
354     // used for knowing which page node to execute the pageTransitionFunc
SetPageNode(const RefPtr<FrameNode> & pageNode)355     void SetPageNode(const RefPtr<FrameNode>& pageNode)
356     {
357         currentPage_ = pageNode;
358     }
359 
GetPageNode()360     const RefPtr<FrameNode>& GetPageNode() const
361     {
362         return currentPage_;
363     }
364 
365     // Sets the implicit animation option. This is needed for 3D Model View.
366     void SetImplicitAnimationOption(const AnimationOption& option);
367 
368     // Returns implicit animation option.
369     const AnimationOption& GetImplicitAnimationOption() const;
370 
371     RefPtr<UINode> GetNewUINode();
372 
GetAndPushFrameNode(const std::string & tag,int32_t elmtId)373     void GetAndPushFrameNode(const std::string& tag, int32_t elmtId)
374     {
375         auto frameNode = FrameNode::GetFrameNode(tag, elmtId);
376         if (!frameNode) {
377             return;
378         }
379         Push(frameNode);
380     }
381 
CheckTopNodeFirstBuilding()382     bool CheckTopNodeFirstBuilding() const
383     {
384         auto node = GetMainFrameNode();
385         CHECK_NULL_RETURN(node, false);
386         return node->IsFirstBuilding();
387     }
388 
SetCustomTitleNode(const RefPtr<UINode> & customTitleNode)389     void SetCustomTitleNode(const RefPtr<UINode>& customTitleNode)
390     {
391         customTitleNode_ = customTitleNode;
392     }
393 
GetCustomTitleNode()394     const RefPtr<UINode> GetCustomTitleNode() const
395     {
396         return customTitleNode_;
397     }
398 
SetIsBuilderNode(bool isBuilderNode)399     void SetIsBuilderNode(bool isBuilderNode)
400     {
401         isBuilderNode_ = isBuilderNode;
402     }
403 
IsBuilderNode()404     bool IsBuilderNode() const
405     {
406         return isBuilderNode_;
407     }
408 
SetIsExportTexture(bool isExportTexture)409     void SetIsExportTexture(bool isExportTexture)
410     {
411         isExportTexture_ = isExportTexture;
412     }
413 
IsExportTexture()414     bool IsExportTexture() const
415     {
416         return isExportTexture_;
417     }
418 
419 private:
420     ViewStackProcessor();
421 
422     bool ShouldPopImmediately();
423 
424     // Singleton instance
425     static thread_local std::unique_ptr<ViewStackProcessor> instance;
426 
427     // render component stack
428     std::stack<RefPtr<UINode>> elementsStack_;
429 
430     RefPtr<FrameNode> currentPage_;
431 
432     RefPtr<UINode> customTitleNode_;
433 
434     RefPtr<GestureProcessor> gestureStack_;
435 
436     std::string viewKey_;
437     std::stack<size_t> keyStack_;
438 
439     RefPtr<UINode> predictNode_;
440 
441     std::stack<int32_t> parentIdStack_;
442 
443     std::optional<UIState> visualState_ = std::nullopt;
444     bool isBuilderNode_ = false;
445     bool isExportTexture_ = false;
446 
447     // elmtId reserved for next component creation
448     ElementIdType reservedNodeId_ = ElementRegister::UndefinedElementId;
449 
450     // elmtId to account get access to
451     ElementIdType accountGetAccessToNodeId_ = ElementRegister::UndefinedElementId;
452 
453     AnimationOption implicitAnimationOption_;
454 
455     ACE_DISALLOW_COPY_AND_MOVE(ViewStackProcessor);
456 };
457 
458 class ACE_EXPORT ScopedViewStackProcessor final {
459 public:
460     ScopedViewStackProcessor();
461     ~ScopedViewStackProcessor();
462 
463 private:
464     std::unique_ptr<ViewStackProcessor> instance_;
465 
466     ACE_DISALLOW_COPY_AND_MOVE(ScopedViewStackProcessor);
467 };
468 } // namespace OHOS::Ace::NG
469 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_VIEW_STACK_PROCESSOR_H
470