• 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(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