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

View File

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

View File

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