• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "core/components_ng/base/view_stack_processor.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components/common/properties/state_attributes.h"
20 #include "core/components_ng/base/group_node.h"
21 #include "core/components_ng/layout/layout_property.h"
22 #include "core/components_ng/pattern/custom/custom_node.h"
23 #include "core/components_ng/syntax/for_each_node.h"
24 #include "core/components_ng/syntax/if_else_node.h"
25 #include "core/components_v2/inspector/inspector_constants.h"
26 
27 namespace OHOS::Ace::NG {
28 thread_local std::unique_ptr<ViewStackProcessor> ViewStackProcessor::instance = nullptr;
29 
GetInstance()30 ViewStackProcessor* ViewStackProcessor::GetInstance()
31 {
32     if (!instance) {
33         instance.reset(new ViewStackProcessor);
34     }
35     return instance.get();
36 }
37 
38 ViewStackProcessor::ViewStackProcessor() = default;
39 
GetMainFrameNode() const40 RefPtr<FrameNode> ViewStackProcessor::GetMainFrameNode() const
41 {
42     return AceType::DynamicCast<FrameNode>(GetMainElementNode());
43 }
44 
GetMainElementNode() const45 RefPtr<UINode> ViewStackProcessor::GetMainElementNode() const
46 {
47     if (elementsStack_.empty()) {
48         return nullptr;
49     }
50     return elementsStack_.top();
51 }
52 
Push(const RefPtr<UINode> & element,bool)53 void ViewStackProcessor::Push(const RefPtr<UINode>& element, bool /*isCustomView*/)
54 {
55     if (ShouldPopImmediately()) {
56         Pop();
57     }
58     element->SetRemoveSilently(false);
59     elementsStack_.push(element);
60 }
61 
ShouldPopImmediately()62 bool ViewStackProcessor::ShouldPopImmediately()
63 {
64     if (elementsStack_.size() <= 1) {
65         return false;
66     }
67     // for custom node and atomic node, just pop top node when next node is coming.
68     return GetMainElementNode()->IsAtomicNode();
69 }
70 
ImplicitPopBeforeContinue()71 void ViewStackProcessor::ImplicitPopBeforeContinue()
72 {
73     if ((elementsStack_.size() > 1) && ShouldPopImmediately()) {
74         Pop();
75     }
76 }
77 
FlushImplicitAnimation()78 void ViewStackProcessor::FlushImplicitAnimation()
79 {
80     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
81     CHECK_NULL_VOID(frameNode);
82     if (frameNode->IsOnMainTree()) {
83         frameNode->MarkDirtyNode();
84     }
85 }
86 
FlushRerenderTask()87 void ViewStackProcessor::FlushRerenderTask()
88 {
89     auto node = Finish();
90     CHECK_NULL_VOID(node);
91     if (predictNode_) {
92         predictNode_->AddAttachToMainTreeTask([node]() {
93             node->FlushUpdateAndMarkDirty();
94         });
95         return;
96     }
97     node->FlushUpdateAndMarkDirty();
98 }
99 
Pop()100 void ViewStackProcessor::Pop()
101 {
102     if (elementsStack_.empty() || elementsStack_.size() == 1) {
103         return;
104     }
105 
106     auto currentNode = Finish();
107     currentNode->SetBuildByJs(true);
108     auto parent = GetMainElementNode();
109     if (AceType::InstanceOf<GroupNode>(parent)) {
110         auto groupNode = AceType::DynamicCast<GroupNode>(parent);
111         groupNode->AddChildToGroup(currentNode);
112         return;
113     }
114 
115     currentNode->MountToParent(
116         parent, DEFAULT_NODE_SLOT, AceType::InstanceOf<ForEachNode>(parent), AceType::InstanceOf<IfElseNode>(parent));
117     auto currentFrameNode = AceType::DynamicCast<FrameNode>(currentNode);
118     if (currentFrameNode) {
119         currentFrameNode->OnMountToParentDone();
120     }
121 }
122 
PopContainer()123 void ViewStackProcessor::PopContainer()
124 {
125     auto top = GetMainElementNode();
126     // for container node.
127     if (top && !top->IsAtomicNode()) {
128         Pop();
129         return;
130     }
131 
132     while (top && (top->IsAtomicNode())) {
133         if (elementsStack_.size() == 1) {
134             return;
135         }
136         Pop();
137         top = GetMainElementNode();
138     }
139     Pop();
140 }
141 
Finish()142 RefPtr<UINode> ViewStackProcessor::Finish()
143 {
144     if (elementsStack_.empty()) {
145         return nullptr;
146     }
147     auto element = elementsStack_.top();
148     elementsStack_.pop();
149     auto frameNode = AceType::DynamicCast<FrameNode>(element);
150     if (frameNode) {
151         frameNode->MarkBuildDone();
152         frameNode->MarkModifyDone();
153         auto renderContext = frameNode->GetRenderContext();
154         if (renderContext) {
155             renderContext->SetNeedDebugBoundary(true);
156         }
157     }
158     // ForEach Partial Update Path.
159     if (AceType::InstanceOf<ForEachNode>(element)) {
160         auto forEachNode = AceType::DynamicCast<ForEachNode>(element);
161         forEachNode->CompareAndUpdateChildren();
162     }
163     return element;
164 }
165 
SetVisualState(VisualState state)166 void ViewStackProcessor::SetVisualState(VisualState state)
167 {
168     switch (state) {
169         case VisualState::DISABLED:
170             visualState_ = UI_STATE_DISABLED;
171             break;
172         case VisualState::FOCUSED:
173             visualState_ = UI_STATE_FOCUSED;
174             break;
175         case VisualState::PRESSED:
176             visualState_ = UI_STATE_PRESSED;
177             break;
178         case VisualState::SELECTED:
179             visualState_ = UI_STATE_SELECTED;
180             break;
181         case VisualState::NORMAL:
182         default:
183             visualState_ = UI_STATE_NORMAL;
184     }
185     auto eventHub = GetMainFrameNodeEventHub<EventHub>();
186     CHECK_NULL_VOID(eventHub);
187     eventHub->AddSupportedState(visualState_.value());
188 }
189 
IsCurrentVisualStateProcess()190 bool ViewStackProcessor::IsCurrentVisualStateProcess()
191 {
192     if (!visualState_.has_value()) {
193         return true;
194     }
195     auto eventHub = GetMainFrameNodeEventHub<EventHub>();
196     CHECK_NULL_RETURN(eventHub, false);
197     auto result = eventHub->IsCurrentStateOn(visualState_.value());
198     return result;
199 }
200 
PushKey(const std::string & key)201 void ViewStackProcessor::PushKey(const std::string& key)
202 {
203     if (viewKey_.empty()) {
204         // For the root node, the key value is xxx.
205         viewKey_ = key;
206         keyStack_.emplace(key.length());
207     } else {
208         // For descendant nodes, the key value is xxx_xxx
209         viewKey_.append("_").append(key);
210         keyStack_.emplace(key.length() + 1);
211     }
212 }
213 
PopKey()214 void ViewStackProcessor::PopKey()
215 {
216     size_t length = keyStack_.top();
217     keyStack_.pop();
218 
219     if (length > 0) {
220         viewKey_.erase(viewKey_.length() - length);
221     }
222 }
223 
GetKey()224 std::string ViewStackProcessor::GetKey()
225 {
226     return viewKey_.empty() ? "" : viewKey_;
227 }
228 
ProcessViewId(const std::string & viewId)229 std::string ViewStackProcessor::ProcessViewId(const std::string& viewId)
230 {
231     return viewKey_.empty() ? viewId : viewKey_ + "_" + viewId;
232 }
233 
SetImplicitAnimationOption(const AnimationOption & option)234 void ViewStackProcessor::SetImplicitAnimationOption(const AnimationOption& option)
235 {
236     implicitAnimationOption_ = option;
237 }
238 
GetImplicitAnimationOption() const239 const AnimationOption& ViewStackProcessor::GetImplicitAnimationOption() const
240 {
241     return implicitAnimationOption_;
242 }
243 
GetNewUINode()244 RefPtr<UINode> ViewStackProcessor::GetNewUINode()
245 {
246     return Finish();
247 }
248 
ScopedViewStackProcessor()249 ScopedViewStackProcessor::ScopedViewStackProcessor()
250 {
251     std::swap(instance_, ViewStackProcessor::instance);
252 }
253 
~ScopedViewStackProcessor()254 ScopedViewStackProcessor::~ScopedViewStackProcessor()
255 {
256     std::swap(instance_, ViewStackProcessor::instance);
257 }
258 } // namespace OHOS::Ace::NG
259