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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_LAZY_FOR_EACH_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_LAZY_FOR_EACH_NODE_H 18 19 #include <list> 20 #include <optional> 21 #include <string> 22 23 #include "base/utils/utils.h" 24 #include "core/common/resource/resource_configuration.h" 25 #include "core/components_ng/base/frame_node.h" 26 #include "core/components_ng/base/ui_node.h" 27 #include "core/components_ng/syntax/for_each_base_node.h" 28 #include "core/components_ng/syntax/lazy_for_each_builder.h" 29 #include "core/components_v2/inspector/inspector_constants.h" 30 31 namespace OHOS::Ace::NG { 32 33 class ACE_EXPORT LazyForEachNode : public ForEachBaseNode, public V2::DataChangeListener { 34 DECLARE_ACE_TYPE(LazyForEachNode, ForEachBaseNode, DataChangeListener); 35 36 public: 37 static RefPtr<LazyForEachNode> GetOrCreateLazyForEachNode( 38 int32_t nodeId, const RefPtr<LazyForEachBuilder>& forEachBuilder); 39 40 static RefPtr<LazyForEachNode> CreateLazyForEachNode( 41 int32_t nodeId, const RefPtr<LazyForEachBuilder>& forEachBuilder); 42 LazyForEachNode(int32_t nodeId,const RefPtr<LazyForEachBuilder> & forEachBuilder)43 LazyForEachNode(int32_t nodeId, const RefPtr<LazyForEachBuilder>& forEachBuilder) 44 : ForEachBaseNode(V2::JS_LAZY_FOR_EACH_ETS_TAG, nodeId, false), builder_(forEachBuilder) 45 {} 46 ~LazyForEachNode()47 ~LazyForEachNode() { 48 CHECK_NULL_VOID(builder_); 49 builder_->UnregisterDataChangeListener(this); 50 builder_->ClearAllOffscreenNode(); 51 isRegisterListener_ = false; 52 } 53 IsAtomicNode()54 bool IsAtomicNode() const override 55 { 56 return false; 57 } 58 FrameCount()59 int32_t FrameCount() const override 60 { 61 return builder_ ? builder_->GetTotalCount() : 0; 62 } 63 64 void AdjustLayoutWrapperTree(const RefPtr<LayoutWrapperNode>& parent, bool forceMeasure, bool forceLayout) override; 65 66 void UpdateLazyForEachItems(int32_t newStartIndex, int32_t newEndIndex, 67 std::list<std::optional<std::string>>&& nodeIds, 68 std::unordered_map<int32_t, std::optional<std::string>>&& cachedItems); 69 70 void OnDataReloaded() override; 71 void OnDataAdded(size_t index) override; 72 void OnDataBulkAdded(size_t index, size_t count) override; 73 void OnDataDeleted(size_t index) override; 74 void OnDataBulkDeleted(size_t index, size_t count) override; 75 void OnDataChanged(size_t index) override; 76 void OnDataMoved(size_t from, size_t to) override; 77 void OnDatasetChange(const std::list<V2::Operation>& DataOperations) override; 78 79 void OnDataBulkChanged(size_t index, size_t count) override; 80 void OnDataMoveToNewPlace(size_t from, size_t to) override; 81 82 void PostIdleTask(std::list<int32_t>&& items, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt, 83 bool longPredictTask = false); 84 SetRequestLongPredict(bool requestLongPredict)85 void SetRequestLongPredict(bool requestLongPredict) 86 { 87 requestLongPredict_ = requestLongPredict; 88 } 89 SetFlagForGeneratedItem(PropertyChangeFlag propertyChangeFlag)90 void SetFlagForGeneratedItem(PropertyChangeFlag propertyChangeFlag) 91 { 92 builder_->SetFlagForGeneratedItem(propertyChangeFlag); 93 } 94 SetIsLoop(bool isLoop)95 void SetIsLoop(bool isLoop) 96 { 97 isLoop_ = isLoop; 98 if (builder_) { 99 builder_->SetIsLoop(isLoop); 100 } 101 } 102 GetIsLoop()103 bool GetIsLoop() const 104 { 105 return isLoop_; 106 } 107 void PostIdleTask(); 108 void OnConfigurationUpdate(const ConfigurationChange& configurationChange) override; 109 void MarkNeedSyncRenderTree(bool needRebuild = false) override; 110 111 void BuildAllChildren(); 112 RefPtr<UINode> GetFrameChildByIndex(uint32_t index, bool needBuild, bool isCache = false, 113 bool addToRenderTree = false) override; 114 void DoRemoveChildInRenderTree(uint32_t index, bool isAll) override; 115 void DoSetActiveChildRange( 116 int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCache = false) override; 117 118 const std::list<RefPtr<UINode>>& GetChildren(bool notDetach = false) const override; 119 void LoadChildren(bool notDetach) const; 120 OnSetCacheCount(int32_t cacheCount,const std::optional<LayoutConstraintF> & itemConstraint)121 void OnSetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint) override 122 { 123 itemConstraint_ = itemConstraint; 124 if (builder_) { 125 builder_->SetCacheCount(cacheCount); 126 } 127 } 128 void SetJSViewActive(bool active = true, bool isLazyForEachNode = false) override 129 { 130 if (builder_) { 131 builder_->SetJSViewActive(active); 132 isActive_ = active; 133 } 134 } PaintDebugBoundaryTreeAll(bool flag)135 void PaintDebugBoundaryTreeAll(bool flag) override 136 { 137 if (builder_) { 138 builder_->PaintDebugBoundaryTreeAll(flag); 139 } 140 } 141 int32_t GetIndexByUINode(const RefPtr<UINode>& uiNode) const; SetNodeIndexOffset(int32_t start,int32_t count)142 void SetNodeIndexOffset(int32_t start, int32_t count) override 143 { 144 startIndex_ = start; 145 count_ = count; 146 } 147 void RecycleItems(int32_t from, int32_t to) override; 148 GetBuilder()149 const RefPtr<LazyForEachBuilder>& GetBuilder() const 150 { 151 return builder_; 152 } 153 RegisterBuilderListener()154 void RegisterBuilderListener() { 155 CHECK_NULL_VOID(builder_); 156 if (!isRegisterListener_) { 157 builder_->RegisterDataChangeListener(Claim(this)); 158 isRegisterListener_ = true; 159 } 160 } 161 162 void SetOnMove(std::function<void(int32_t, int32_t)>&& onMove); 163 void MoveData(int32_t from, int32_t to) override; 164 void FireOnMove(int32_t from, int32_t to) override; 165 RefPtr<FrameNode> GetFrameNode(int32_t index) override; 166 int32_t GetFrameNodeIndex(const RefPtr<FrameNode>& node, bool isExpanded = true) override; 167 void InitDragManager(const RefPtr<FrameNode>& childNode); 168 void InitAllChilrenDragManager(bool init); 169 170 /** 171 * @brief Notify the change of dataSource to parent. 172 * 173 * @param index the position of change. 174 * @param count the count of change in [index]. 175 * @param notificationType the type of notification. 176 */ 177 void NotifyChangeWithCount(int32_t index, int32_t count, NotificationType notificationType) const; 178 179 /** 180 * @brief Parse OnDatasetChange for NotifyCountChange. 181 * 182 * @param dataOperations bulk change operations. 183 */ 184 void ParseOperations(const std::list<V2::Operation>& dataOperations); 185 protected: 186 void UpdateChildrenFreezeState(bool isFreeze) override; 187 private: OnAttachToMainTree(bool recursive)188 void OnAttachToMainTree(bool recursive) override 189 { 190 UINode::OnAttachToMainTree(recursive); 191 RegisterBuilderListener(); 192 if (builder_) { 193 for (const auto& item : builder_->GetCachedUINodeMap()) { 194 if (item.second.second != nullptr) { 195 builder_->ProcessOffscreenNode(item.second.second, false); 196 } 197 } 198 } 199 } 200 201 void OnDetachFromMainTree(bool recursive, PipelineContext* context = nullptr) override 202 { 203 UINode::OnDetachFromMainTree(recursive, context); 204 if (builder_) { 205 auto tempExpiringItem = builder_->GetCachedUINodeMap(); 206 for (const auto& [key, child] : tempExpiringItem) { 207 if (child.second != nullptr) { 208 child.second->DetachFromMainTree(recursive); 209 builder_->ProcessOffscreenNode(child.second, true); 210 } 211 } 212 } 213 } 214 OnOffscreenProcess(bool recursive)215 void OnOffscreenProcess(bool recursive) override 216 { 217 UINode::OnOffscreenProcess(recursive); 218 RegisterBuilderListener(); 219 } 220 OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>> & visibleList)221 void OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList) override 222 { 223 // LazyForEachNode::GetChildren() may add some children to disappearingChildren_, execute earlier to ensure 224 // disappearingChildren_ is correct before calling GenerateOneDepthVisibleFrameWithTransition. 225 GetChildren(); 226 UINode::GenerateOneDepthVisibleFrameWithTransition(visibleList); 227 } 228 229 // The index values of the start and end of the current children nodes and the corresponding keys. 230 std::list<std::optional<std::string>> ids_; 231 std::list<int32_t> predictItems_; 232 std::optional<LayoutConstraintF> itemConstraint_; 233 bool requestLongPredict_ = true; 234 bool isRegisterListener_ = false; 235 bool isLoop_ = false; 236 237 mutable std::list<RefPtr<UINode>> tempChildren_; 238 mutable std::list<RefPtr<UINode>> children_; 239 mutable bool needPredict_ = false; 240 bool needMarkParent_ = true; 241 bool isActive_ = true; 242 int32_t startIndex_ = 0; 243 int32_t count_ = 0; 244 245 RefPtr<LazyForEachBuilder> builder_; 246 247 ACE_DISALLOW_COPY_AND_MOVE(LazyForEachNode); 248 }; 249 250 } // namespace OHOS::Ace::NG 251 252 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_LAZY_FOR_EACH_NODE_H