tdesktop/Telegram/SourceFiles/data/data_download_manager.h

210 lines
5.8 KiB
C
Raw Normal View History

2022-02-21 15:40:20 +00:00
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/timer.h"
namespace Ui {
struct DownloadBarProgress;
struct DownloadBarContent;
} // namespace Ui
2022-02-21 15:40:20 +00:00
namespace Main {
class Session;
} // namespace Main
namespace Data {
// Used in serialization!
2022-02-21 15:40:20 +00:00
enum class DownloadType {
Document,
Photo,
};
// unixtime * 1000.
using DownloadDate = int64;
[[nodiscard]] inline TimeId DateFromDownloadDate(DownloadDate date) {
return date / 1000;
}
2022-02-21 15:40:20 +00:00
struct DownloadId {
uint64 objectId = 0;
DownloadType type = DownloadType::Document;
};
struct DownloadProgress {
int64 ready = 0;
int64 total = 0;
};
inline constexpr bool operator==(
const DownloadProgress &a,
const DownloadProgress &b) {
return (a.ready == b.ready) && (a.total == b.total);
}
2022-02-21 15:40:20 +00:00
struct DownloadObject {
2022-02-26 11:51:54 +00:00
not_null<HistoryItem*> item;
2022-02-21 15:40:20 +00:00
DocumentData *document = nullptr;
PhotoData *photo = nullptr;
};
struct DownloadedId {
DownloadId download;
DownloadDate started = 0;
QString path;
2022-05-10 14:22:28 +00:00
int64 size = 0;
2022-02-21 15:40:20 +00:00
FullMsgId itemId;
uint64 peerAccessHash = 0;
std::unique_ptr<DownloadObject> object;
};
struct DownloadingId {
DownloadObject object;
DownloadDate started = 0;
2022-02-27 13:32:36 +00:00
QString path;
2022-05-10 14:22:28 +00:00
int64 ready = 0;
int64 total = 0;
bool hiddenByView = false;
bool done = false;
2022-02-21 15:40:20 +00:00
};
class DownloadManager final {
public:
DownloadManager();
~DownloadManager();
void trackSession(not_null<Main::Session*> session);
void itemVisibilitiesUpdated(not_null<Main::Session*> session);
2022-02-21 15:40:20 +00:00
2022-02-27 13:32:36 +00:00
[[nodiscard]] DownloadDate computeNextStartDate();
2022-02-21 15:40:20 +00:00
void addLoading(DownloadObject object);
void addLoaded(
DownloadObject object,
const QString &path,
DownloadDate started);
void clearIfFinished();
void deleteFiles(const std::vector<GlobalMsgId> &ids);
void deleteAll();
[[nodiscard]] bool loadedHasNonCloudFile() const;
[[nodiscard]] auto loadingList() const
2022-02-26 11:51:54 +00:00
-> ranges::any_view<const DownloadingId*, ranges::category::input>;
[[nodiscard]] DownloadProgress loadingProgress() const;
[[nodiscard]] rpl::producer<> loadingListChanges() const;
[[nodiscard]] auto loadingProgressValue() const
-> rpl::producer<DownloadProgress>;
2022-03-09 11:30:22 +00:00
[[nodiscard]] bool loadingInProgress(
Main::Session *onlyInSession = nullptr) const;
void loadingStopWithConfirmation(
Fn<void()> callback,
Main::Session *onlyInSession = nullptr);
[[nodiscard]] auto loadedList()
2022-02-26 11:51:54 +00:00
-> ranges::any_view<const DownloadedId*, ranges::category::input>;
[[nodiscard]] auto loadedAdded() const
-> rpl::producer<not_null<const DownloadedId*>>;
[[nodiscard]] auto loadedRemoved() const
-> rpl::producer<not_null<const HistoryItem*>>;
[[nodiscard]] rpl::producer<> loadedResolveDone() const;
2022-02-26 11:51:54 +00:00
2022-02-21 15:40:20 +00:00
private:
struct DeleteFilesDescriptor;
2022-02-21 15:40:20 +00:00
struct SessionData {
std::vector<DownloadedId> downloaded;
std::vector<DownloadingId> downloading;
int resolveNeeded = 0;
int resolveSentRequests = 0;
int resolveSentTotal = 0;
2022-02-21 15:40:20 +00:00
rpl::lifetime lifetime;
};
void check(not_null<const HistoryItem*> item);
void check(not_null<DocumentData*> document);
void check(
SessionData &data,
std::vector<DownloadingId>::iterator i);
2022-02-21 15:40:20 +00:00
void changed(not_null<const HistoryItem*> item);
void removed(not_null<const HistoryItem*> item);
2022-02-26 11:51:54 +00:00
void detach(DownloadedId &id);
2022-02-21 15:40:20 +00:00
void untrack(not_null<Main::Session*> session);
void remove(
SessionData &data,
std::vector<DownloadingId>::iterator i);
void cancel(
SessionData &data,
std::vector<DownloadingId>::iterator i);
void clearLoading();
2022-02-21 15:40:20 +00:00
[[nodiscard]] SessionData &sessionData(not_null<Main::Session*> session);
[[nodiscard]] const SessionData &sessionData(
not_null<Main::Session*> session) const;
2022-02-21 15:40:20 +00:00
[[nodiscard]] SessionData &sessionData(
not_null<const HistoryItem*> item);
[[nodiscard]] SessionData &sessionData(not_null<DocumentData*> document);
2022-02-21 15:40:20 +00:00
void resolve(not_null<Main::Session*> session, SessionData &data);
void resolveRequestsFinished(
not_null<Main::Session*> session,
SessionData &data);
void checkFullResolveDone();
[[nodiscard]] not_null<HistoryItem*> regenerateItem(
const DownloadObject &previous);
[[nodiscard]] not_null<HistoryItem*> generateFakeItem(
not_null<DocumentData*> document);
[[nodiscard]] not_null<HistoryItem*> generateItem(
HistoryItem *previousItem,
DocumentData *document,
PhotoData *photo);
void generateEntry(not_null<Main::Session*> session, DownloadedId &id);
2022-03-09 11:30:22 +00:00
[[nodiscard]] HistoryItem *lookupLoadingItem(
Main::Session *onlyInSession) const;
void loadingStop(Main::Session *onlyInSession);
void finishFilesDelete(DeleteFilesDescriptor &&descriptor);
void writePostponed(not_null<Main::Session*> session);
[[nodiscard]] Fn<std::optional<QByteArray>()> serializator(
not_null<Main::Session*> session) const;
[[nodiscard]] std::vector<DownloadedId> deserialize(
not_null<Main::Session*> session) const;
2022-02-21 15:40:20 +00:00
base::flat_map<not_null<Main::Session*>, SessionData> _sessions;
base::flat_set<not_null<const HistoryItem*>> _loading;
base::flat_set<not_null<DocumentData*>> _loadingDocuments;
base::flat_set<not_null<const HistoryItem*>> _loadingDone;
base::flat_set<not_null<const HistoryItem*>> _loaded;
2022-02-26 11:51:54 +00:00
base::flat_set<not_null<HistoryItem*>> _generated;
base::flat_set<not_null<DocumentData*>> _generatedDocuments;
2022-02-26 11:51:54 +00:00
TimeId _lastStartedBase = 0;
int _lastStartedAdded = 0;
rpl::event_stream<> _loadingListChanges;
rpl::variable<DownloadProgress> _loadingProgress;
2022-02-21 15:40:20 +00:00
2022-02-26 11:51:54 +00:00
rpl::event_stream<not_null<const DownloadedId*>> _loadedAdded;
rpl::event_stream<not_null<const HistoryItem*>> _loadedRemoved;
rpl::variable<bool> _loadedResolveDone;
2022-02-26 11:51:54 +00:00
base::Timer _clearLoadingTimer;
2022-02-21 15:40:20 +00:00
};
[[nodiscard]] auto MakeDownloadBarProgress()
-> rpl::producer<Ui::DownloadBarProgress>;
[[nodiscard]] rpl::producer<Ui::DownloadBarContent> MakeDownloadBarContent();
2022-02-21 15:40:20 +00:00
} // namespace Data