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_ng/base/frame_node.h" 26 #include "core/components_ng/base/ui_node.h" 27 #include "core/components_ng/event/state_style_manager.h" 28 #include "core/components_ng/layout/layout_property.h" 29 #include "core/components_ng/pattern/custom/custom_node.h" 30 #include "core/components_ng/pattern/tabs/tab_bar_pattern.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 namespace OHOS::Ace::NG { 73 class ACE_EXPORT ViewStackProcessor final { 74 public: 75 friend class ScopedViewStackProcessor; 76 77 static ViewStackProcessor* GetInstance(); 78 ~ViewStackProcessor() = default; 79 80 template<typename Pattern> GetMainFrameNodePattern()81 RefPtr<Pattern> GetMainFrameNodePattern() const 82 { 83 auto frameNode = GetMainFrameNode(); 84 if (!frameNode) { 85 return nullptr; 86 } 87 return AceType::DynamicCast<Pattern>(frameNode->GetPattern()); 88 } 89 90 template<typename EventHubType> GetMainFrameNodeEventHub()91 RefPtr<EventHubType> GetMainFrameNodeEventHub() const 92 { 93 auto frameNode = GetMainFrameNode(); 94 if (!frameNode) { 95 return nullptr; 96 } 97 return frameNode->GetEventHub<EventHubType>(); 98 } 99 GetMainFrameNodeGestureEventHub()100 RefPtr<GestureEventHub> GetMainFrameNodeGestureEventHub() const 101 { 102 auto frameNode = GetMainFrameNode(); 103 if (!frameNode) { 104 return nullptr; 105 } 106 return frameNode->GetOrCreateGestureEventHub(); 107 } 108 GetMainFrameNodeInputEventHub()109 RefPtr<InputEventHub> GetMainFrameNodeInputEventHub() const 110 { 111 auto frameNode = GetMainFrameNode(); 112 if (!frameNode) { 113 return nullptr; 114 } 115 return frameNode->GetOrCreateInputEventHub(); 116 } 117 GetOrCreateMainFrameNodeFocusHub()118 RefPtr<FocusHub> GetOrCreateMainFrameNodeFocusHub() const 119 { 120 auto frameNode = GetMainFrameNode(); 121 if (!frameNode) { 122 return nullptr; 123 } 124 return frameNode->GetOrCreateFocusHub(); 125 } 126 GetMainFrameNodeFocusHub()127 RefPtr<FocusHub> GetMainFrameNodeFocusHub() const 128 { 129 auto frameNode = GetMainFrameNode(); 130 if (!frameNode) { 131 return nullptr; 132 } 133 return frameNode->GetFocusHub(); 134 } 135 136 RefPtr<FrameNode> GetMainFrameNode() const; 137 138 // Get main component include composed component created by js view. 139 RefPtr<UINode> GetMainElementNode() const; 140 141 // create wrappingComponentsMap and the component to map and then Push 142 // the map to the render component stack. 143 void Push(const RefPtr<UINode>& element, bool isCustomView = false); 144 145 // Wrap the components map for the stack top and then pop the stack. 146 // Add the wrapped component has child of the new stack top's main component. 147 void Pop(); 148 149 // pop the last container 150 void PopContainer(); 151 152 // End of Render function, create component tree and flush modify task. 153 RefPtr<UINode> Finish(); 154 155 // Set key to be used for next node on the stack 156 void PushKey(const std::string& key); 157 158 // Returns a key for the node if it has been pushed to the stack. Default is "" 159 std::string GetKey(); 160 161 // Takes care of the viewId wrt to foreach 162 std::string ProcessViewId(const std::string& viewId); 163 164 // Clear the key pushed to the stack 165 void PopKey(); 166 167 // Check whether the current node is in the corresponding polymorphic style state. 168 // When the polymorphic style is not set on the front end, it returns true regardless of the current node state; 169 // When the polymorphic style is set on the front end, true is returned only if the current node state is the same 170 // as the polymorphic style. 171 bool IsCurrentVisualStateProcess(); 172 173 void SetVisualState(VisualState state); 174 GetVisualState()175 std::optional<UIState> GetVisualState() const 176 { 177 return visualState_; 178 } 179 IsVisualStateSet()180 bool IsVisualStateSet() 181 { 182 return visualState_.has_value(); 183 } 184 ClearVisualState()185 void ClearVisualState() 186 { 187 visualState_.reset(); 188 } 189 ClearStack()190 void ClearStack() 191 { 192 auto emptyStack = std::stack<RefPtr<UINode>>(); 193 elementsStack_.swap(emptyStack); 194 } 195 GetOrCreateGestureProcessor()196 RefPtr<GestureProcessor> GetOrCreateGestureProcessor() 197 { 198 if (!gestureStack_) { 199 gestureStack_ = AceType::MakeRefPtr<GestureProcessor>(); 200 } 201 return gestureStack_; 202 } 203 ResetGestureProcessor()204 void ResetGestureProcessor() 205 { 206 return gestureStack_.Reset(); 207 } 208 209 /** 210 * when nesting observeComponentCreation functions, such as in the case of 211 * If, and the if branch creates a Text etc that requires an implicit pop 212 * this function is needed after executing the inner observeComponentCreation 213 * and before read ViewStackProcessor.GetTopMostElementId(); on the outer one 214 */ 215 void ImplicitPopBeforeContinue(); 216 217 // End of Rerender function, flush modifier task. 218 void FlushRerenderTask(); 219 220 /** 221 * start 'get' access recording 222 * account all get access to given node id 223 * next node creation will claim the given node id 224 * see ClaimNodeId() 225 */ StartGetAccessRecordingFor(int32_t elmtId)226 void StartGetAccessRecordingFor(int32_t elmtId) 227 { 228 accountGetAccessToNodeId_ = elmtId; 229 reservedNodeId_ = elmtId; 230 } 231 ClaimNodeId()232 int32_t ClaimNodeId() 233 { 234 const auto result = reservedNodeId_; 235 reservedNodeId_ = ElementRegister::UndefinedElementId; 236 return result; 237 } 238 239 /** 240 * get the elmtId to which all get access should be accounted 241 * ElementRegister::UndefinedElementId; means no get access recording enabled 242 */ GetNodeIdToAccountFor()243 ElementIdType GetNodeIdToAccountFor() const 244 { 245 return accountGetAccessToNodeId_; 246 } SetNodeIdToAccountFor(ElementIdType elmtId)247 void SetNodeIdToAccountFor(ElementIdType elmtId) 248 { 249 accountGetAccessToNodeId_ = elmtId; 250 } 251 252 /** 253 * inverse of StartGetAccessRecordingFor 254 */ StopGetAccessRecording()255 void StopGetAccessRecording() 256 { 257 accountGetAccessToNodeId_ = ElementRegister::UndefinedElementId; 258 reservedNodeId_ = ElementRegister::UndefinedElementId; 259 } 260 261 void FlushImplicitAnimation(); 262 263 // used for knowing which page node to execute the pageTransitionFunc SetPageNode(const RefPtr<FrameNode> & pageNode)264 void SetPageNode(const RefPtr<FrameNode>& pageNode) 265 { 266 currentPage_ = pageNode; 267 } 268 GetPageNode()269 const RefPtr<FrameNode>& GetPageNode() const 270 { 271 return currentPage_; 272 } 273 274 RefPtr<UINode> GetNewUINode(); 275 private: 276 ViewStackProcessor(); 277 278 bool ShouldPopImmediately(); 279 280 // Singleton instance 281 static thread_local std::unique_ptr<ViewStackProcessor> instance; 282 283 // render component stack 284 std::stack<RefPtr<UINode>> elementsStack_; 285 286 RefPtr<FrameNode> currentPage_; 287 288 RefPtr<GestureProcessor> gestureStack_; 289 290 std::string viewKey_; 291 std::stack<size_t> keyStack_; 292 293 std::stack<int32_t> parentIdStack_; 294 295 std::optional<UIState> visualState_ = std::nullopt; 296 297 // elmtId reserved for next component creation 298 ElementIdType reservedNodeId_ = ElementRegister::UndefinedElementId; 299 300 // elmtId to account get access to 301 ElementIdType accountGetAccessToNodeId_ = ElementRegister::UndefinedElementId; 302 303 ACE_DISALLOW_COPY_AND_MOVE(ViewStackProcessor); 304 }; 305 306 class ACE_EXPORT ScopedViewStackProcessor final { 307 public: 308 ScopedViewStackProcessor(); 309 ~ScopedViewStackProcessor(); 310 311 private: 312 std::unique_ptr<ViewStackProcessor> instance_; 313 314 ACE_DISALLOW_COPY_AND_MOVE(ScopedViewStackProcessor); 315 }; 316 } // namespace OHOS::Ace::NG 317 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_VIEW_STACK_PROCESSOR_H 318