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(int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd) override; 116 117 const std::list<RefPtr<UINode>>& GetChildren(bool notDetach = false) const override; 118 void LoadChildren(bool notDetach) const; 119 OnSetCacheCount(int32_t cacheCount,const std::optional<LayoutConstraintF> & itemConstraint)120 void OnSetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint) override 121 { 122 itemConstraint_ = itemConstraint; 123 if (builder_) { 124 builder_->SetCacheCount(cacheCount); 125 } 126 } 127 void SetJSViewActive(bool active = true, bool isLazyForEachNode = false) override 128 { 129 if (builder_) { 130 builder_->SetJSViewActive(active); 131 isActive_ = active; 132 } 133 } PaintDebugBoundaryTreeAll(bool flag)134 void PaintDebugBoundaryTreeAll(bool flag) override 135 { 136 if (builder_) { 137 builder_->PaintDebugBoundaryTreeAll(flag); 138 } 139 } 140 int32_t GetIndexByUINode(const RefPtr<UINode>& uiNode) const; SetNodeIndexOffset(int32_t start,int32_t count)141 void SetNodeIndexOffset(int32_t start, int32_t count) override 142 { 143 startIndex_ = start; 144 count_ = count; 145 } 146 void RecycleItems(int32_t from, int32_t to) override; 147 GetBuilder()148 const RefPtr<LazyForEachBuilder>& GetBuilder() const 149 { 150 return builder_; 151 } 152 RegisterBuilderListener()153 void RegisterBuilderListener() { 154 CHECK_NULL_VOID(builder_); 155 if (!isRegisterListener_) { 156 builder_->RegisterDataChangeListener(Claim(this)); 157 isRegisterListener_ = true; 158 } 159 } 160 161 void SetOnMove(std::function<void(int32_t, int32_t)>&& onMove); 162 void MoveData(int32_t from, int32_t to) override; 163 void FireOnMove(int32_t from, int32_t to) override; 164 RefPtr<FrameNode> GetFrameNode(int32_t index) override; 165 int32_t GetFrameNodeIndex(const RefPtr<FrameNode>& node, bool isExpanded = true) override; 166 void InitDragManager(const RefPtr<FrameNode>& childNode); 167 void InitAllChilrenDragManager(bool init); 168 169 /** 170 * @brief Notify the change of dataSource to parent. 171 * 172 * @param index the position of change. 173 * @param count the count of change in [index]. 174 * @param notificationType the type of notification. 175 */ 176 void NotifyChangeWithCount(int32_t index, int32_t count, NotificationType notificationType) const; 177 178 /** 179 * @brief Parse OnDatasetChange for NotifyCountChange. 180 * 181 * @param dataOperations bulk change operations. 182 */ 183 void ParseOperations(const std::list<V2::Operation>& dataOperations); 184 protected: 185 void UpdateChildrenFreezeState(bool isFreeze) override; 186 private: OnAttachToMainTree(bool recursive)187 void OnAttachToMainTree(bool recursive) override 188 { 189 UINode::OnAttachToMainTree(recursive); 190 RegisterBuilderListener(); 191 if (builder_) { 192 for (const auto& item : builder_->GetCachedUINodeMap()) { 193 if (item.second.second != nullptr) { 194 builder_->ProcessOffscreenNode(item.second.second, false); 195 } 196 } 197 } 198 } 199 200 void OnDetachFromMainTree(bool recursive, PipelineContext* context = nullptr) override 201 { 202 UINode::OnDetachFromMainTree(recursive, context); 203 if (builder_) { 204 for (const auto& item : builder_->GetCachedUINodeMap()) { 205 if (item.second.second != nullptr) { 206 item.second.second->DetachFromMainTree(recursive); 207 builder_->ProcessOffscreenNode(item.second.second, true); 208 } 209 } 210 } 211 } 212 OnOffscreenProcess(bool recursive)213 void OnOffscreenProcess(bool recursive) override 214 { 215 UINode::OnOffscreenProcess(recursive); 216 RegisterBuilderListener(); 217 } 218 OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>> & visibleList)219 void OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList) override 220 { 221 // LazyForEachNode::GetChildren() may add some children to disappearingChildren_, execute earlier to ensure 222 // disappearingChildren_ is correct before calling GenerateOneDepthVisibleFrameWithTransition. 223 GetChildren(); 224 UINode::GenerateOneDepthVisibleFrameWithTransition(visibleList); 225 } 226 227 // The index values of the start and end of the current children nodes and the corresponding keys. 228 std::list<std::optional<std::string>> ids_; 229 std::list<int32_t> predictItems_; 230 std::optional<LayoutConstraintF> itemConstraint_; 231 bool requestLongPredict_ = false; 232 bool isRegisterListener_ = false; 233 bool isLoop_ = false; 234 235 mutable std::list<RefPtr<UINode>> tempChildren_; 236 mutable std::list<RefPtr<UINode>> children_; 237 mutable bool needPredict_ = false; 238 bool needMarkParent_ = true; 239 bool isActive_ = true; 240 int32_t startIndex_ = 0; 241 int32_t count_ = 0; 242 243 RefPtr<LazyForEachBuilder> builder_; 244 245 ACE_DISALLOW_COPY_AND_MOVE(LazyForEachNode); 246 }; 247 248 } // namespace OHOS::Ace::NG 249 250 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_LAZY_FOR_EACH_NODE_H