1
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-03-31 15:59:54 +00:00

Move several fields to bit flags in DocumentData.

This commit is contained in:
John Preston 2019-04-30 16:53:44 +04:00
parent 021ada5e9e
commit 274fed3cb0
2 changed files with 77 additions and 46 deletions
Telegram/SourceFiles/data

View File

@ -455,8 +455,8 @@ AuthSession &DocumentData::session() const {
void DocumentData::setattributes(
const QVector<MTPDocumentAttribute> &attributes) {
_isImage = false;
_supportsStreaming = SupportsStreaming::Unknown;
_flags &= ~(Flag::ImageType | kStreamingSupportedMask);
_flags |= kStreamingSupportedUnknown;
for (const auto &attribute : attributes) {
attribute.match([&](const MTPDdocumentAttributeImageSize & data) {
dimensions = QSize(data.vw.v, data.vh.v);
@ -732,15 +732,17 @@ void DocumentData::automaticLoadSettingsChanged() {
return;
}
_loader = nullptr;
_flags &= ~Flag::DownloadCancelled;
}
bool DocumentData::loaded(FilePathResolve resolve) const {
if (loading() && _loader->finished()) {
if (_loader->cancelled()) {
destroyLoader(CancelledFileLoader);
_flags |= Flag::DownloadCancelled;
destroyLoader();
} else {
auto that = const_cast<DocumentData*>(this);
that->_location = FileLocation(_loader->fileName());
that->setLocation(FileLocation(_loader->fileName()));
ActiveCache().decrement(that->_data.size());
that->_data = _loader->bytes();
ActiveCache().increment(that->_data.size());
@ -769,17 +771,19 @@ bool DocumentData::loaded(FilePathResolve resolve) const {
return !data().isEmpty() || !filepath(resolve).isEmpty();
}
void DocumentData::destroyLoader(FileLoader *newValue) const {
const auto loader = std::exchange(_loader, newValue);
void DocumentData::destroyLoader() const {
if (!_loader) {
return;
}
const auto loader = base::take(_loader);
if (cancelled()) {
loader->cancel();
}
loader->stop();
delete loader;
}
bool DocumentData::loading() const {
return _loader && !cancelled();
return (_loader != nullptr);
}
QString DocumentData::loadingFilePath() const {
@ -850,13 +854,10 @@ void DocumentData::save(
return;
}
if (cancelled()) {
_loader = nullptr;
}
if (_loader) {
if (!_loader->setFileName(toFile)) {
cancel();
_loader = nullptr;
_flags &= ~Flag::DownloadCancelled;
}
}
@ -868,7 +869,7 @@ void DocumentData::save(
status = FileReady;
auto reader = owner().documentStreamedReader(this, origin, true);
if (reader) {
_loader = new Storage::StreamedFileDownloader(
_loader = std::make_unique<Storage::StreamedFileDownloader>(
id,
_dc,
origin,
@ -883,21 +884,21 @@ void DocumentData::save(
autoLoading,
cacheTag());
} else if (hasWebLocation()) {
_loader = new mtpFileLoader(
_loader = std::make_unique<mtpFileLoader>(
_urlLocation,
size,
fromCloud,
autoLoading,
cacheTag());
} else if (!_access && !_url.isEmpty()) {
_loader = new webFileLoader(
_loader = std::make_unique<webFileLoader>(
_url,
toFile,
fromCloud,
autoLoading,
cacheTag());
} else {
_loader = new mtpFileLoader(
_loader = std::make_unique<mtpFileLoader>(
StorageFileLocation(
_dc,
session().userId(),
@ -916,8 +917,16 @@ void DocumentData::save(
cacheTag());
}
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(documentLoadProgress(FileLoader*)));
_loader->connect(_loader, SIGNAL(failed(FileLoader*,bool)), App::main(), SLOT(documentLoadFailed(FileLoader*,bool)));
QObject::connect(
_loader.get(),
&FileLoader::progress,
App::main(),
[=](FileLoader *l) { App::main()->documentLoadProgress(l); });
QObject::connect(
_loader.get(),
&FileLoader::failed,
App::main(),
&MainWidget::documentLoadFailed);
}
if (loading()) {
_loader->start();
@ -930,13 +939,14 @@ void DocumentData::cancel() {
return;
}
destroyLoader(CancelledFileLoader);
_flags |= Flag::DownloadCancelled;
destroyLoader();
_owner->notifyDocumentLayoutChanged(this);
App::main()->documentLoadProgress(this);
}
bool DocumentData::cancelled() const {
return (_loader == CancelledFileLoader);
return (_flags & Flag::DownloadCancelled);
}
VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit) {
@ -1208,17 +1218,17 @@ bool DocumentData::canBeStreamed() const {
}
bool DocumentData::canBePlayed() const {
return !_inappPlaybackFailed
return !(_flags & Flag::StreamingPlaybackFailed)
&& useStreamingLoader()
&& (loaded() || canBeStreamed());
}
void DocumentData::setInappPlaybackFailed() {
_inappPlaybackFailed = true;
_flags |= Flag::StreamingPlaybackFailed;
}
bool DocumentData::inappPlaybackFailed() const {
return _inappPlaybackFailed;
return (_flags & Flag::StreamingPlaybackFailed);
}
auto DocumentData::createStreamingLoader(
@ -1367,7 +1377,8 @@ bool DocumentData::isVideoMessage() const {
bool DocumentData::isAnimation() const {
return (type == AnimatedDocument)
|| isVideoMessage()
|| (hasMimeType(qstr("image/gif")) && !_inappPlaybackFailed);
|| (hasMimeType(qstr("image/gif"))
&& !(_flags & Flag::StreamingPlaybackFailed));
}
bool DocumentData::isGifv() const {
@ -1430,30 +1441,37 @@ TimeId DocumentData::getDuration() const {
}
bool DocumentData::isImage() const {
return _isImage;
return (_flags & Flag::ImageType);
}
bool DocumentData::supportsStreaming() const {
return (_supportsStreaming == SupportsStreaming::MaybeYes);
return (_flags & kStreamingSupportedMask) == kStreamingSupportedMaybeYes;
}
void DocumentData::setNotSupportsStreaming() {
_supportsStreaming = SupportsStreaming::No;
_flags &= ~kStreamingSupportedMask;
_flags |= kStreamingSupportedNo;
}
void DocumentData::setMaybeSupportsStreaming(bool supports) {
if (_supportsStreaming == SupportsStreaming::No) {
if ((_flags & kStreamingSupportedMask) == kStreamingSupportedNo) {
return;
}
_supportsStreaming = supports
? SupportsStreaming::MaybeYes
: SupportsStreaming::MaybeNo;
_flags &= ~kStreamingSupportedMask;
_flags |= supports
? kStreamingSupportedMaybeYes
: kStreamingSupportedMaybeNo;
}
void DocumentData::recountIsImage() {
_isImage = !isAnimation()
const auto isImage = !isAnimation()
&& !isVideoFile()
&& fileIsImage(filename(), mimeString());
if (isImage) {
_flags |= Flag::ImageType;
} else {
_flags &= ~Flag::ImageType;
}
}
bool DocumentData::thumbnailEnoughForSticker() const {
@ -1509,9 +1527,7 @@ void DocumentData::collectLocalData(not_null<DocumentData*> local) {
}
DocumentData::~DocumentData() {
if (loading()) {
destroyLoader();
}
destroyLoader();
unload();
ActiveCache().remove(this);
}

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/flags.h"
#include "data/data_types.h"
#include "ui/image/image.h"
@ -236,12 +237,29 @@ public:
std::unique_ptr<Data::UploadState> uploadingData;
private:
enum class SupportsStreaming : uchar {
Unknown,
MaybeYes,
MaybeNo,
No,
enum class Flag : uchar {
StreamingMaybeYes = 0x01,
StreamingMaybeNo = 0x02,
StreamingPlaybackFailed = 0x04,
ImageType = 0x08,
DownloadCancelled = 0x10,
LoadedInMediaCache = 0x20,
};
using Flags = base::flags<Flag>;
friend constexpr bool is_flag_type(Flag) { return true; };
static constexpr Flags kStreamingSupportedMask = Flags()
| Flag::StreamingMaybeYes
| Flag::StreamingMaybeNo;
static constexpr Flags kStreamingSupportedUnknown = Flags()
| Flag::StreamingMaybeYes
| Flag::StreamingMaybeNo;
static constexpr Flags kStreamingSupportedMaybeYes = Flags()
| Flag::StreamingMaybeYes;
static constexpr Flags kStreamingSupportedMaybeNo = Flags()
| Flag::StreamingMaybeNo;
static constexpr Flags kStreamingSupportedNo = Flags();
friend class Serialize::Document;
LocationType locationType() const;
@ -249,7 +267,7 @@ private:
void validateGoodThumbnail();
void setMaybeSupportsStreaming(bool supports);
void destroyLoader(FileLoader *newValue = nullptr) const;
void destroyLoader() const;
[[nodiscard]] bool useStreamingLoader() const;
[[nodiscard]] bool thumbnailEnoughForSticker() const;
@ -274,11 +292,8 @@ private:
QByteArray _data;
std::unique_ptr<DocumentAdditionalData> _additional;
int32 _duration = -1;
bool _isImage = false;
SupportsStreaming _supportsStreaming = SupportsStreaming::Unknown;
bool _inappPlaybackFailed = false;
mutable FileLoader *_loader = nullptr;
mutable Flags _flags = kStreamingSupportedUnknown;
mutable std::unique_ptr<FileLoader> _loader;
};