From 274fed3cb0ab851755a53c8496beb081a83060a7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 30 Apr 2019 16:53:44 +0400 Subject: [PATCH] Move several fields to bit flags in DocumentData. --- Telegram/SourceFiles/data/data_document.cpp | 86 ++++++++++++--------- Telegram/SourceFiles/data/data_document.h | 37 ++++++--- 2 files changed, 77 insertions(+), 46 deletions(-) diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index bebaf6e77..50232afac 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -455,8 +455,8 @@ AuthSession &DocumentData::session() const { void DocumentData::setattributes( const QVector &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(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( id, _dc, origin, @@ -883,21 +884,21 @@ void DocumentData::save( autoLoading, cacheTag()); } else if (hasWebLocation()) { - _loader = new mtpFileLoader( + _loader = std::make_unique( _urlLocation, size, fromCloud, autoLoading, cacheTag()); } else if (!_access && !_url.isEmpty()) { - _loader = new webFileLoader( + _loader = std::make_unique( _url, toFile, fromCloud, autoLoading, cacheTag()); } else { - _loader = new mtpFileLoader( + _loader = std::make_unique( 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 local) { } DocumentData::~DocumentData() { - if (loading()) { - destroyLoader(); - } + destroyLoader(); unload(); ActiveCache().remove(this); } diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index bc35aff1b..89add5cde 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -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 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; + 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 _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 _loader; };