From 249f7813c1845e5d9225793222f4c16c7eb41b8e Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 28 May 2020 17:51:18 +0400 Subject: [PATCH] Don't hold session pointer in Data::CloudImage. --- .../chat_helpers/gifs_list_widget.cpp | 12 ++++++---- Telegram/SourceFiles/data/data_cloud_file.cpp | 22 ++++++++++++------- Telegram/SourceFiles/data/data_cloud_file.h | 12 ++++++---- Telegram/SourceFiles/data/data_session.cpp | 13 ++++++----- Telegram/SourceFiles/data/data_user.cpp | 12 +++++----- .../view/media/history_view_location.cpp | 3 ++- .../inline_bots/inline_bot_layout_item.cpp | 6 ++--- .../inline_bots/inline_bot_result.cpp | 20 +++++++++-------- .../inline_bots/inline_bot_result.h | 16 ++++++++------ .../inline_bots/inline_results_widget.cpp | 16 +++++++++----- .../inline_bots/inline_results_widget.h | 2 +- 11 files changed, 81 insertions(+), 53 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp index aa719e28b8..61a0ea27bf 100644 --- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp @@ -250,14 +250,18 @@ void GifsListWidget::inlineResultsDone(const MTPmessages_BotResults &result) { _inlineQuery, std::make_unique()).first; } - auto entry = it->second.get(); + const auto entry = it->second.get(); entry->nextOffset = qs(d.vnext_offset().value_or_empty()); - if (auto count = v.size()) { + if (const auto count = v.size()) { entry->results.reserve(entry->results.size() + count); } auto added = 0; - for_const (const auto &res, v) { - if (auto result = InlineBots::Result::create(queryId, res)) { + for (const auto &res : v) { + auto result = InlineBots::Result::Create( + &controller()->session(), + queryId, + res); + if (result) { ++added; entry->results.push_back(std::move(result)); } diff --git a/Telegram/SourceFiles/data/data_cloud_file.cpp b/Telegram/SourceFiles/data/data_cloud_file.cpp index d13fb5ef43..4b17a3ccea 100644 --- a/Telegram/SourceFiles/data/data_cloud_file.cpp +++ b/Telegram/SourceFiles/data/data_cloud_file.cpp @@ -26,24 +26,30 @@ void CloudImageView::set( session->downloaderTaskFinished().notify(); } -CloudImage::CloudImage(not_null session) -: _session(session) { +CloudImage::CloudImage() = default; + +CloudImage::CloudImage( + not_null session, + const ImageWithLocation &data) { + update(session, data); } Image *CloudImageView::image() const { return _image.get(); } -void CloudImage::set(const ImageWithLocation &data) { +void CloudImage::update( + not_null session, + const ImageWithLocation &data) { UpdateCloudFile( _file, data, - _session->data().cache(), + session->data().cache(), kImageCacheTag, - [=](FileOrigin origin) { load(origin); }, + [=](FileOrigin origin) { load(session, origin); }, [=](QImage preloaded) { if (const auto view = activeView()) { - view->set(_session, data.preloaded); + view->set(session, data.preloaded); } }); } @@ -60,7 +66,7 @@ bool CloudImage::failed() const { return (_file.flags & CloudFile::Flag::Failed); } -void CloudImage::load(FileOrigin origin) { +void CloudImage::load(not_null session, FileOrigin origin) { const auto fromCloud = LoadFromCloudOrLocal; const auto cacheTag = kImageCacheTag; const auto autoLoading = false; @@ -71,7 +77,7 @@ void CloudImage::load(FileOrigin origin) { return true; }, [=](QImage result) { if (const auto active = activeView()) { - active->set(_session, std::move(result)); + active->set(session, std::move(result)); } }); } diff --git a/Telegram/SourceFiles/data/data_cloud_file.h b/Telegram/SourceFiles/data/data_cloud_file.h index 0e01e8072b..cde52e5d8c 100644 --- a/Telegram/SourceFiles/data/data_cloud_file.h +++ b/Telegram/SourceFiles/data/data_cloud_file.h @@ -52,14 +52,19 @@ private: class CloudImage final { public: - explicit CloudImage(not_null session); + CloudImage(); + CloudImage( + not_null session, + const ImageWithLocation &data); - void set(const ImageWithLocation &data); + void update( + not_null session, + const ImageWithLocation &data); [[nodiscard]] bool empty() const; [[nodiscard]] bool loading() const; [[nodiscard]] bool failed() const; - void load(FileOrigin origin); + void load(not_null session, FileOrigin origin); [[nodiscard]] const ImageLocation &location() const; [[nodiscard]] int byteSize() const; @@ -67,7 +72,6 @@ public: [[nodiscard]] std::shared_ptr activeView(); private: - const not_null _session; CloudFile _file; std::weak_ptr _view; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 79da37b0df..2d717c2aff 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -3030,17 +3030,18 @@ not_null Session::location(const LocationPoint &point) { if (i != _locations.cend()) { return i->second.get(); } - const auto result = _locations.emplace( - point, - std::make_unique(_session)).first->second.get(); const auto location = Data::ComputeLocation(point); - result->set(ImageWithLocation{ + const auto prepared = ImageWithLocation{ .location = ImageLocation( { location }, location.width, location.height) - }); - return result; + }; + return _locations.emplace( + point, + std::make_unique( + _session, + prepared)).first->second.get(); } void Session::registerPhotoItem( diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index fbb4e78f24..9389f5dbe3 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -73,12 +73,14 @@ void UserData::setIsContact(bool is) { // see Local::readPeer as well void UserData::setPhoto(const MTPUserProfilePhoto &photo) { - if (photo.type() == mtpc_userProfilePhoto) { - const auto &data = photo.c_userProfilePhoto(); - updateUserpic(data.vphoto_id().v, data.vdc_id().v, data.vphoto_small()); - } else { + photo.match([&](const MTPDuserProfilePhoto &data) { + updateUserpic( + data.vphoto_id().v, + data.vdc_id().v, + data.vphoto_small()); + }, [&](const MTPDuserProfilePhotoEmpty &) { clearUserpic(); - } + }); } auto UserData::unavailableReasons() const diff --git a/Telegram/SourceFiles/history/view/media/history_view_location.cpp b/Telegram/SourceFiles/history/view/media/history_view_location.cpp index 57a386a715..7645bfdc76 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_location.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_location.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/media/history_view_location.h" #include "layout.h" +#include "history/history.h" #include "history/history_item_components.h" #include "history/history_item.h" #include "history/history_location_manager.h" @@ -54,7 +55,7 @@ void Location::ensureMediaCreated() const { return; } _media = _data->createView(); - _data->load(_parent->data()->fullId()); + _data->load(&history()->session(), _parent->data()->fullId()); } QSize Location::countOptimalSize() { diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp index 426e792e34..2482928656 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp @@ -76,7 +76,7 @@ void ItemBase::preload() const { } else if (const auto document = _result->_document) { document->loadThumbnail(origin); } else if (auto &thumb = _result->_thumbnail; !thumb.empty()) { - thumb.load(origin); + thumb.load(_result->_session, origin); } } else if (_document) { _document->loadThumbnail(origin); @@ -154,10 +154,10 @@ Image *ItemBase::getResultThumb(Data::FileOrigin origin) const { if (_result && !_thumbnail) { if (!_result->_thumbnail.empty()) { _thumbnail = _result->_thumbnail.createView(); - _result->_thumbnail.load(origin); + _result->_thumbnail.load(_result->_session, origin); } else if (!_result->_locationThumbnail.empty()) { _thumbnail = _result->_locationThumbnail.createView(); - _result->_locationThumbnail.load(origin); + _result->_locationThumbnail.load(_result->_session, origin); } } return _thumbnail->image(); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp index 33ab6411dc..b76b72c46e 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp @@ -41,14 +41,14 @@ QString GetContentUrl(const MTPWebDocument &document) { } // namespace -Result::Result(const Creator &creator) -: _queryId(creator.queryId) -, _type(creator.type) -, _thumbnail(&Auth()) -, _locationThumbnail(&Auth()) { +Result::Result(not_null session, const Creator &creator) +: _session(session) +, _queryId(creator.queryId) +, _type(creator.type) { } -std::unique_ptr Result::create( +std::unique_ptr Result::Create( + not_null session, uint64 queryId, const MTPBotInlineResult &mtpData) { using Type = Result::Type; @@ -78,7 +78,9 @@ std::unique_ptr Result::create( return nullptr; } - auto result = std::make_unique(Creator{ queryId, type }); + auto result = std::make_unique( + session, + Creator{ queryId, type }); const MTPBotInlineMessage *message = nullptr; switch (mtpData.type()) { case mtpc_botInlineResult: { @@ -126,7 +128,7 @@ std::unique_ptr Result::create( } } if (!result->_photo && !result->_document && imageThumb) { - result->_thumbnail.set(ImageWithLocation{ + result->_thumbnail.update(result->_session, ImageWithLocation{ .location = Images::FromWebDocument(*r.vthumb()) }); } @@ -280,7 +282,7 @@ std::unique_ptr Result::create( location.height = h; location.zoom = zoom; location.scale = scale; - result->_locationThumbnail.set(ImageWithLocation{ + result->_locationThumbnail.update(result->_session, ImageWithLocation{ .location = ImageLocation({ location }, w, h) }); } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.h b/Telegram/SourceFiles/inline_bots/inline_bot_result.h index 9604cc4905..b778b469b0 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.h @@ -32,13 +32,14 @@ private: struct Creator; public: - // Constructor is public only for std::make_unique<>() to work. // You should use create() static method instead. - explicit Result(const Creator &creator); - static std::unique_ptr create(uint64 queryId, const MTPBotInlineResult &mtpData); - Result(const Result &other) = delete; - Result &operator=(const Result &other) = delete; + Result(not_null session, const Creator &creator); + + static std::unique_ptr Create( + not_null session, + uint64 queryId, + const MTPBotInlineResult &mtpData); uint64 getQueryId() const { return _queryId; @@ -102,10 +103,11 @@ private: friend class internal::SendData; friend class Layout::ItemBase; struct Creator { - uint64 queryId; - Type type; + uint64 queryId = 0; + Type type = Type::Unknown; }; + not_null _session; uint64 _queryId = 0; QString _id; Type _type = Type::Unknown; diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index a2eb7e564e..a3855e7d9a 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -59,7 +59,7 @@ Inner::Inner( setMouseTracking(true); setAttribute(Qt::WA_OpaquePaintEvent); - subscribe(Auth().downloaderTaskFinished(), [this] { + subscribe(_controller->session().downloaderTaskFinished(), [this] { update(); }); subscribe(controller->gifPauseLevelChanged(), [this] { @@ -1056,13 +1056,15 @@ void Widget::inlineResultsDone(const MTPmessages_BotResults &result) { auto adding = (it != _inlineCache.cend()); if (result.type() == mtpc_messages_botResults) { auto &d = result.c_messages_botResults(); - Auth().data().processUsers(d.vusers()); + _controller->session().data().processUsers(d.vusers()); auto &v = d.vresults().v; auto queryId = d.vquery_id().v; if (it == _inlineCache.cend()) { - it = _inlineCache.emplace(_inlineQuery, std::make_unique()).first; + it = _inlineCache.emplace( + _inlineQuery, + std::make_unique()).first; } auto entry = it->second.get(); entry->nextOffset = qs(d.vnext_offset().value_or_empty()); @@ -1077,8 +1079,12 @@ void Widget::inlineResultsDone(const MTPmessages_BotResults &result) { entry->results.reserve(entry->results.size() + count); } auto added = 0; - for_const (const auto &res, v) { - if (auto result = InlineBots::Result::create(queryId, res)) { + for (const auto &res : v) { + auto result = InlineBots::Result::Create( + &_controller->session(), + queryId, + res); + if (result) { ++added; entry->results.push_back(std::move(result)); } diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.h b/Telegram/SourceFiles/inline_bots/inline_results_widget.h index e24e621fb7..3a763b3c02 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.h +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.h @@ -246,7 +246,7 @@ private: bool refreshInlineRows(int *added = nullptr); void inlineResultsDone(const MTPmessages_BotResults &result); - not_null _controller; + const not_null _controller; MTP::Sender _api; int _contentMaxHeight = 0;