Wallpapers cache and combinig of queries.

GitOrigin-RevId: 4dbad3fadcff8d0978b2600c500e3dd7e9d0bd1c
This commit is contained in:
levlam 2019-01-17 03:27:43 +03:00
parent eaf7e36532
commit 33657d521a
5 changed files with 122 additions and 60 deletions

View File

@ -135,7 +135,7 @@ tl_object_ptr<td_api::profilePhoto> get_profile_photo_object(FileManager *file_m
if (profile_photo == nullptr || !profile_photo->small_file_id.is_valid()) { if (profile_photo == nullptr || !profile_photo->small_file_id.is_valid()) {
return nullptr; return nullptr;
} }
return make_tl_object<td_api::profilePhoto>(profile_photo->id, return td_api::make_object<td_api::profilePhoto>(profile_photo->id,
file_manager->get_file_object(profile_photo->small_file_id), file_manager->get_file_object(profile_photo->small_file_id),
file_manager->get_file_object(profile_photo->big_file_id)); file_manager->get_file_object(profile_photo->big_file_id));
} }
@ -196,7 +196,7 @@ tl_object_ptr<td_api::chatPhoto> get_chat_photo_object(FileManager *file_manager
if (dialog_photo == nullptr || !dialog_photo->small_file_id.is_valid()) { if (dialog_photo == nullptr || !dialog_photo->small_file_id.is_valid()) {
return nullptr; return nullptr;
} }
return make_tl_object<td_api::chatPhoto>(file_manager->get_file_object(dialog_photo->small_file_id), return td_api::make_object<td_api::chatPhoto>(file_manager->get_file_object(dialog_photo->small_file_id),
file_manager->get_file_object(dialog_photo->big_file_id)); file_manager->get_file_object(dialog_photo->big_file_id));
} }
@ -379,13 +379,17 @@ tl_object_ptr<td_api::photoSize> get_photo_size_object(FileManager *file_manager
return nullptr; return nullptr;
} }
return make_tl_object<td_api::photoSize>( return td_api::make_object<td_api::photoSize>(
photo_size->type ? std::string(1, static_cast<char>(photo_size->type)) photo_size->type ? std::string(1, static_cast<char>(photo_size->type))
: std::string(), // TODO replace string type with integer type : std::string(), // TODO replace string type with integer type
file_manager->get_file_object(photo_size->file_id), photo_size->dimensions.width, photo_size->dimensions.height); file_manager->get_file_object(photo_size->file_id), photo_size->dimensions.width, photo_size->dimensions.height);
} }
void sort_photo_sizes(vector<td_api::object_ptr<td_api::photoSize>> &sizes) { vector<td_api::object_ptr<td_api::photoSize>> get_photo_sizes_object(FileManager *file_manager,
const vector<PhotoSize> &photo_sizes) {
auto sizes = transform(photo_sizes, [file_manager](const PhotoSize &photo_size) {
return get_photo_size_object(file_manager, &photo_size);
});
std::sort(sizes.begin(), sizes.end(), [](const auto &lhs, const auto &rhs) { std::sort(sizes.begin(), sizes.end(), [](const auto &lhs, const auto &rhs) {
if (lhs->photo_->expected_size_ != rhs->photo_->expected_size_) { if (lhs->photo_->expected_size_ != rhs->photo_->expected_size_) {
return lhs->photo_->expected_size_ < rhs->photo_->expected_size_; return lhs->photo_->expected_size_ < rhs->photo_->expected_size_;
@ -393,6 +397,7 @@ void sort_photo_sizes(vector<td_api::object_ptr<td_api::photoSize>> &sizes) {
return static_cast<uint32>(lhs->width_) * static_cast<uint32>(lhs->height_) < return static_cast<uint32>(lhs->width_) * static_cast<uint32>(lhs->height_) <
static_cast<uint32>(rhs->width_) * static_cast<uint32>(rhs->height_); static_cast<uint32>(rhs->width_) * static_cast<uint32>(rhs->height_);
}); });
return sizes;
} }
bool operator==(const PhotoSize &lhs, const PhotoSize &rhs) { bool operator==(const PhotoSize &lhs, const PhotoSize &rhs) {
@ -488,12 +493,7 @@ tl_object_ptr<td_api::photo> get_photo_object(FileManager *file_manager, const P
return nullptr; return nullptr;
} }
vector<td_api::object_ptr<td_api::photoSize>> photos; return td_api::make_object<td_api::photo>(photo->has_stickers, get_photo_sizes_object(file_manager, photo->photos));
for (auto &photo_size : photo->photos) {
photos.push_back(get_photo_size_object(file_manager, &photo_size));
}
sort_photo_sizes(photos);
return make_tl_object<td_api::photo>(photo->has_stickers, std::move(photos));
} }
tl_object_ptr<td_api::userProfilePhoto> get_user_profile_photo_object(FileManager *file_manager, const Photo *photo) { tl_object_ptr<td_api::userProfilePhoto> get_user_profile_photo_object(FileManager *file_manager, const Photo *photo) {
@ -501,12 +501,8 @@ tl_object_ptr<td_api::userProfilePhoto> get_user_profile_photo_object(FileManage
return nullptr; return nullptr;
} }
vector<td_api::object_ptr<td_api::photoSize>> photos; return td_api::make_object<td_api::userProfilePhoto>(photo->id, photo->date,
for (auto &photo_size : photo->photos) { get_photo_sizes_object(file_manager, photo->photos));
photos.push_back(get_photo_size_object(file_manager, &photo_size));
}
sort_photo_sizes(photos);
return make_tl_object<td_api::userProfilePhoto>(photo->id, photo->date, std::move(photos));
} }
void photo_delete_thumbnail(Photo &photo) { void photo_delete_thumbnail(Photo &photo) {

View File

@ -84,8 +84,9 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id
DialogId owner_dialog_id, tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp); DialogId owner_dialog_id, tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp);
PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id, PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id,
tl_object_ptr<telegram_api::WebDocument> web_document_ptr); tl_object_ptr<telegram_api::WebDocument> web_document_ptr);
tl_object_ptr<td_api::photoSize> get_photo_size_object(FileManager *file_manager, const PhotoSize *photo_size); td_api::object_ptr<td_api::photoSize> get_photo_size_object(FileManager *file_manager, const PhotoSize *photo_size);
void sort_photo_sizes(vector<td_api::object_ptr<td_api::photoSize>> &sizes); vector<td_api::object_ptr<td_api::photoSize>> get_photo_sizes_object(FileManager *file_manager,
const vector<PhotoSize> &photo_sizes);
bool operator==(const PhotoSize &lhs, const PhotoSize &rhs); bool operator==(const PhotoSize &lhs, const PhotoSize &rhs);
bool operator!=(const PhotoSize &lhs, const PhotoSize &rhs); bool operator!=(const PhotoSize &lhs, const PhotoSize &rhs);

View File

@ -2841,6 +2841,20 @@ class GetSupportUserRequest : public RequestActor<> {
} }
}; };
class GetWallpapersRequest : public RequestOnceActor {
void do_run(Promise<Unit> &&promise) override {
td->wallpaper_manager_->get_wallpapers(std::move(promise));
}
void do_send_result() override {
send_result(td->wallpaper_manager_->get_wallpapers_object());
}
public:
GetWallpapersRequest(ActorShared<Td> td, uint64 request_id) : RequestOnceActor(std::move(td), request_id) {
}
};
class GetRecentlyVisitedTMeUrlsRequest : public RequestActor<tl_object_ptr<td_api::tMeUrls>> { class GetRecentlyVisitedTMeUrlsRequest : public RequestActor<tl_object_ptr<td_api::tMeUrls>> {
string referrer_; string referrer_;
@ -6647,8 +6661,7 @@ void Td::on_request(uint64 id, const td_api::getSupportUser &request) {
void Td::on_request(uint64 id, const td_api::getWallpapers &request) { void Td::on_request(uint64 id, const td_api::getWallpapers &request) {
CHECK_IS_USER(); CHECK_IS_USER();
CREATE_REQUEST_PROMISE(); CREATE_NO_ARGS_REQUEST(GetWallpapersRequest);
send_closure(wallpaper_manager_actor_, &WallpaperManager::get_wallpapers, std::move(promise));
} }
void Td::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) { void Td::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) {

View File

@ -13,13 +13,15 @@
#include "td/telegram/Photo.h" #include "td/telegram/Photo.h"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
#include "td/utils/misc.h"
namespace td { namespace td {
class GetWallpapersQuery : public Td::ResultHandler { class GetWallpapersQuery : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::wallpapers>> promise_; Promise<vector<telegram_api::object_ptr<telegram_api::WallPaper>>> promise_;
public: public:
explicit GetWallpapersQuery(Promise<td_api::object_ptr<td_api::wallpapers>> &&promise) explicit GetWallpapersQuery(Promise<vector<telegram_api::object_ptr<telegram_api::WallPaper>>> &&promise)
: promise_(std::move(promise)) { : promise_(std::move(promise)) {
} }
@ -33,38 +35,7 @@ class GetWallpapersQuery : public Td::ResultHandler {
return on_error(id, result_ptr.move_as_error()); return on_error(id, result_ptr.move_as_error());
} }
auto wallpapers = result_ptr.move_as_ok(); promise_.set_value(result_ptr.move_as_ok());
auto results = td_api::make_object<td_api::wallpapers>();
results->wallpapers_.reserve(wallpapers.size());
for (auto &wallpaper_ptr : wallpapers) {
CHECK(wallpaper_ptr != nullptr);
switch (wallpaper_ptr->get_id()) {
case telegram_api::wallPaper::ID: {
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
vector<td_api::object_ptr<td_api::photoSize>> sizes;
sizes.reserve(wallpaper->sizes_.size());
for (auto &size_ptr : wallpaper->sizes_) {
auto photo_size = get_photo_size(td->file_manager_.get(), FileType::Wallpaper, 0, 0, DialogId(),
std::move(size_ptr), false);
sizes.push_back(get_photo_size_object(td->file_manager_.get(), &photo_size));
}
sort_photo_sizes(sizes);
results->wallpapers_.push_back(
td_api::make_object<td_api::wallpaper>(wallpaper->id_, std::move(sizes), wallpaper->color_));
break;
}
case telegram_api::wallPaperSolid::ID: {
auto wallpaper = move_tl_object_as<telegram_api::wallPaperSolid>(wallpaper_ptr);
results->wallpapers_.push_back(td_api::make_object<td_api::wallpaper>(
wallpaper->id_, vector<td_api::object_ptr<td_api::photoSize>>(), wallpaper->bg_color_));
break;
}
default:
UNREACHABLE();
}
}
promise_.set_value(std::move(results));
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
@ -79,8 +50,70 @@ void WallpaperManager::tear_down() {
parent_.reset(); parent_.reset();
} }
void WallpaperManager::get_wallpapers(Promise<td_api::object_ptr<td_api::wallpapers>> &&promise) { void WallpaperManager::get_wallpapers(Promise<Unit> &&promise) {
td_->create_handler<GetWallpapersQuery>(std::move(promise))->send(); if (!wallpapers_.empty()) {
return promise.set_value(Unit());
}
pending_get_wallpapers_queries_.push_back(std::move(promise));
if (pending_get_wallpapers_queries_.size() == 1) {
auto request_promise = PromiseCreator::lambda(
[actor_id = actor_id(this)](Result<vector<telegram_api::object_ptr<telegram_api::WallPaper>>> result) {
send_closure(actor_id, &WallpaperManager::on_get_wallpapers, std::move(result));
});
td_->create_handler<GetWallpapersQuery>(std::move(request_promise))->send();
}
}
void WallpaperManager::on_get_wallpapers(Result<vector<telegram_api::object_ptr<telegram_api::WallPaper>>> result) {
CHECK(wallpapers_.empty());
auto promises = std::move(pending_get_wallpapers_queries_);
CHECK(!promises.empty());
reset_to_empty(pending_get_wallpapers_queries_);
if (result.is_error()) {
auto error = result.move_as_error();
for (auto &promise : promises) {
promise.set_error(error.clone());
}
return;
}
wallpapers_ = transform(result.move_as_ok(), [file_manager = td_->file_manager_.get()](
tl_object_ptr<telegram_api::WallPaper> &&wallpaper_ptr) {
CHECK(wallpaper_ptr != nullptr);
switch (wallpaper_ptr->get_id()) {
case telegram_api::wallPaper::ID: {
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
vector<PhotoSize> sizes = transform(
std::move(wallpaper->sizes_), [file_manager](tl_object_ptr<telegram_api::PhotoSize> &&photo_size) {
return get_photo_size(file_manager, FileType::Wallpaper, 0, 0, DialogId(), std::move(photo_size), false);
});
return Wallpaper{wallpaper->id_, std::move(sizes), wallpaper->color_};
}
case telegram_api::wallPaperSolid::ID: {
auto wallpaper = move_tl_object_as<telegram_api::wallPaperSolid>(wallpaper_ptr);
return Wallpaper{wallpaper->id_, {}, wallpaper->bg_color_};
}
default:
UNREACHABLE();
return Wallpaper{0, {}, 0};
}
});
for (auto &promise : promises) {
promise.set_value(Unit());
}
}
td_api::object_ptr<td_api::wallpapers> WallpaperManager::get_wallpapers_object() const {
return td_api::make_object<td_api::wallpapers>(
transform(wallpapers_, [file_manager = td_->file_manager_.get()](const Wallpaper &wallpaper) {
return td_api::make_object<td_api::wallpaper>(
wallpaper.id, get_photo_sizes_object(file_manager, wallpaper.sizes), wallpaper.color);
}));
} }
} // namespace td } // namespace td

View File

@ -6,11 +6,14 @@
// //
#pragma once #pragma once
#include "td/telegram/Photo.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
#include "td/actor/actor.h" #include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h" #include "td/actor/PromiseFuture.h"
#include "td/utils/Status.h"
namespace td { namespace td {
class Td; class Td;
@ -19,11 +22,27 @@ class WallpaperManager : public Actor {
public: public:
WallpaperManager(Td *td, ActorShared<> parent); WallpaperManager(Td *td, ActorShared<> parent);
void get_wallpapers(Promise<td_api::object_ptr<td_api::wallpapers>> &&promise); void get_wallpapers(Promise<> &&promise);
td_api::object_ptr<td_api::wallpapers> get_wallpapers_object() const;
private: private:
void tear_down() override; void tear_down() override;
void on_get_wallpapers(Result<vector<telegram_api::object_ptr<telegram_api::WallPaper>>> result);
struct Wallpaper {
int32 id = 0;
vector<PhotoSize> sizes;
int32 color = 0;
Wallpaper(int32 id, vector<PhotoSize> sizes, int32 color) : id(id), sizes(std::move(sizes)), color(color) {
}
};
vector<Wallpaper> wallpapers_;
vector<Promise<Unit>> pending_get_wallpapers_queries_;
Td *td_; Td *td_;
ActorShared<> parent_; ActorShared<> parent_;
}; };