• 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 #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() override;
47 
48     void OnDelete() override;
49 
IsAtomicNode()50     bool IsAtomicNode() const override
51     {
52         return false;
53     }
54 
FrameCount()55     int32_t FrameCount() const override
56     {
57         return builder_ ? builder_->GetTotalCount() : 0;
58     }
59 
60     void NotifyColorModeChange(uint32_t colorMode) override;
61 
62     void AdjustLayoutWrapperTree(const RefPtr<LayoutWrapperNode>& parent, bool forceMeasure, bool forceLayout) override;
63 
64     void UpdateLazyForEachItems(int32_t newStartIndex, int32_t newEndIndex,
65         std::list<std::optional<std::string>>&& nodeIds,
66         std::unordered_map<int32_t, std::optional<std::string>>&& cachedItems);
67 
68     void OnDataReloaded() override;
69     void OnDataAdded(size_t index) override;
70     void OnDataBulkAdded(size_t index, size_t count) override;
71     void OnDataDeleted(size_t index) override;
72     void OnDataBulkDeleted(size_t index, size_t count) override;
73     void OnDataChanged(size_t index) override;
74     void OnDataMoved(size_t from, size_t to) override;
75     void OnDatasetChange(const std::list<V2::Operation>& DataOperations) override;
76 
77     void OnDataBulkChanged(size_t index, size_t count) override;
78     void OnDataMoveToNewPlace(size_t from, size_t to) override;
79 
80     void PostIdleTask(std::list<int32_t>&& items, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt,
81         bool longPredictTask = false);
82 
SetRequestLongPredict(bool requestLongPredict)83     void SetRequestLongPredict(bool requestLongPredict)
84     {
85         requestLongPredict_ = requestLongPredict;
86     }
87 
SetFlagForGeneratedItem(PropertyChangeFlag propertyChangeFlag)88     void SetFlagForGeneratedItem(PropertyChangeFlag propertyChangeFlag)
89     {
90         builder_->SetFlagForGeneratedItem(propertyChangeFlag);
91     }
92 
SetIsLoop(bool isLoop)93     void SetIsLoop(bool isLoop)
94     {
95         isLoop_ = isLoop;
96         if (builder_) {
97             builder_->SetIsLoop(isLoop);
98         }
99     }
100 
GetIsLoop()101     bool GetIsLoop() const
102     {
103         return isLoop_;
104     }
105     void PostIdleTask();
106     void OnConfigurationUpdate(const ConfigurationChange& configurationChange) override;
107     void MarkNeedSyncRenderTree(bool needRebuild = false) override;
108 
109     void BuildAllChildren();
110     RefPtr<UINode> GetFrameChildByIndex(uint32_t index, bool needBuild, bool isCache = false,
111         bool addToRenderTree = false) override;
112     void DoRemoveChildInRenderTree(uint32_t index, bool isAll) override;
113     void DoSetActiveChildRange(
114         int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCache = false) override;
115 
116     const std::list<RefPtr<UINode>>& GetChildren(bool notDetach = false) const override;
117     void LoadChildren(bool notDetach) const;
118 
119     const std::list<RefPtr<UINode>>& GetChildrenForInspector(bool needCacheNode = false) const override;
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, bool isReuse = false) override
129     {
130         if (builder_) {
131             builder_->SetJSViewActive(active);
132             isActive_ = active;
133         }
134     }
135     void SetDestroying(bool isDestroying = true, bool cleanStatus = true) override
136     {
137         if (builder_) {
138             builder_->SetDestroying(isDestroying, cleanStatus);
139         }
140     }
PaintDebugBoundaryTreeAll(bool flag)141     void PaintDebugBoundaryTreeAll(bool flag) override
142     {
143         if (builder_) {
144             builder_->PaintDebugBoundaryTreeAll(flag);
145         }
146     }
147     int32_t GetIndexByUINode(const RefPtr<UINode>& uiNode) const;
SetNodeIndexOffset(int32_t start,int32_t count)148     void SetNodeIndexOffset(int32_t start, int32_t count) override
149     {
150         startIndex_ = start;
151         count_ = count;
152     }
153     void RecycleItems(int32_t from, int32_t to) override;
154 
GetBuilder()155     const RefPtr<LazyForEachBuilder>& GetBuilder() const
156     {
157         return builder_;
158     }
159 
RegisterBuilderListener()160     void RegisterBuilderListener() {
161         CHECK_NULL_VOID(builder_);
162         if (!isRegisterListener_) {
163             builder_->RegisterDataChangeListener(Claim(this));
164             isRegisterListener_ = true;
165         }
166     }
167 
168     void SetItemDragHandler(std::function<void(int32_t)>&& onLongPress, std::function<void(int32_t)>&& onDragStart,
169         std::function<void(int32_t, int32_t)>&& onMoveThrough, std::function<void(int32_t)>&& onDrop);
170     void SetOnMove(std::function<void(int32_t, int32_t)>&& onMove);
171     void MoveData(int32_t from, int32_t to) override;
172     void FireOnMove(int32_t from, int32_t to) override;
173     RefPtr<FrameNode> GetFrameNode(int32_t index) override;
174     int32_t GetFrameNodeIndex(const RefPtr<FrameNode>& node, bool isExpanded = true) override;
175     void InitDragManager(const RefPtr<FrameNode>& childNode);
176     void InitAllChilrenDragManager(bool init);
177 
178     /**
179      * @brief Notify the change of dataSource to parent.
180      *
181      * @param index the position of change.
182      * @param count the count of change in [index].
183      * @param notificationType the type of notification.
184      */
185     void NotifyChangeWithCount(int32_t index, int32_t count, NotificationType notificationType) const;
186 
187     /**
188      * @brief Parse OnDatasetChange for NotifyCountChange.
189      *
190      * @param dataOperations bulk change operations.
191      */
192     void ParseOperations(const std::list<V2::Operation>& dataOperations);
193 
194     void EnablePreBuild(bool enable);
195 protected:
196     void UpdateChildrenFreezeState(bool isFreeze, bool isForceUpdateFreezeVaule = false) override;
197 private:
OnAttachToMainTree(bool recursive)198     void OnAttachToMainTree(bool recursive) override
199     {
200         UINode::OnAttachToMainTree(recursive);
201         RegisterBuilderListener();
202         if (builder_) {
203             for (const auto& item : builder_->GetCachedUINodeMap()) {
204                 if (item.second.second != nullptr) {
205                     builder_->ProcessOffscreenNode(item.second.second, false);
206                 }
207             }
208         }
209     }
210 
211     void OnDetachFromMainTree(bool recursive, PipelineContext* context = nullptr) override
212     {
213         UINode::OnDetachFromMainTree(recursive, context);
214         if (builder_) {
215             auto tempExpiringItem = builder_->GetCachedUINodeMap();
216             for (const auto& [key, child] : tempExpiringItem) {
217                 if (child.second != nullptr) {
218                     child.second->DetachFromMainTree(recursive);
219                     builder_->ProcessOffscreenNode(child.second, true);
220                 }
221             }
222         }
223     }
224 
OnOffscreenProcess(bool recursive)225     void OnOffscreenProcess(bool recursive) override
226     {
227         UINode::OnOffscreenProcess(recursive);
228         RegisterBuilderListener();
229     }
230 
OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>> & visibleList)231     void OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList) override
232     {
233         // LazyForEachNode::GetChildren() may add some children to disappearingChildren_, execute earlier to ensure
234         // disappearingChildren_ is correct before calling GenerateOneDepthVisibleFrameWithTransition.
235         GetChildren();
236         UINode::GenerateOneDepthVisibleFrameWithTransition(visibleList);
237     }
238 
239     // The index values of the start and end of the current children nodes and the corresponding keys.
240     std::list<std::optional<std::string>> ids_;
241     std::list<int32_t> predictItems_;
242     std::optional<LayoutConstraintF> itemConstraint_;
243     bool requestLongPredict_ = true;
244     bool isRegisterListener_ = false;
245     bool isLoop_ = false;
246 
247     mutable std::list<RefPtr<UINode>> tempChildren_;
248     mutable std::list<RefPtr<UINode>> children_;
249     mutable bool needPredict_ = false;
250     mutable std::list<RefPtr<UINode>> childrenWithCache_;
251     bool needMarkParent_ = true;
252     bool isActive_ = true;
253     int32_t startIndex_ = 0;
254     int32_t count_ = 0;
255 
256     RefPtr<LazyForEachBuilder> builder_;
257 
258     ACE_DISALLOW_COPY_AND_MOVE(LazyForEachNode);
259 };
260 
261 } // namespace OHOS::Ace::NG
262 
263 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_LAZY_FOR_EACH_NODE_H