修复ListItemGroup组件CacheCount节点回收时机错误问题

Signed-off-by: yeyinglong_admin <yeyinglong@hisilicon.com>
This commit is contained in:
yeyinglong_admin 2024-07-02 22:14:38 +08:00
parent 0cbb48378c
commit 736c629e46
8 changed files with 117 additions and 88 deletions

View File

@ -1140,8 +1140,8 @@ void ListItemGroupLayoutAlgorithm::MeasureCacheItem(LayoutWrapper* layoutWrapper
ListItemGroupCacheParam& cacheParam = cacheParam_.value(); ListItemGroupCacheParam& cacheParam = cacheParam_.value();
if (cacheParam.forward) { if (cacheParam.forward) {
int32_t endIndex = itemPosition_.empty() ? -1 : itemPosition_.rbegin()->first; int32_t endIndex = itemPosition_.empty() ? -1 : itemPosition_.rbegin()->first;
int32_t limit = std::min(endIndex + cacheParam.cacheCount, totalItemCount_ - 1); int32_t limit = std::min(endIndex + cacheParam.cacheCount * lanes_, totalItemCount_ - 1);
int32_t currentIndex = cacheParam.currCachedIndex + 1; int32_t currentIndex = std::clamp(cacheParam.forwardCachedIndex, endIndex, limit) + 1;
for (; currentIndex <= limit; currentIndex++) { for (; currentIndex <= limit; currentIndex++) {
auto item = layoutWrapper->GetOrCreateChildByIndex(currentIndex + itemStartIndex_, false, true); auto item = layoutWrapper->GetOrCreateChildByIndex(currentIndex + itemStartIndex_, false, true);
auto frameNode = AceType::DynamicCast<FrameNode>(item); auto frameNode = AceType::DynamicCast<FrameNode>(item);
@ -1160,11 +1160,11 @@ void ListItemGroupLayoutAlgorithm::MeasureCacheItem(LayoutWrapper* layoutWrapper
item->Measure(childLayoutConstraint_); item->Measure(childLayoutConstraint_);
cachedItem_.push_back(currentIndex); cachedItem_.push_back(currentIndex);
} }
cacheParam.currCachedIndex = std::min(currentIndex - 1, limit); cacheParam.forwardCachedIndex = std::min(currentIndex - 1, limit);
} else { } else {
int32_t startIndex = itemPosition_.empty() ? totalItemCount_ : itemPosition_.begin()->first; int32_t startIndex = itemPosition_.empty() ? totalItemCount_ : itemPosition_.begin()->first;
int32_t limit = std::max(startIndex - cacheParam.cacheCount, 0); int32_t limit = std::max(startIndex - cacheParam.cacheCount * lanes_, 0);
int32_t currentIndex = cacheParam.currCachedIndex - 1; int32_t currentIndex = std::clamp(cacheParam.backwardCachedIndex, limit, startIndex) - 1;
for (; currentIndex >= limit; currentIndex--) { for (; currentIndex >= limit; currentIndex--) {
auto item = layoutWrapper->GetOrCreateChildByIndex(currentIndex + itemStartIndex_, false, true); auto item = layoutWrapper->GetOrCreateChildByIndex(currentIndex + itemStartIndex_, false, true);
auto frameNode = AceType::DynamicCast<FrameNode>(item); auto frameNode = AceType::DynamicCast<FrameNode>(item);
@ -1183,7 +1183,7 @@ void ListItemGroupLayoutAlgorithm::MeasureCacheItem(LayoutWrapper* layoutWrapper
item->Measure(childLayoutConstraint_); item->Measure(childLayoutConstraint_);
cachedItem_.push_back(currentIndex); cachedItem_.push_back(currentIndex);
} }
cacheParam.currCachedIndex = std::max(currentIndex + 1, limit); cacheParam.backwardCachedIndex = std::max(currentIndex + 1, limit);
} }
} }

View File

@ -43,7 +43,8 @@ struct ListItemGroupInfo {
struct ListItemGroupCacheParam { struct ListItemGroupCacheParam {
bool forward = true; bool forward = true;
int32_t cacheCount = 0; int32_t cacheCount = 0;
int32_t currCachedIndex = -1; int32_t forwardCachedIndex = -1;
int32_t backwardCachedIndex = INT_MAX;
int64_t deadline = 0; int64_t deadline = 0;
}; };

View File

@ -155,11 +155,8 @@ bool ListItemGroupPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>&
} }
auto cacheParam = layoutAlgorithm->GetCacheParam(); auto cacheParam = layoutAlgorithm->GetCacheParam();
if (cacheParam) { if (cacheParam) {
if (cacheParam.value().forward) { forwardCachedIndex_ = cacheParam.value().forwardCachedIndex;
forwardCachedIndex_ = cacheParam.value().currCachedIndex; backwardCachedIndex_ = cacheParam.value().backwardCachedIndex;
} else {
backwardCachedIndex_ = cacheParam.value().currCachedIndex;
}
layoutAlgorithm->SetCacheParam(std::nullopt); layoutAlgorithm->SetCacheParam(std::nullopt);
} }
auto listLayoutProperty = host->GetLayoutProperty<ListItemGroupLayoutProperty>(); auto listLayoutProperty = host->GetLayoutProperty<ListItemGroupLayoutProperty>();
@ -363,19 +360,39 @@ void ListItemGroupPattern::CalculateItemStartIndex()
itemStartIndex_ = itemStartIndex; itemStartIndex_ = itemStartIndex;
} }
int32_t ListItemGroupPattern::GetForwardCachedIndex(int32_t cacheCount) void ListItemGroupPattern::UpdateActiveChildRange(bool forward, int32_t cacheCount)
{ {
int32_t endIndex = itemPosition_.empty() ? -1 : itemPosition_.rbegin()->first; auto host = GetHost();
int32_t limit = std::min(endIndex + cacheCount, itemTotalCount_ - 1); CHECK_NULL_VOID(host);
forwardCachedIndex_ = std::clamp(forwardCachedIndex_, endIndex, limit); if (forward) {
host->SetActiveChildRange(-1, -1, 0, cacheCount);
} else {
int32_t index = itemTotalCount_ + itemStartIndex_;
host->SetActiveChildRange(index, index, cacheCount, 0);
}
}
int32_t ListItemGroupPattern::UpdateForwardCachedIndex(int32_t cacheCount, bool outOfView)
{
int32_t endIndex = (outOfView || itemPosition_.empty()) ? -1 : itemPosition_.rbegin()->first;
int32_t limit = std::min(endIndex + cacheCount * lanes_, itemTotalCount_ - 1);
int32_t forwardCachedIndex = std::clamp(forwardCachedIndex_, endIndex, limit);
if (outOfView && forwardCachedIndex < forwardCachedIndex_) {
UpdateActiveChildRange(true, forwardCachedIndex + 1);
}
forwardCachedIndex_ = forwardCachedIndex;
return forwardCachedIndex_; return forwardCachedIndex_;
} }
int32_t ListItemGroupPattern::GetBackwardCachedIndex(int32_t cacheCount) int32_t ListItemGroupPattern::UpdateBackwardCachedIndex(int32_t cacheCount, bool outOfView)
{ {
int32_t startIndex = itemPosition_.empty() ? itemTotalCount_ : itemPosition_.begin()->first; int32_t startIndex = (outOfView || itemPosition_.empty()) ? itemTotalCount_ : itemPosition_.begin()->first;
int32_t limit = std::max(startIndex - cacheCount, 0); int32_t limit = std::max(startIndex - cacheCount * lanes_, 0);
backwardCachedIndex_ = std::clamp(backwardCachedIndex_, limit, startIndex); int32_t backwardCachedIndex = std::clamp(backwardCachedIndex_, limit, startIndex);
if (outOfView && backwardCachedIndex > backwardCachedIndex_) {
UpdateActiveChildRange(false, itemTotalCount_ - backwardCachedIndex);
}
backwardCachedIndex_ = backwardCachedIndex;
return backwardCachedIndex_; return backwardCachedIndex_;
} }
@ -397,11 +414,11 @@ void ListItemGroupPattern::LayoutCache(const LayoutConstraintF& constraint,
CHECK_NULL_VOID(layoutAlgorithmWrapper); CHECK_NULL_VOID(layoutAlgorithmWrapper);
auto itemGroup = AceType::DynamicCast<ListItemGroupLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm()); auto itemGroup = AceType::DynamicCast<ListItemGroupLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm());
CHECK_NULL_VOID(itemGroup); CHECK_NULL_VOID(itemGroup);
int32_t currentIndex = forward ? GetForwardCachedIndex(cached) : GetBackwardCachedIndex(cacheCount);
ListItemGroupCacheParam param = { ListItemGroupCacheParam param = {
.forward = forward, .forward = forward,
.cacheCount = cacheCount, .cacheCount = cacheCount,
.currCachedIndex = currentIndex, .forwardCachedIndex = forwardCachedIndex_,
.backwardCachedIndex = backwardCachedIndex_,
.deadline = deadline, .deadline = deadline,
}; };
itemGroup->SetCacheParam(param); itemGroup->SetCacheParam(param);

View File

@ -207,8 +207,9 @@ public:
void ResetChildrenSize(); void ResetChildrenSize();
void CalculateItemStartIndex(); void CalculateItemStartIndex();
int32_t GetForwardCachedIndex(int32_t cacheCount); void UpdateActiveChildRange(bool forward, int32_t cacheCount);
int32_t GetBackwardCachedIndex(int32_t cacheCount); int32_t UpdateForwardCachedIndex(int32_t cacheCount, bool outOfView);
int32_t UpdateBackwardCachedIndex(int32_t cacheCount, bool outOfView);
void LayoutCache(const LayoutConstraintF& constraint, bool forward, int64_t deadline, int32_t cached); void LayoutCache(const LayoutConstraintF& constraint, bool forward, int64_t deadline, int32_t cached);
private: private:
bool IsNeedInitClickEventRecorder() const override bool IsNeedInitClickEventRecorder() const override
@ -243,7 +244,7 @@ private:
std::set<int32_t> pressedItem_; std::set<int32_t> pressedItem_;
bool layouted_ = false; bool layouted_ = false;
int32_t backwardCachedIndex_ = -1; int32_t backwardCachedIndex_ = INT_MAX;
int32_t forwardCachedIndex_ = -1; int32_t forwardCachedIndex_ = -1;
ListItemGroupLayoutAlgorithm::PositionMap itemPosition_; ListItemGroupLayoutAlgorithm::PositionMap itemPosition_;

View File

@ -242,19 +242,6 @@ void ListLanesLayoutAlgorithm::SetCacheCount(LayoutWrapper* layoutWrapper, int32
layoutWrapper->SetCacheCount(count); layoutWrapper->SetCacheCount(count);
} }
void ListLanesLayoutAlgorithm::SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheCount)
{
auto& itemPosition = GetItemPosition();
if (itemPosition.empty()) {
layoutWrapper->SetActiveChildRange(-1, -1);
return;
}
auto cacheStart = itemPosition.begin()->second.isGroup ? cacheCount : cacheCount * lanes_;
auto cacheEnd = itemPosition.rbegin()->second.isGroup ? cacheCount : cacheCount * lanes_;
layoutWrapper->SetActiveChildRange(
itemPosition.begin()->first, itemPosition.rbegin()->first, cacheStart, cacheEnd);
}
int32_t ListLanesLayoutAlgorithm::CalculateLanesParam(std::optional<float>& minLaneLength, int32_t ListLanesLayoutAlgorithm::CalculateLanesParam(std::optional<float>& minLaneLength,
std::optional<float>& maxLaneLength, int32_t lanes, std::optional<float> crossSizeOptional, float laneGutter) std::optional<float>& maxLaneLength, int32_t lanes, std::optional<float> crossSizeOptional, float laneGutter)
{ {
@ -585,12 +572,13 @@ float ListLanesLayoutAlgorithm::GetLayoutCrossAxisSize(LayoutWrapper* layoutWrap
return GetCrossAxisSize(size, axis_); return GetCrossAxisSize(size, axis_);
} }
int32_t ListLanesLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached) int32_t ListLanesLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex)
{ {
ACE_SCOPED_TRACE("LayoutCachedForward:%d,%d", cacheCount, cached); ACE_SCOPED_TRACE("LayoutCachedForward:%d,%d", cacheCount, cached);
float crossSize = GetLayoutCrossAxisSize(layoutWrapper); float crossSize = GetLayoutCrossAxisSize(layoutWrapper);
RefPtr<LayoutWrapper> wrapper; RefPtr<LayoutWrapper> wrapper;
int32_t currIndex = GetItemPosition().rbegin()->first + 1; currIndex = GetItemPosition().rbegin()->first + 1;
auto startPos = GetItemPosition().rbegin()->second.endPos + GetSpaceWidth(); auto startPos = GetItemPosition().rbegin()->second.endPos + GetSpaceWidth();
while (cached < cacheCount && currIndex <= GetMaxListItemIndex()) { while (cached < cacheCount && currIndex <= GetMaxListItemIndex()) {
ListLayoutAlgorithm::PositionMap posMap; ListLayoutAlgorithm::PositionMap posMap;
@ -622,7 +610,7 @@ int32_t ListLanesLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapp
} }
startPos = startPos + mainLen + GetSpaceWidth(); startPos = startPos + mainLen + GetSpaceWidth();
if (isGroup) { if (isGroup) {
auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount); auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount - cached, true);
if (res.first < res.second && res.first < cacheCount - cached) { if (res.first < res.second && res.first < cacheCount - cached) {
return currIndex; return currIndex;
} }
@ -635,12 +623,13 @@ int32_t ListLanesLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapp
return -1; return -1;
} }
int32_t ListLanesLayoutAlgorithm::LayoutCachedBackward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached) int32_t ListLanesLayoutAlgorithm::LayoutCachedBackward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex)
{ {
ACE_SCOPED_TRACE("LayoutCachedBackward:%d,%d", cacheCount, cached); ACE_SCOPED_TRACE("LayoutCachedBackward:%d,%d", cacheCount, cached);
float crossSize = GetLayoutCrossAxisSize(layoutWrapper); float crossSize = GetLayoutCrossAxisSize(layoutWrapper);
RefPtr<LayoutWrapper> wrapper; RefPtr<LayoutWrapper> wrapper;
int32_t currIndex = GetItemPosition().begin()->first - 1; currIndex = GetItemPosition().begin()->first - 1;
auto endPos = GetItemPosition().begin()->second.startPos - GetSpaceWidth(); auto endPos = GetItemPosition().begin()->second.startPos - GetSpaceWidth();
while (cached < cacheCount && currIndex >= 0) { while (cached < cacheCount && currIndex >= 0) {
ListLayoutAlgorithm::PositionMap posMap; ListLayoutAlgorithm::PositionMap posMap;
@ -674,13 +663,14 @@ int32_t ListLanesLayoutAlgorithm::LayoutCachedBackward(LayoutWrapper* layoutWrap
LayoutCachedALine(layoutWrapper, pos, startIndex, crossSize); LayoutCachedALine(layoutWrapper, pos, startIndex, crossSize);
} }
endPos = endPos - mainLen - GetSpaceWidth(); endPos = endPos - mainLen - GetSpaceWidth();
cached++;
if (isGroup) { if (isGroup) {
auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount); auto res = GetLayoutGroupCachedCount(wrapper, false, cacheCount - cached, true);
if (res.first < res.second && res.first < cacheCount - cached) { if (res.first < res.second && res.first < cacheCount - cached) {
return currIndex; return currIndex;
} }
cached += std::max(res.second, 1) - 1; cached += std::max(res.second, 1);
} else {
cached++;
} }
currIndex -= cnt; currIndex -= cnt;
} }

View File

@ -63,7 +63,6 @@ protected:
int32_t GetLanesFloor(LayoutWrapper* layoutWrapper, int32_t index) override; int32_t GetLanesFloor(LayoutWrapper* layoutWrapper, int32_t index) override;
int32_t GetLanesCeil(LayoutWrapper* layoutWrapper, int32_t index) override; int32_t GetLanesCeil(LayoutWrapper* layoutWrapper, int32_t index) override;
void SetCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount) override; void SetCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount) override;
void SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheCount) override;
private: private:
static void ModifyLaneLength( static void ModifyLaneLength(
@ -78,8 +77,10 @@ private:
void LayoutCachedALine(LayoutWrapper* layoutWrapper, std::pair<const int, ListItemInfo>& pos, void LayoutCachedALine(LayoutWrapper* layoutWrapper, std::pair<const int, ListItemInfo>& pos,
int32_t startIndex, float crossSize); int32_t startIndex, float crossSize);
float GetLayoutCrossAxisSize(LayoutWrapper* layoutWrapper); float GetLayoutCrossAxisSize(LayoutWrapper* layoutWrapper);
int32_t LayoutCachedForward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached) override; int32_t LayoutCachedForward(LayoutWrapper* layoutWrapper,
int32_t LayoutCachedBackward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached) override; int32_t cacheCount, int32_t cached, int32_t& currIndex) override;
int32_t LayoutCachedBackward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex) override;
static int32_t FindLanesStartIndex(LayoutWrapper* layoutWrapper, int32_t startIndex, int32_t index); static int32_t FindLanesStartIndex(LayoutWrapper* layoutWrapper, int32_t startIndex, int32_t index);
static int32_t GetLazyForEachIndex(const RefPtr<FrameNode>& host); static int32_t GetLazyForEachIndex(const RefPtr<FrameNode>& host);
void MeasureGroup(LayoutWrapper* listWrapper, const RefPtr<LayoutWrapper>& groupWrapper, void MeasureGroup(LayoutWrapper* listWrapper, const RefPtr<LayoutWrapper>& groupWrapper,

View File

@ -167,8 +167,6 @@ void ListLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
} }
} }
SetActiveChildRange(layoutWrapper, listLayoutProperty->GetCachedCountValue(1));
auto crossSize = contentIdealSize.CrossSize(axis_); auto crossSize = contentIdealSize.CrossSize(axis_);
if (crossSize.has_value() && GreaterOrEqualToInfinity(crossSize.value())) { if (crossSize.has_value() && GreaterOrEqualToInfinity(crossSize.value())) {
contentIdealSize.SetCrossSize(GetChildMaxCrossSize(layoutWrapper, axis_), axis_); contentIdealSize.SetCrossSize(GetChildMaxCrossSize(layoutWrapper, axis_), axis_);
@ -192,14 +190,14 @@ void ListLayoutAlgorithm::SetCacheCount(LayoutWrapper* layoutWrapper, int32_t ca
layoutWrapper->SetCacheCount(cacheCount); layoutWrapper->SetCacheCount(cacheCount);
} }
void ListLayoutAlgorithm::SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheCount) void ListLayoutAlgorithm::SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheStart, int32_t cacheEnd)
{ {
if (itemPosition_.empty()) { if (itemPosition_.empty()) {
layoutWrapper->SetActiveChildRange(-1, -1); layoutWrapper->SetActiveChildRange(-1, -1);
return; return;
} }
layoutWrapper->SetActiveChildRange( layoutWrapper->SetActiveChildRange(
itemPosition_.begin()->first, itemPosition_.rbegin()->first, cacheCount, cacheCount); itemPosition_.begin()->first, itemPosition_.rbegin()->first, cacheStart, cacheEnd);
} }
bool ListLayoutAlgorithm::CheckNeedMeasure(const RefPtr<LayoutWrapper>& layoutWrapper) const bool ListLayoutAlgorithm::CheckNeedMeasure(const RefPtr<LayoutWrapper>& layoutWrapper) const
@ -1320,6 +1318,24 @@ void ListLayoutAlgorithm::LayoutItem(RefPtr<LayoutWrapper>& wrapper, int32_t ind
SetListItemIndex(wrapper, index); SetListItemIndex(wrapper, index);
} }
void ListLayoutAlgorithm::ProcessCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount)
{
if (!itemPosition_.empty() && cacheCount > 0) {
auto items = LayoutCachedItemV2(layoutWrapper, cacheCount);
auto host = layoutWrapper->GetHostNode();
CHECK_NULL_VOID(host);
if (!items.empty()) {
PostIdleTaskV2(host, { items, childLayoutConstraint_, GetGroupLayoutConstraint() });
} else {
auto pattern = host->GetPattern<ListPattern>();
CHECK_NULL_VOID(pattern);
pattern->SetPredictLayoutParamV2(std::nullopt);
}
} else {
SetActiveChildRange(layoutWrapper, cacheCount, cacheCount);
}
}
void ListLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) void ListLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
{ {
auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty()); auto listLayoutProperty = AceType::DynamicCast<ListLayoutProperty>(layoutWrapper->GetLayoutProperty());
@ -1360,18 +1376,7 @@ void ListLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
pos.second.endPos -= currentOffset_; pos.second.endPos -= currentOffset_;
} }
auto cacheCount = listLayoutProperty->GetCachedCountValue(1); auto cacheCount = listLayoutProperty->GetCachedCountValue(1);
if (!itemPosition_.empty() && cacheCount > 0) { ProcessCacheCount(layoutWrapper, cacheCount);
auto items = LayoutCachedItemV2(layoutWrapper, cacheCount);
auto host = layoutWrapper->GetHostNode();
CHECK_NULL_VOID(host);
if (!items.empty()) {
PostIdleTaskV2(host, { items, childLayoutConstraint_, GetGroupLayoutConstraint() });
} else {
auto pattern = host->GetPattern<ListPattern>();
CHECK_NULL_VOID(pattern);
pattern->SetPredictLayoutParamV2(std::nullopt);
}
}
} }
float ListLayoutAlgorithm::CalculateLaneCrossOffset(float crossSize, float childCrossSize) float ListLayoutAlgorithm::CalculateLaneCrossOffset(float crossSize, float childCrossSize)
@ -1719,7 +1724,7 @@ void ListLayoutAlgorithm::PostIdleTask(RefPtr<FrameNode> frameNode, const ListPr
// return current CachedCount and max CacheCount // return current CachedCount and max CacheCount
std::pair<int32_t, int32_t> ListLayoutAlgorithm::GetLayoutGroupCachedCount( std::pair<int32_t, int32_t> ListLayoutAlgorithm::GetLayoutGroupCachedCount(
const RefPtr<LayoutWrapper>& wrapper, bool forward, int32_t cacheCount) const RefPtr<LayoutWrapper>& wrapper, bool forward, int32_t cacheCount, bool outOfView)
{ {
ACE_FUNCTION_TRACE(); ACE_FUNCTION_TRACE();
std::pair<int32_t, int32_t> res = { 0, 0 }; std::pair<int32_t, int32_t> res = { 0, 0 };
@ -1729,30 +1734,33 @@ std::pair<int32_t, int32_t> ListLayoutAlgorithm::GetLayoutGroupCachedCount(
CHECK_NULL_RETURN(groupPattern, res); CHECK_NULL_RETURN(groupPattern, res);
const auto& itemPos = groupPattern->GetItemPosition(); const auto& itemPos = groupPattern->GetItemPosition();
int32_t itemCount = groupPattern->GetTotalItemCount(); int32_t itemCount = groupPattern->GetTotalItemCount();
int32_t lanes = groupPattern->GetLanesInGroup();
lanes = lanes > 1 ? lanes : 1;
if (groupNode->CheckNeedForceMeasureAndLayout()) { if (groupNode->CheckNeedForceMeasureAndLayout()) {
groupPattern->CalculateItemStartIndex(); groupPattern->CalculateItemStartIndex();
itemCount = groupNode->GetTotalChildCount() - groupPattern->GetItemStartIndex(); itemCount = groupNode->GetTotalChildCount() - groupPattern->GetItemStartIndex();
} }
if (forward) { if (forward) {
int32_t cachedIndex = groupPattern->GetForwardCachedIndex(cacheCount); int32_t cachedIndex = groupPattern->UpdateForwardCachedIndex(cacheCount, outOfView);
int32_t endIndex = itemPos.empty() ? -1 : itemPos.rbegin()->first; int32_t endIndex = (outOfView || itemPos.empty()) ? -1 : itemPos.rbegin()->first;
res.first = cachedIndex - endIndex; res.first = (cachedIndex - endIndex) / lanes;
res.second = itemCount - 1 - endIndex; res.second = (itemCount - 1 - endIndex) / lanes;
} else { } else {
int32_t cachedIndex = groupPattern->GetBackwardCachedIndex(cacheCount); int32_t cachedIndex = groupPattern->UpdateBackwardCachedIndex(cacheCount, outOfView);
int32_t startIndex = itemPos.empty() ? itemCount : itemPos.begin()->first; int32_t startIndex = (outOfView || itemPos.empty()) ? itemCount : itemPos.begin()->first;
res.first = startIndex - cachedIndex; res.first = (startIndex - cachedIndex) / lanes;
res.second = startIndex; res.second = startIndex / lanes;
} }
return res; return res;
} }
int32_t ListLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached) int32_t ListLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex)
{ {
ACE_SCOPED_TRACE("LayoutCachedForward:%d,%d", cacheCount, cached); ACE_SCOPED_TRACE("LayoutCachedForward:%d,%d", cacheCount, cached);
auto size = layoutWrapper->GetGeometryNode()->GetFrameSize(); auto size = layoutWrapper->GetGeometryNode()->GetFrameSize();
float crossSize = GetCrossAxisSize(size, axis_); float crossSize = GetCrossAxisSize(size, axis_);
int32_t currIndex = itemPosition_.rbegin()->first + 1; currIndex = itemPosition_.rbegin()->first + 1;
auto currPos = itemPosition_.rbegin()->second.endPos + spaceWidth_; auto currPos = itemPosition_.rbegin()->second.endPos + spaceWidth_;
while (cached < cacheCount && currIndex < totalItemCount_) { while (cached < cacheCount && currIndex < totalItemCount_) {
auto wrapper = layoutWrapper->GetChildByIndex(currIndex, true); auto wrapper = layoutWrapper->GetChildByIndex(currIndex, true);
@ -1773,7 +1781,7 @@ int32_t ListLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapper, i
SyncGeometry(wrapper); SyncGeometry(wrapper);
wrapper->SetActive(false); wrapper->SetActive(false);
if (isGroup) { if (isGroup) {
auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount); auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount - cached, true);
if (res.first < res.second && res.first < cacheCount - cached) { if (res.first < res.second && res.first < cacheCount - cached) {
return currIndex; return currIndex;
} }
@ -1786,12 +1794,13 @@ int32_t ListLayoutAlgorithm::LayoutCachedForward(LayoutWrapper* layoutWrapper, i
return -1; return -1;
} }
int32_t ListLayoutAlgorithm::LayoutCachedBackward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached) int32_t ListLayoutAlgorithm::LayoutCachedBackward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex)
{ {
ACE_SCOPED_TRACE("LayoutCachedBackward:%d,%d", cacheCount, cached); ACE_SCOPED_TRACE("LayoutCachedBackward:%d,%d", cacheCount, cached);
auto size = layoutWrapper->GetGeometryNode()->GetFrameSize(); auto size = layoutWrapper->GetGeometryNode()->GetFrameSize();
float crossSize = GetCrossAxisSize(size, axis_); float crossSize = GetCrossAxisSize(size, axis_);
int32_t currIndex = itemPosition_.begin()->first - 1; currIndex = itemPosition_.begin()->first - 1;
auto currPos = itemPosition_.begin()->second.startPos - spaceWidth_; auto currPos = itemPosition_.begin()->second.startPos - spaceWidth_;
while (cached < cacheCount && currIndex >= 0) { while (cached < cacheCount && currIndex >= 0) {
auto wrapper = layoutWrapper->GetChildByIndex(currIndex, true); auto wrapper = layoutWrapper->GetChildByIndex(currIndex, true);
@ -1812,7 +1821,7 @@ int32_t ListLayoutAlgorithm::LayoutCachedBackward(LayoutWrapper* layoutWrapper,
SyncGeometry(wrapper); SyncGeometry(wrapper);
wrapper->SetActive(false); wrapper->SetActive(false);
if (isGroup) { if (isGroup) {
auto res = GetLayoutGroupCachedCount(wrapper, false, cacheCount); auto res = GetLayoutGroupCachedCount(wrapper, false, cacheCount - cached, true);
if (res.first < res.second && res.first < cacheCount - cached) { if (res.first < res.second && res.first < cacheCount - cached) {
return currIndex; return currIndex;
} }
@ -1833,34 +1842,41 @@ std::list<PredictLayoutItem> ListLayoutAlgorithm::LayoutCachedItemV2(LayoutWrapp
int32_t endIndex = itemPosition_.rbegin()->first; int32_t endIndex = itemPosition_.rbegin()->first;
if (itemPosition_.rbegin()->second.isGroup) { if (itemPosition_.rbegin()->second.isGroup) {
auto wrapper = layoutWrapper->GetChildByIndex(endIndex); auto wrapper = layoutWrapper->GetChildByIndex(endIndex);
auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount); auto res = GetLayoutGroupCachedCount(wrapper, true, cacheCount, false);
if (res.first < res.second && res.first < cacheCount) { if (res.first < res.second && res.first < cacheCount) {
predictBuildList.emplace_back(PredictLayoutItem { endIndex, true, cachedForward }); predictBuildList.emplace_back(PredictLayoutItem { endIndex, true, cachedForward });
} }
cachedForward += res.second; cachedForward += res.second;
} }
if (cachedForward < cacheCount && endIndex < totalItemCount_ - 1) { if (cachedForward < cacheCount && endIndex < totalItemCount_ - 1) {
int32_t index = LayoutCachedForward(layoutWrapper, cacheCount, cachedForward); int32_t index = LayoutCachedForward(layoutWrapper, cacheCount, cachedForward, endIndex);
if (index >= 0) { if (index >= 0) {
predictBuildList.emplace_back(PredictLayoutItem { index, true, cachedForward }); predictBuildList.emplace_back(PredictLayoutItem { index, true, cachedForward });
} else {
endIndex--;
} }
} }
int32_t cachedBackward = 0; int32_t cachedBackward = 0;
int32_t startIndex = itemPosition_.begin()->first; int32_t startIndex = itemPosition_.begin()->first;
if (itemPosition_.begin()->second.isGroup) { if (itemPosition_.begin()->second.isGroup) {
auto wrapper = layoutWrapper->GetChildByIndex(startIndex); auto wrapper = layoutWrapper->GetChildByIndex(startIndex);
auto res = GetLayoutGroupCachedCount(wrapper, false, cacheCount); auto res = GetLayoutGroupCachedCount(wrapper, false, cacheCount, false);
if (res.first < res.second && res.first < cacheCount) { if (res.first < res.second && res.first < cacheCount) {
predictBuildList.emplace_back(PredictLayoutItem { startIndex, false, cachedBackward }); predictBuildList.emplace_back(PredictLayoutItem { startIndex, false, cachedBackward });
} }
cachedBackward += res.second; cachedBackward += res.second;
} }
if (cachedBackward < cacheCount && startIndex > 0) { if (cachedBackward < cacheCount && startIndex > 0) {
auto index = LayoutCachedBackward(layoutWrapper, cacheCount, cachedBackward); auto index = LayoutCachedBackward(layoutWrapper, cacheCount, cachedBackward, startIndex);
if (index >= 0) { if (index >= 0) {
predictBuildList.emplace_back(PredictLayoutItem { index, false, cachedBackward }); predictBuildList.emplace_back(PredictLayoutItem { index, false, cachedBackward });
} else {
startIndex++;
} }
} }
int32_t cacheStart = itemPosition_.begin()->first - startIndex;
int32_t cacheEnd = endIndex - itemPosition_.rbegin()->first;
SetActiveChildRange(layoutWrapper, cacheStart, cacheEnd);
return predictBuildList; return predictBuildList;
} }

View File

@ -396,7 +396,7 @@ protected:
return index; return index;
} }
virtual void SetCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount); virtual void SetCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount);
virtual void SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheCount); virtual void SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheStart, int32_t cacheEnd);
void SetListItemGroupParam(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index, float referencePos, void SetListItemGroupParam(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index, float referencePos,
bool forwardLayout, const RefPtr<ListLayoutProperty>& layoutProperty, bool groupNeedAllLayout, bool forwardLayout, const RefPtr<ListLayoutProperty>& layoutProperty, bool groupNeedAllLayout,
@ -417,7 +417,7 @@ protected:
bool CheckNeedMeasure(const RefPtr<LayoutWrapper>& layoutWrapper) const; bool CheckNeedMeasure(const RefPtr<LayoutWrapper>& layoutWrapper) const;
void ReviseSpace(const RefPtr<ListLayoutProperty>& listLayoutProperty); void ReviseSpace(const RefPtr<ListLayoutProperty>& listLayoutProperty);
std::pair<int32_t, int32_t> GetLayoutGroupCachedCount( std::pair<int32_t, int32_t> GetLayoutGroupCachedCount(
const RefPtr<LayoutWrapper>& wrapper, bool forward, int32_t cacheCount); const RefPtr<LayoutWrapper>& wrapper, bool forward, int32_t cacheCount, bool outOfView);
Axis axis_ = Axis::VERTICAL; Axis axis_ = Axis::VERTICAL;
LayoutConstraintF childLayoutConstraint_; LayoutConstraintF childLayoutConstraint_;
@ -449,8 +449,11 @@ private:
static void PostIdleTask(RefPtr<FrameNode> frameNode, const ListPredictLayoutParam& param); static void PostIdleTask(RefPtr<FrameNode> frameNode, const ListPredictLayoutParam& param);
static bool PredictBuildItem(RefPtr<LayoutWrapper> wrapper, const LayoutConstraintF& constraint); static bool PredictBuildItem(RefPtr<LayoutWrapper> wrapper, const LayoutConstraintF& constraint);
virtual int32_t LayoutCachedForward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached); void ProcessCacheCount(LayoutWrapper* layoutWrapper, int32_t cacheCount);
virtual int32_t LayoutCachedBackward(LayoutWrapper* layoutWrapper, int32_t cacheCount, int32_t cached); virtual int32_t LayoutCachedForward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex);
virtual int32_t LayoutCachedBackward(LayoutWrapper* layoutWrapper,
int32_t cacheCount, int32_t cached, int32_t& currIndex);
std::list<PredictLayoutItem> LayoutCachedItemV2(LayoutWrapper* layoutWrapper, int32_t cacheCount); std::list<PredictLayoutItem> LayoutCachedItemV2(LayoutWrapper* layoutWrapper, int32_t cacheCount);
static bool PredictBuildGroup(RefPtr<LayoutWrapper> wrapper, static bool PredictBuildGroup(RefPtr<LayoutWrapper> wrapper,
const LayoutConstraintF& constraint, bool forward, int64_t deadline, int32_t cached); const LayoutConstraintF& constraint, bool forward, int64_t deadline, int32_t cached);