• 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()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, 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 protected:
194     void UpdateChildrenFreezeState(bool isFreeze, bool isForceUpdateFreezeVaule = false) override;
195 private:
OnAttachToMainTree(bool recursive)196     void OnAttachToMainTree(bool recursive) override
197     {
198         UINode::OnAttachToMainTree(recursive);
199         RegisterBuilderListener();
200         if (builder_) {
201             for (const auto& item : builder_->GetCachedUINodeMap()) {
202                 if (item.second.second != nullptr) {
203                     builder_->ProcessOffscreenNode(item.second.second, false);
204                 }
205             }
206         }
207     }
208 
209     void OnDetachFromMainTree(bool recursive, PipelineContext* context = nullptr) override
210     {
211         UINode::OnDetachFromMainTree(recursive, context);
212         if (builder_) {
213             auto tempExpiringItem = builder_->GetCachedUINodeMap();
214             for (const auto& [key, child] : tempExpiringItem) {
215                 if (child.second != nullptr) {
216                     child.second->DetachFromMainTree(recursive);
217                     builder_->ProcessOffscreenNode(child.second, true);
218                 }
219             }
220         }
221     }
222 
OnOffscreenProcess(bool recursive)223     void OnOffscreenProcess(bool recursive) override
224     {
225         UINode::OnOffscreenProcess(recursive);
226         RegisterBuilderListener();
227     }
228 
OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>> & visibleList)229     void OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList) override
230     {
231         // LazyForEachNode::GetChildren() may add some children to disappearingChildren_, execute earlier to ensure
232         // disappearingChildren_ is correct before calling GenerateOneDepthVisibleFrameWithTransition.
233         GetChildren();
234         UINode::GenerateOneDepthVisibleFrameWithTransition(visibleList);
235     }
236 
237     // The index values of the start and end of the current children nodes and the corresponding keys.
238     std::list<std::optional<std::string>> ids_;
239     std::list<int32_t> predictItems_;
240     std::optional<LayoutConstraintF> itemConstraint_;
241     bool requestLongPredict_ = true;
242     bool isRegisterListener_ = false;
243     bool isLoop_ = false;
244 
245     mutable std::list<RefPtr<UINode>> tempChildren_;
246     mutable std::list<RefPtr<UINode>> children_;
247     mutable bool needPredict_ = false;
248     bool needMarkParent_ = true;
249     bool isActive_ = true;
250     int32_t startIndex_ = 0;
251     int32_t count_ = 0;
252 
253     RefPtr<LazyForEachBuilder> builder_;
254 
255     ACE_DISALLOW_COPY_AND_MOVE(LazyForEachNode);
256 };
257 
258 } // namespace OHOS::Ace::NG
259 
260 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_LAZY_FOR_EACH_NODE_H