• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_REPEAT_VIRTUAL_SCROLL_NODE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_REPEAT_VIRTUAL_SCROLL_NODE_H
18 
19 #include <cstdint>
20 #include <list>
21 #include <string>
22 #include <functional>
23 
24 #include "base/memory/referenced.h"
25 #include "base/utils/macros.h"
26 #include "core/components_ng/base/ui_node.h"
27 #include "core/components_ng/pattern/custom/custom_node.h"
28 #include "core/components_ng/syntax/for_each_base_node.h"
29 #include "core/components_ng/syntax/repeat_virtual_scroll_caches.h"
30 
31 namespace OHOS::Ace::NG {
32 struct OffscreenItems {
33     int32_t from = -1;
34     int32_t to = -1;
35 };
36 
37 class ACE_EXPORT RepeatVirtualScrollNode : public ForEachBaseNode {
38     DECLARE_ACE_TYPE(RepeatVirtualScrollNode, ForEachBaseNode);
39 
40 public:
41     static RefPtr<RepeatVirtualScrollNode> GetOrCreateRepeatNode(int32_t nodeId, uint32_t totalCount,
42         const std::map<std::string, std::pair<bool, uint32_t>>& templateCachedCountMap,
43         const std::function<void(uint32_t)>& onCreateNode,
44         const std::function<void(const std::string&, uint32_t)>& onUpdateNode,
45         const std::function<std::list<std::string>(uint32_t, uint32_t)>& onGetKeys4Range,
46         const std::function<std::list<std::string>(uint32_t, uint32_t)>& onGetTypes4Range,
47         const std::function<void(int32_t, int32_t)>& onSetActiveRange,
48         bool reusable = true);
49 
50     RepeatVirtualScrollNode(int32_t nodeId, int32_t totalCount,
51         const std::map<std::string, std::pair<bool, uint32_t>>& templateCacheCountMap,
52         const std::function<void(uint32_t)>& onCreateNode,
53         const std::function<void(const std::string&, uint32_t)>& onUpdateNode,
54         const std::function<std::list<std::string>(uint32_t, uint32_t)>& onGetKeys4Range,
55         const std::function<std::list<std::string>(uint32_t, uint32_t)>& onGetTypes4Range,
56         const std::function<void(int32_t, int32_t)>& onSetActiveRange,
57         bool reusable = true);
58 
59     ~RepeatVirtualScrollNode() override = default;
60 
61     void UpdateTotalCount(uint32_t totalCount);
62 
63     // Number of children that Repeat can product
64     // returns TotalCount
65     int32_t FrameCount() const override;
66 
67     // called from TS upon Repeat rerender
68     void UpdateRenderState(bool visibleItemsChanged);
69 
70     /**
71      * GetChildren re-assembles children_ and cleanup the L1 cache
72      * active items remain in L1 cache and are added to RepeatVirtualScroll.children_
73      * inactive items are moved from L1 to L2 cache, not added to children_
74      * function returns children_
75      * function runs as part of idle task
76      */
77     const std::list<RefPtr<UINode>>& GetChildren(bool notDetach = false) const override;
78 
79     void OnRecycle() override;
80     void OnReuse() override;
81 
82     /**
83      * scenario: called by layout informs:
84      *   - start: the first visible index
85      *   - end: the last visible index
86      *   - cacheStart: number of items cached before start
87      *   - cacheEnd: number of items cached after end
88      *
89      * Total L1 cache includes items from start-cacheStart to end+cacheEnd,
90      * but the active items are only start...end.
91      *
92      * those items with index in range [ start ... end ] are marked active
93      * those out of range marked inactive.
94      *
95      * those items out of cached range are removed from L1
96      * requests idle task
97      */
98     void DoSetActiveChildRange(
99         int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCache = false) override;
100 
101     /**
102      * those items with index in cachedItems are marked active
103      * those items with index in cachedItems are marked inactive
104      * baseIndex is repeat first node index
105      */
106     void DoSetActiveChildRange(
107         const std::set<int32_t>& activeItems, const std::set<int32_t>& cachedItems, int32_t baseIndex) override;
108 
109     // largely unknown when it is expected to be called
110     // meant to inform which items with index [ from .. to ] can be recycled / updated
111     void RecycleItems(int32_t from, int32_t to) override;
112 
113     // Called by parent generate frame child.
114     void SetNodeIndexOffset(int32_t start, int32_t count) override;
115 
116     /** Called by Layout to request ListItem and child subtree
117      for given index
118      either returns existing item for index from L1 or L2 cache, or gets a new item created
119      update of L2 cache item to new index)
120      result is in L1 cache if isCache is false, and L2 cache if isCache is true.
121 
122      meaning of parameters
123      needBuild: true - if found in cache, then return, if not in cache then return newly build
124                 false: - if found in cache, then return, if not found in cache then return nullptr
125      isCache: true indicates prebuild item (only used by List/Grid/Waterflow, this item should go to L2 cache,
126             do not add to the tree,
127             isCaxche==false this item is for display or near display area
128     addToRenderTree: true  - set it to active state, call SetActive
129     */
130     RefPtr<UINode> GetFrameChildByIndex(
131         uint32_t index, bool needBuild, bool isCache = false, bool addToRenderTree = false) override;
132 
IsAtomicNode()133     bool IsAtomicNode() const override
134     {
135         return false;
136     }
137 
138     // used for drag move operation.
139     void SetOnMove(std::function<void(int32_t, int32_t)>&& onMove);
140     void MoveData(int32_t from, int32_t to) override;
141     RefPtr<FrameNode> GetFrameNode(int32_t index) override;
142     int32_t GetFrameNodeIndex(const RefPtr<FrameNode>& node, bool isExpanded = true) override;
143     void InitDragManager(const RefPtr<UINode>& childNode);
144     void InitAllChildrenDragManager(bool init);
145 
146     void OnConfigurationUpdate(const ConfigurationChange& configurationChange) override;
147 
148     void SetJSViewActive(bool active = true, bool isLazyForEachNode = false, bool isReuse = false) override
149     {
150         const auto& children = caches_.GetAllNodes();
151         for (const auto& [key, child] : children) {
152             child.item->SetJSViewActive(active);
153         }
154         isActive_ = active;
155     }
156 
157     void SetDestroying(bool isDestroying = true, bool cleanStatus = true) override
158     {
159         for (const auto& [key, child] : caches_.GetAllNodes()) {
160             if (child.item->IsReusableNode()) {
161                 child.item->SetDestroying(isDestroying, false);
162             } else {
163                 child.item->SetDestroying(isDestroying, cleanStatus);
164             }
165         }
166     }
167 
PaintDebugBoundaryTreeAll(bool flag)168     void PaintDebugBoundaryTreeAll(bool flag) override
169     {
170         const auto& children = caches_.GetAllNodes();
171         for (const auto& [key, child] : children) {
172             child.item->PaintDebugBoundaryTreeAll(flag);
173         }
174     }
SetIsLoop(bool isLoop)175     void SetIsLoop(bool isLoop)
176     {
177         isLoop_ = isLoop;
178     }
OnSetCacheCount(int32_t cacheCount,const std::optional<LayoutConstraintF> & itemConstraint)179     void OnSetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint) override
180     {
181         containerCacheCount_ = cacheCount;
182     }
183 protected:
184     void UpdateChildrenFreezeState(bool isFreeze, bool isForceUpdateFreezeVaule = false) override;
185 private:
186     void PostIdleTask();
187 
188     // try to find entry for given index in L1 or L2 cache
GetFromCaches(uint32_t forIndex)189     RefPtr<UINode> GetFromCaches(uint32_t forIndex)
190     {
191         return caches_.GetCachedNode4Index(forIndex);
192     }
193 
194     // get farthest (from L1 indexes) index in L2 cache or -1
195     int32_t GetFarthestL2CacheIndex();
196 
197     // drop UINode with given key from L1 but keep in L2
198     // detach from tree and request tree sync
199     void DropFromL1(const std::string& key);
200 
201     // check whether UINode (index) is in the L1 cache range
202     bool CheckNode4IndexInL1(int32_t index, int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd,
203         RefPtr<FrameNode>& frameNode);
204 
205     // process params sent by parent
206     void CheckActiveRange(int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd);
207 
208     // RepeatVirtualScrollNode is not instance of FrameNode
209     // needs to propagate active state to all items inside
210     bool isActive_ = true;
211 
212     // size of data source when all data items loaded
213     uint32_t totalCount_ = 0;
214 
215     // loop property of the parent container
216     bool isLoop_ = false;
217 
218     // caches:
219     mutable RepeatVirtualScrollCaches caches_;
220 
221     // get active child range
222     std::function<void(int32_t, int32_t)> onSetActiveRange_;
223 
224     // used by one of the unknown functions
225     std::list<std::string> ids_;
226 
227     // re-assembled by GetChildren called from idle task
228     mutable std::list<RefPtr<UINode>> children_;
229 
230     // true in the time from requesting idle / predict task until exec predict tsk.
231     bool postUpdateTaskHasBeenScheduled_;
232 
233     // STATE_MGMT_NOTE: What are these?
234     OffscreenItems offscreenItems_;
235     int32_t startIndex_ = 0;
236 
237     // reuse node in L2 cache or not
238     bool reusable_ = true;
239     int32_t containerCacheCount_ = 0;
240 
241     ACE_DISALLOW_COPY_AND_MOVE(RepeatVirtualScrollNode);
242 };
243 } // namespace OHOS::Ace::NG
244 
245 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_REPEAT_VIRTUAL_SCROLL_NODE_H
246