• 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     const std::list<RefPtr<UINode>>& GetChildrenForInspector(bool needCacheNode = false) const override;
80 
81     void OnRecycle() override;
82     void OnReuse() override;
83 
84     /**
85      * scenario: called by layout informs:
86      *   - start: the first visible index
87      *   - end: the last visible index
88      *   - cacheStart: number of items cached before start
89      *   - cacheEnd: number of items cached after end
90      *
91      * Total L1 cache includes items from start-cacheStart to end+cacheEnd,
92      * but the active items are only start...end.
93      *
94      * those items with index in range [ start ... end ] are marked active
95      * those out of range marked inactive.
96      *
97      * those items out of cached range are removed from L1
98      * requests idle task
99      */
100     void DoSetActiveChildRange(
101         int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd, bool showCache = false) override;
102 
103     /**
104      * those items with index in cachedItems are marked active
105      * those items with index in cachedItems are marked inactive
106      * baseIndex is repeat first node index
107      */
108     void DoSetActiveChildRange(
109         const std::set<int32_t>& activeItems, const std::set<int32_t>& cachedItems, int32_t baseIndex) override;
110 
111     // largely unknown when it is expected to be called
112     // meant to inform which items with index [ from .. to ] can be recycled / updated
113     void RecycleItems(int32_t from, int32_t to) override;
114 
115     // Called by parent generate frame child.
116     void SetNodeIndexOffset(int32_t start, int32_t count) override;
117 
118     /** Called by Layout to request ListItem and child subtree
119      for given index
120      either returns existing item for index from L1 or L2 cache, or gets a new item created
121      update of L2 cache item to new index)
122      result is in L1 cache if isCache is false, and L2 cache if isCache is true.
123 
124      meaning of parameters
125      needBuild: true - if found in cache, then return, if not in cache then return newly build
126                 false: - if found in cache, then return, if not found in cache then return nullptr
127      isCache: true indicates prebuild item (only used by List/Grid/Waterflow, this item should go to L2 cache,
128             do not add to the tree,
129             isCaxche==false this item is for display or near display area
130     addToRenderTree: true  - set it to active state, call SetActive
131     */
132     RefPtr<UINode> GetFrameChildByIndex(
133         uint32_t index, bool needBuild, bool isCache = false, bool addToRenderTree = false) override;
134 
IsAtomicNode()135     bool IsAtomicNode() const override
136     {
137         return false;
138     }
139 
140     // used for drag move operation.
141     void SetOnMove(std::function<void(int32_t, int32_t)>&& onMove);
142     void MoveData(int32_t from, int32_t to) override;
143     RefPtr<FrameNode> GetFrameNode(int32_t index) override;
144     int32_t GetFrameNodeIndex(const RefPtr<FrameNode>& node, bool isExpanded = true) override;
145     void InitDragManager(const RefPtr<UINode>& childNode);
146     void InitAllChildrenDragManager(bool init);
147 
148     void OnConfigurationUpdate(const ConfigurationChange& configurationChange) override;
149 
150     void SetJSViewActive(bool active = true, bool isLazyForEachNode = false, bool isReuse = false) override
151     {
152         const auto& children = caches_.GetAllNodes();
153         for (const auto& [key, child] : children) {
154             child.item->SetJSViewActive(active);
155         }
156         isActive_ = active;
157     }
158 
159     void SetDestroying(bool isDestroying = true, bool cleanStatus = true) override
160     {
161         for (const auto& [key, child] : caches_.GetAllNodes()) {
162             if (child.item->IsReusableNode()) {
163                 child.item->SetDestroying(isDestroying, false);
164             } else {
165                 child.item->SetDestroying(isDestroying, cleanStatus);
166             }
167         }
168     }
169 
PaintDebugBoundaryTreeAll(bool flag)170     void PaintDebugBoundaryTreeAll(bool flag) override
171     {
172         const auto& children = caches_.GetAllNodes();
173         for (const auto& [key, child] : children) {
174             child.item->PaintDebugBoundaryTreeAll(flag);
175         }
176     }
SetIsLoop(bool isLoop)177     void SetIsLoop(bool isLoop)
178     {
179         isLoop_ = isLoop;
180     }
OnSetCacheCount(int32_t cacheCount,const std::optional<LayoutConstraintF> & itemConstraint)181     void OnSetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint) override
182     {
183         containerCacheCount_ = cacheCount;
184     }
185 protected:
186     void UpdateChildrenFreezeState(bool isFreeze, bool isForceUpdateFreezeVaule = false) override;
187 private:
188     void PostIdleTask();
189 
190     // try to find entry for given index in L1 or L2 cache
GetFromCaches(uint32_t forIndex)191     RefPtr<UINode> GetFromCaches(uint32_t forIndex)
192     {
193         return caches_.GetCachedNode4Index(forIndex);
194     }
195 
196     // get farthest (from L1 indexes) index in L2 cache or -1
197     int32_t GetFarthestL2CacheIndex();
198 
199     // drop UINode with given key from L1 but keep in L2
200     // detach from tree and request tree sync
201     void DropFromL1(const std::string& key);
202 
203     // check whether UINode (index) is in the L1 cache range
204     bool CheckNode4IndexInL1(int32_t index, int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd,
205         RefPtr<FrameNode>& frameNode);
206 
207     // process params sent by parent
208     void CheckActiveRange(int32_t start, int32_t end, int32_t cacheStart, int32_t cacheEnd);
209 
210     // RepeatVirtualScrollNode is not instance of FrameNode
211     // needs to propagate active state to all items inside
212     bool isActive_ = true;
213 
214     // size of data source when all data items loaded
215     uint32_t totalCount_ = 0;
216 
217     // loop property of the parent container
218     bool isLoop_ = false;
219 
220     // caches:
221     mutable RepeatVirtualScrollCaches caches_;
222 
223     // get active child range
224     std::function<void(int32_t, int32_t)> onSetActiveRange_;
225 
226     // used by one of the unknown functions
227     std::list<std::string> ids_;
228 
229     // re-assembled by GetChildren called from idle task
230     mutable std::list<RefPtr<UINode>> children_;
231 
232     // true in the time from requesting idle / predict task until exec predict tsk.
233     bool postUpdateTaskHasBeenScheduled_;
234 
235     // STATE_MGMT_NOTE: What are these?
236     OffscreenItems offscreenItems_;
237     int32_t startIndex_ = 0;
238 
239     // reuse node in L2 cache or not
240     bool reusable_ = true;
241     int32_t containerCacheCount_ = 0;
242 
243     ACE_DISALLOW_COPY_AND_MOVE(RepeatVirtualScrollNode);
244 };
245 } // namespace OHOS::Ace::NG
246 
247 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SYNTAX_REPEAT_VIRTUAL_SCROLL_NODE_H
248