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