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