• 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 #include "core/components_ng/pattern/waterflow/layout/water_flow_layout_algorithm_base.h"
17 
18 #include "core/components_ng/pattern/waterflow/water_flow_pattern.h"
19 
20 namespace OHOS::Ace::NG {
PreloadItems(LayoutWrapper * host,const RefPtr<WaterFlowLayoutInfoBase> & info,int32_t cacheCount)21 void WaterFlowLayoutBase::PreloadItems(
22     LayoutWrapper* host, const RefPtr<WaterFlowLayoutInfoBase>& info, int32_t cacheCount)
23 {
24     if (cacheCount <= 0) {
25         return;
26     }
27     auto frameNode = host->GetHostNode();
28     CHECK_NULL_VOID(frameNode);
29     auto pattern = frameNode->GetPattern<WaterFlowPattern>();
30     CHECK_NULL_VOID(pattern);
31     const bool taskRegistered = !pattern->PreloadListEmpty();
32     pattern->SetPreloadList(GeneratePreloadList(info, host, cacheCount));
33     if (pattern->PreloadListEmpty()) {
34         return;
35     }
36 
37     pattern->SetCacheLayoutAlgo(Claim(this));
38     if (taskRegistered) {
39         return;
40     }
41     PostIdleTask(frameNode);
42 }
43 
GeneratePreloadList(const RefPtr<WaterFlowLayoutInfoBase> & info,LayoutWrapper * host,int32_t cacheCount)44 std::list<int32_t> WaterFlowLayoutBase::GeneratePreloadList(
45     const RefPtr<WaterFlowLayoutInfoBase>& info, LayoutWrapper* host, int32_t cacheCount)
46 {
47     std::list<int32_t> preloadList;
48     const int32_t endBound = std::min(info->ItemCnt(host->GetTotalChildCount()) - 1, info->endIndex_ + cacheCount);
49     for (int32_t i = info->endIndex_ + 1; i <= endBound; ++i) {
50         if (!host->GetChildByIndex(info->NodeIdx(i), true)) {
51             preloadList.emplace_back(i);
52         }
53     }
54 
55     const int32_t startBound = std::max(0, info->startIndex_ - cacheCount);
56     for (int32_t i = info->FirstIdx() - 1; i >= startBound; --i) {
57         if (!host->GetChildByIndex(info->NodeIdx(i), true)) {
58             preloadList.emplace_back(i);
59         }
60     }
61     return preloadList;
62 }
63 
PostIdleTask(const RefPtr<FrameNode> & frameNode)64 void WaterFlowLayoutBase::PostIdleTask(const RefPtr<FrameNode>& frameNode)
65 {
66     auto* context = frameNode->GetContext();
67     CHECK_NULL_VOID(context);
68     context->AddPredictTask([weak = WeakPtr(frameNode)](int64_t deadline, bool canUseLongPredictTask) {
69         auto host = weak.Upgrade();
70         CHECK_NULL_VOID(host);
71         auto pattern = host->GetPattern<WaterFlowPattern>();
72         CHECK_NULL_VOID(pattern);
73 
74         auto&& algo = pattern->GetCacheLayoutAlgo();
75         CHECK_NULL_VOID(algo);
76         algo->StartCacheLayout();
77 
78         bool needMarkDirty = false;
79         auto items = pattern->MovePreloadList();
80         for (auto it = items.begin(); it != items.end(); ++it) {
81             if (GetSysTimestamp() > deadline) {
82                 pattern->SetPreloadList(std::list<int32_t>(it, items.end()));
83                 PostIdleTask(host);
84                 break;
85             }
86             ACE_SCOPED_TRACE("Preload FlowItem %d", *it);
87             ScopedLayout scope(host->GetContext());
88             needMarkDirty |= algo->AppendCacheItem(RawPtr(host), *it, deadline);
89         }
90         if (needMarkDirty) {
91             host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
92         }
93         algo->EndCacheLayout();
94     });
95 }
96 
GetUpdateIdx(LayoutWrapper * host,int32_t footerIdx)97 int32_t WaterFlowLayoutBase::GetUpdateIdx(LayoutWrapper* host, int32_t footerIdx)
98 {
99     int32_t updateIdx = host->GetHostNode()->GetChildrenUpdated();
100     if (updateIdx > 0 && footerIdx == 0) {
101         --updateIdx;
102     }
103     return updateIdx;
104 }
105 } // namespace OHOS::Ace::NG
106