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