Clear memory while scrolling in topics / discussions.

This commit is contained in:
John Preston 2023-03-17 17:51:53 +04:00
parent f410a3b6da
commit 3b1d13eac9
2 changed files with 28 additions and 9 deletions

View File

@ -490,6 +490,8 @@ void ListWidget::setGeometryCrashAnnotations(not_null<Element*> view) {
}
void ListWidget::refreshRows(const Data::MessagesSlice &old) {
Expects(_viewsCapacity.empty());
saveScrollState();
const auto addedToEndFrom = (old.skippedAfter == 0
@ -507,13 +509,14 @@ void ListWidget::refreshRows(const Data::MessagesSlice &old) {
_resizePending = true;
_items.clear();
_items.reserve(_slice.ids.size());
std::swap(_views, _viewsCapacity);
auto nearestIndex = -1;
for (const auto &fullId : _slice.ids) {
if (const auto item = session().data().message(fullId)) {
if (_slice.nearestToAround == fullId) {
nearestIndex = int(_items.size());
}
const auto view = enforceViewForItem(item);
const auto view = enforceViewForItem(item, _viewsCapacity);
_items.push_back(view);
if (destroyingBarElement == view) {
destroyingBarElement = nullptr;
@ -541,6 +544,13 @@ void ListWidget::refreshRows(const Data::MessagesSlice &old) {
_bar = {};
}
for (const auto &[item, view] : _viewsCapacity) {
if (const auto raw = view.get()) {
viewReplaced(raw, nullptr);
}
}
_viewsCapacity.clear();
checkUnreadBarCreation();
restoreScrollState();
if (!_itemsRevealHeight) {
@ -868,9 +878,16 @@ Element *ListWidget::viewForItem(const HistoryItem *item) const {
}
not_null<Element*> ListWidget::enforceViewForItem(
not_null<HistoryItem*> item) {
if (const auto view = viewForItem(item)) {
return view;
not_null<HistoryItem*> item,
ViewsMap &old) {
if (const auto i = old.find(item); i != end(old)) {
if (i->second) {
return _views.emplace(
item,
base::take(i->second)).first->second.get();
} else if (const auto j = _views.find(item); j != end(_views)) {
return j->second.get();
}
}
const auto [i, ok] = _views.emplace(
item,

View File

@ -359,6 +359,9 @@ private:
using PointState = HistoryView::PointState;
using CursorState = HistoryView::CursorState;
using ChosenReaction = HistoryView::Reactions::ChosenReaction;
using ViewsMap = base::flat_map<
not_null<HistoryItem*>,
std::unique_ptr<Element>>;
struct MouseState {
MouseState();
@ -433,7 +436,9 @@ private:
Element *viewForItem(FullMsgId itemId) const;
Element *viewForItem(const HistoryItem *item) const;
not_null<Element*> enforceViewForItem(not_null<HistoryItem*> item);
not_null<Element*> enforceViewForItem(
not_null<HistoryItem*> item,
ViewsMap &old);
void mouseActionStart(
const QPoint &globalPosition,
@ -623,10 +628,7 @@ private:
int _idsLimit = kMinimalIdsLimit;
Data::MessagesSlice _slice;
std::vector<not_null<Element*>> _items;
std::map<
not_null<HistoryItem*>,
std::unique_ptr<Element>,
std::less<>> _views;
ViewsMap _views, _viewsCapacity;
int _itemsTop = 0;
int _itemsWidth = 0;
int _itemsHeight = 0;