Hold only last 5 custom themes in memory.

This commit is contained in:
John Preston 2021-09-19 18:15:46 +03:00
parent 4f6c7657bf
commit 17511749de
2 changed files with 52 additions and 11 deletions

View File

@ -75,6 +75,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Window { namespace Window {
namespace { namespace {
constexpr auto kCustomThemesInMemory = 5;
constexpr auto kMaxChatEntryHistorySize = 50; constexpr auto kMaxChatEntryHistorySize = 50;
constexpr auto kDayBaseFile = ":/gui/day-custom-base.tdesktop-theme"_cs; constexpr auto kDayBaseFile = ":/gui/day-custom-base.tdesktop-theme"_cs;
constexpr auto kNightBaseFile = ":/gui/night-custom-base.tdesktop-theme"_cs; constexpr auto kNightBaseFile = ":/gui/night-custom-base.tdesktop-theme"_cs;
@ -505,9 +506,10 @@ void SessionNavigation::showPollResults(
} }
struct SessionController::CachedTheme { struct SessionController::CachedTheme {
std::shared_ptr<Ui::ChatTheme> theme; std::weak_ptr<Ui::ChatTheme> theme;
std::shared_ptr<Data::DocumentMedia> media; std::shared_ptr<Data::DocumentMedia> media;
Data::WallPaper paper; Data::WallPaper paper;
bool caching = false;
rpl::lifetime lifetime; rpl::lifetime lifetime;
}; };
@ -1393,10 +1395,13 @@ auto SessionController::cachedChatThemeValue(
return rpl::single(_defaultChatTheme); return rpl::single(_defaultChatTheme);
} }
const auto i = _customChatThemes.find(key); const auto i = _customChatThemes.find(key);
if (i != end(_customChatThemes) && i->second.theme) { if (i != end(_customChatThemes)) {
return rpl::single(i->second.theme); if (auto strong = i->second.theme.lock()) {
pushToLastUsed(strong);
return rpl::single(std::move(strong));
} }
if (i == end(_customChatThemes)) { }
if (i == end(_customChatThemes) || !i->second.caching) {
cacheChatTheme(data); cacheChatTheme(data);
} }
const auto limit = Data::CloudThemes::TestingColors() ? (1 << 20) : 1; const auto limit = Data::CloudThemes::TestingColors() ? (1 << 20) : 1;
@ -1405,10 +1410,27 @@ auto SessionController::cachedChatThemeValue(
_defaultChatTheme _defaultChatTheme
) | rpl::then(_cachedThemesStream.events( ) | rpl::then(_cachedThemesStream.events(
) | rpl::filter([=](const std::shared_ptr<Ui::ChatTheme> &theme) { ) | rpl::filter([=](const std::shared_ptr<Ui::ChatTheme> &theme) {
return (theme->key() == key); if (theme->key() != key) {
return false;
}
pushToLastUsed(theme);
return true;
}) | rpl::take(limit)); }) | rpl::take(limit));
} }
void SessionController::pushToLastUsed(
const std::shared_ptr<Ui::ChatTheme> &theme) {
const auto i = ranges::find(_lastUsedCustomChatThemes, theme);
if (i == end(_lastUsedCustomChatThemes)) {
if (_lastUsedCustomChatThemes.size() >= kCustomThemesInMemory) {
_lastUsedCustomChatThemes.pop_back();
}
_lastUsedCustomChatThemes.push_front(theme);
} else if (i != begin(_lastUsedCustomChatThemes)) {
std::rotate(begin(_lastUsedCustomChatThemes), i, i + 1);
}
}
void SessionController::setChatStyleTheme( void SessionController::setChatStyleTheme(
const std::shared_ptr<Ui::ChatTheme> &theme) { const std::shared_ptr<Ui::ChatTheme> &theme) {
if (_chatStyleTheme.lock() == theme) { if (_chatStyleTheme.lock() == theme) {
@ -1447,9 +1469,22 @@ void SessionController::cacheChatTheme(const Data::CloudTheme &data) {
const auto document = data.paper->document(); const auto document = data.paper->document();
const auto media = document ? document->createMediaView() : nullptr; const auto media = document ? document->createMediaView() : nullptr;
data.paper->loadDocument(); data.paper->loadDocument();
auto &theme = _customChatThemes.emplace( auto &theme = [&]() -> CachedTheme& {
const auto i = _customChatThemes.find(key);
if (i != end(_customChatThemes)) {
i->second.media = media;
i->second.paper = *data.paper;
i->second.caching = true;
return i->second;
}
return _customChatThemes.emplace(
key, key,
CachedTheme{ .media = media, .paper = *data.paper }).first->second; CachedTheme{
.media = media,
.paper = *data.paper,
.caching = true,
}).first->second;
}();
auto descriptor = Ui::ChatThemeDescriptor{ auto descriptor = Ui::ChatThemeDescriptor{
.id = key, .id = key,
.preparePalette = PreparePaletteCallback( .preparePalette = PreparePaletteCallback(
@ -1485,6 +1520,7 @@ void SessionController::cacheChatThemeDone(
if (i == end(_customChatThemes)) { if (i == end(_customChatThemes)) {
return; return;
} }
i->second.caching = false;
i->second.theme = result; i->second.theme = result;
if (i->second.media) { if (i->second.media) {
if (i->second.media->loaded(true)) { if (i->second.media->loaded(true)) {
@ -1510,10 +1546,11 @@ void SessionController::updateCustomThemeBackground(CachedTheme &theme) {
theme.lifetime.destroy(); theme.lifetime.destroy();
theme.media = nullptr; theme.media = nullptr;
}); });
if (!theme.media || !theme.theme || !theme.media->loaded(true)) { const auto strong = theme.theme.lock();
if (!theme.media || !strong || !theme.media->loaded(true)) {
return; return;
} }
const auto key = theme.theme->key(); const auto key = strong->key();
const auto weak = base::make_weak(this); const auto weak = base::make_weak(this);
crl::async([=, data = backgroundData(theme, false)] { crl::async([=, data = backgroundData(theme, false)] {
crl::on_main(weak, [ crl::on_main(weak, [
@ -1522,7 +1559,9 @@ void SessionController::updateCustomThemeBackground(CachedTheme &theme) {
]() mutable { ]() mutable {
const auto i = _customChatThemes.find(key); const auto i = _customChatThemes.find(key);
if (i != end(_customChatThemes)) { if (i != end(_customChatThemes)) {
i->second.theme->updateBackgroundImageFrom(std::move(result)); if (const auto strong = i->second.theme.lock()) {
strong->updateBackgroundImageFrom(std::move(result));
}
} }
}); });
}); });

View File

@ -464,6 +464,7 @@ private:
[[nodiscard]] Ui::ChatThemeBackgroundData backgroundData( [[nodiscard]] Ui::ChatThemeBackgroundData backgroundData(
CachedTheme &theme, CachedTheme &theme,
bool generateGradient = true) const; bool generateGradient = true) const;
void pushToLastUsed(const std::shared_ptr<Ui::ChatTheme> &theme);
const not_null<Controller*> _window; const not_null<Controller*> _window;
const std::unique_ptr<ChatHelpers::EmojiInteractions> _emojiInteractions; const std::unique_ptr<ChatHelpers::EmojiInteractions> _emojiInteractions;
@ -498,6 +499,7 @@ private:
rpl::event_stream<std::shared_ptr<Ui::ChatTheme>> _cachedThemesStream; rpl::event_stream<std::shared_ptr<Ui::ChatTheme>> _cachedThemesStream;
const std::unique_ptr<Ui::ChatStyle> _chatStyle; const std::unique_ptr<Ui::ChatStyle> _chatStyle;
std::weak_ptr<Ui::ChatTheme> _chatStyleTheme; std::weak_ptr<Ui::ChatTheme> _chatStyleTheme;
std::deque<std::shared_ptr<Ui::ChatTheme>> _lastUsedCustomChatThemes;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;