Don't hold session pointer in Data::CloudImage.

This commit is contained in:
John Preston 2020-05-28 17:51:18 +04:00
parent 29a498b959
commit 249f7813c1
11 changed files with 81 additions and 53 deletions

View File

@ -250,14 +250,18 @@ void GifsListWidget::inlineResultsDone(const MTPmessages_BotResults &result) {
_inlineQuery,
std::make_unique<InlineCacheEntry>()).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));
}

View File

@ -26,24 +26,30 @@ void CloudImageView::set(
session->downloaderTaskFinished().notify();
}
CloudImage::CloudImage(not_null<Main::Session*> session)
: _session(session) {
CloudImage::CloudImage() = default;
CloudImage::CloudImage(
not_null<Main::Session*> 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<Main::Session*> 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<Main::Session*> 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));
}
});
}

View File

@ -52,14 +52,19 @@ private:
class CloudImage final {
public:
explicit CloudImage(not_null<Main::Session*> session);
CloudImage();
CloudImage(
not_null<Main::Session*> session,
const ImageWithLocation &data);
void set(const ImageWithLocation &data);
void update(
not_null<Main::Session*> session,
const ImageWithLocation &data);
[[nodiscard]] bool empty() const;
[[nodiscard]] bool loading() const;
[[nodiscard]] bool failed() const;
void load(FileOrigin origin);
void load(not_null<Main::Session*> session, FileOrigin origin);
[[nodiscard]] const ImageLocation &location() const;
[[nodiscard]] int byteSize() const;
@ -67,7 +72,6 @@ public:
[[nodiscard]] std::shared_ptr<CloudImageView> activeView();
private:
const not_null<Main::Session*> _session;
CloudFile _file;
std::weak_ptr<CloudImageView> _view;

View File

@ -3030,17 +3030,18 @@ not_null<Data::CloudImage*> Session::location(const LocationPoint &point) {
if (i != _locations.cend()) {
return i->second.get();
}
const auto result = _locations.emplace(
point,
std::make_unique<Data::CloudImage>(_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<Data::CloudImage>(
_session,
prepared)).first->second.get();
}
void Session::registerPhotoItem(

View File

@ -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

View File

@ -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() {

View File

@ -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();

View File

@ -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<Main::Session*> session, const Creator &creator)
: _session(session)
, _queryId(creator.queryId)
, _type(creator.type) {
}
std::unique_ptr<Result> Result::create(
std::unique_ptr<Result> Result::Create(
not_null<Main::Session*> session,
uint64 queryId,
const MTPBotInlineResult &mtpData) {
using Type = Result::Type;
@ -78,7 +78,9 @@ std::unique_ptr<Result> Result::create(
return nullptr;
}
auto result = std::make_unique<Result>(Creator{ queryId, type });
auto result = std::make_unique<Result>(
session,
Creator{ queryId, type });
const MTPBotInlineMessage *message = nullptr;
switch (mtpData.type()) {
case mtpc_botInlineResult: {
@ -126,7 +128,7 @@ std::unique_ptr<Result> 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> 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)
});
}

View File

@ -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<Result> create(uint64 queryId, const MTPBotInlineResult &mtpData);
Result(const Result &other) = delete;
Result &operator=(const Result &other) = delete;
Result(not_null<Main::Session*> session, const Creator &creator);
static std::unique_ptr<Result> Create(
not_null<Main::Session*> 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<Main::Session*> _session;
uint64 _queryId = 0;
QString _id;
Type _type = Type::Unknown;

View File

@ -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<internal::CacheEntry>()).first;
it = _inlineCache.emplace(
_inlineQuery,
std::make_unique<internal::CacheEntry>()).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));
}

View File

@ -246,7 +246,7 @@ private:
bool refreshInlineRows(int *added = nullptr);
void inlineResultsDone(const MTPmessages_BotResults &result);
not_null<Window::SessionController*> _controller;
const not_null<Window::SessionController*> _controller;
MTP::Sender _api;
int _contentMaxHeight = 0;