void tst_QFuture::statePropagation() { QFuture<void> f1; QFuture<void> f2; QCOMPARE(f1.isStarted(), true); QFutureInterface<void> result; result.reportStarted(); f1 = result.future(); f2 = f1; QCOMPARE(f2.isStarted(), true); result.reportCanceled(); QCOMPARE(f2.isStarted(), true); QCOMPARE(f2.isCanceled(), true); QFuture<void> f3 = f2; QCOMPARE(f3.isStarted(), true); QCOMPARE(f3.isCanceled(), true); result.reportFinished(); QCOMPARE(f2.isStarted(), true); QCOMPARE(f2.isCanceled(), true); QCOMPARE(f3.isStarted(), true); QCOMPARE(f3.isCanceled(), true); }
QFuture<QImage> PhotoStorage::GetImage (const QUrl& url) { QFutureInterface<QImage> iface; iface.reportStarted (); if (Pending_.contains (url)) return Pending_.value (url); const auto& future = iface.future (); Pending_ [url] = future; FetchQueue_->Schedule ([=] () mutable { const auto& reply = NAM_->get (QNetworkRequest (url)); new Util::SlotClosure<Util::DeleteLaterPolicy> { [=] { Pending_.remove (url); HandleReplyFinished (reply, iface); }, reply, SIGNAL (finished ()), reply }; }); return future; }
void tst_QFuture::progressText() { QFutureInterface<void> i; i.reportStarted(); QFuture<void> f = i.future(); QCOMPARE(f.progressText(), QLatin1String("")); i.setProgressValueAndText(1, QLatin1String("foo")); QCOMPARE(f.progressText(), QLatin1String("foo")); i.reportFinished(); }
bool BaseTextDocument::open(QString *errorString, const QString &fileName, const QString &realFileName) { QString title = tr("untitled"); QStringList content; ReadResult readResult = Utils::TextFileFormat::ReadIOError; if (!fileName.isEmpty()) { const QFileInfo fi(fileName); d->m_fileIsReadOnly = !fi.isWritable(); d->m_fileName = QDir::cleanPath(fi.absoluteFilePath()); title = fi.fileName(); readResult = read(realFileName, &content, errorString); d->m_document->setModified(false); const int chunks = content.size(); if (chunks == 0) { d->m_document->setPlainText(QString()); } else if (chunks == 1) { d->m_document->setPlainText(content.at(0)); } else { QFutureInterface<void> interface; interface.setProgressRange(0, chunks); Core::ICore::progressManager()->addTask( interface.future(), tr("Opening file"), QLatin1String(Constants::TASK_OPEN_FILE)); interface.reportStarted(); d->m_document->setUndoRedoEnabled(false); QTextCursor c(d->m_document); c.beginEditBlock(); d->m_document->clear(); for (int i = 0; i < chunks; ++i) { c.insertText(content.at(i)); interface.setProgressValue(i + 1); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); } c.endEditBlock(); d->m_document->setUndoRedoEnabled(true); interface.reportFinished(); } BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(d->m_document->documentLayout()); QTC_ASSERT(documentLayout, return true); documentLayout->lastSaveRevision = d->m_autoSaveRevision = d->m_document->revision(); d->m_document->setModified(fileName != realFileName); emit titleChanged(title); emit changed(); } return readResult == Utils::TextFileFormat::ReadSuccess || readResult == Utils::TextFileFormat::ReadEncodingError; }
/* Test that QFuture<T> can be implicitly converted to T */ void tst_QFuture::implicitConversions() { QFutureInterface<QString> iface; iface.reportStarted(); QFuture<QString> f(&iface); const QString input("FooBar 2000"); iface.reportFinished(&input); const QString result = f; QCOMPARE(result, input); QCOMPARE(QString(f), input); QCOMPARE(static_cast<QString>(f), input); }
QFuture<QImage> SelfAvatarFetcher::FetchAvatar (IHaveAvatars::Size size) const { QUrl url; switch (size) { case IHaveAvatars::Size::Thumbnail: url = Urls_.SmallUrl_; break; case IHaveAvatars::Size::Full: url = Urls_.BigUrl_; break; } if (!url.isValid ()) { qWarning () << Q_FUNC_INFO << "invalid URL for" << static_cast<int> (size) << FullAddress_; return Util::MakeReadyFuture<QImage> ({}); } QFutureInterface<QImage> iface; iface.reportStarted (); const auto reply = NAM_->get (QNetworkRequest { url }); new Util::SlotClosure<Util::DeleteLaterPolicy> { [iface, reply] () mutable { reply->deleteLater (); const auto& image = QImage::fromData (reply->readAll ()); iface.reportFinished (&image); }, reply, SIGNAL (finished ()), reply }; return iface.future (); }
void tst_QFuture::progress() { QFutureInterface<QChar> result; QFuture<QChar> f; QCOMPARE (f.progressValue(), 0); result.reportStarted(); f = result.future(); QCOMPARE (f.progressValue(), 0); result.setProgressValue(50); QCOMPARE (f.progressValue(), 50); result.reportFinished(); QCOMPARE (f.progressValue(), 50); }
QFuture<QImage> EntryBase::RefreshAvatar (Size) { const auto maybeVCard = Account_->GetParentProtocol ()-> GetVCardStorage ()->GetVCard (GetHumanReadableID ()); if (maybeVCard && VCardPhotoHash_ == ComputeVCardPhotoHash (*maybeVCard)) return Util::MakeReadyFuture (QImage::fromData (maybeVCard->photo ())); QFutureInterface<QImage> iface; iface.reportStarted (); Account_->GetClientConnection ()->FetchVCard (GetJID (), [iface] (const QXmppVCardIq& iq) mutable { const auto& photo = iq.photo (); const auto image = photo.isEmpty () ? QImage {} : QImage::fromData (photo); iface.reportFinished (&image); }); return iface.future (); }
QFuture<DeadLyRicS::LyricsQueryResult_t> DeadLyRicS::RequestLyrics (const Media::LyricsQuery& query) { if (query.Artist_.isEmpty () || query.Title_.isEmpty ()) return Util::MakeReadyFuture (LyricsQueryResult_t { tr ("Not enough parameters to build a search query.") }); QFutureInterface<LyricsQueryResult_t> promise; promise.reportStarted (); promise.setExpectedResultCount (Searchers_.size ()); for (auto searcher : Searchers_) searcher->Search (query, [promise] (const LyricsQueryResult_t& result) mutable { const auto currentCount = promise.resultCount (); promise.reportResult (result, currentCount); if (currentCount + 1 == promise.expectedResultCount ()) promise.reportFinished (); }); return promise.future (); }
void testRefCounting() { QFutureInterface<T> interface; QCOMPARE(interface.d->refCount.load(), 1); { interface.reportStarted(); QFuture<T> f = interface.future(); QCOMPARE(interface.d->refCount.load(), 2); QFuture<T> f2(f); QCOMPARE(interface.d->refCount.load(), 3); QFuture<T> f3; f3 = f2; QCOMPARE(interface.d->refCount.load(), 4); interface.reportFinished(0); QCOMPARE(interface.d->refCount.load(), 4); } QCOMPARE(interface.d->refCount.load(), 1); }
void tst_QFuture::iterators() { { QFutureInterface<int> e; e.reportStarted(); QFuture<int> f = e.future(); int result; result = 1; e.reportResult(&result); result = 2; e.reportResult(&result); result = 3; e.reportResult(&result); e.reportFinished(); QList<int> results; QFutureIterator<int> i(f); while (i.hasNext()) { results.append(i.next()); } QCOMPARE(results, f.results()); QFuture<int>::const_iterator i1 = f.begin(), i2 = i1 + 1; QFuture<int>::const_iterator c1 = i1, c2 = c1 + 1; QCOMPARE(i1, i1); QCOMPARE(i1, c1); QCOMPARE(c1, i1); QCOMPARE(c1, c1); QCOMPARE(i2, i2); QCOMPARE(i2, c2); QCOMPARE(c2, i2); QCOMPARE(c2, c2); QVERIFY(i1 != i2); QVERIFY(i1 != c2); QVERIFY(c1 != i2); QVERIFY(c1 != c2); QVERIFY(i2 != i1); QVERIFY(i2 != c1); QVERIFY(c2 != i1); QVERIFY(c2 != c1); int x1 = *i1; Q_UNUSED(x1); int x2 = *i2; Q_UNUSED(x2); int y1 = *c1; Q_UNUSED(y1); int y2 = *c2; Q_UNUSED(y2); } { QFutureInterface<QString> e; e.reportStarted(); QFuture<QString> f = e.future(); e.reportResult(QString("one")); e.reportResult(QString("two")); e.reportResult(QString("three")); e.reportFinished(); QList<QString> results; QFutureIterator<QString> i(f); while (i.hasNext()) { results.append(i.next()); } QCOMPARE(results, f.results()); QFuture<QString>::const_iterator i1 = f.begin(), i2 = i1 + 1; QFuture<QString>::const_iterator c1 = i1, c2 = c1 + 1; QCOMPARE(i1, i1); QCOMPARE(i1, c1); QCOMPARE(c1, i1); QCOMPARE(c1, c1); QCOMPARE(i2, i2); QCOMPARE(i2, c2); QCOMPARE(c2, i2); QCOMPARE(c2, c2); QVERIFY(i1 != i2); QVERIFY(i1 != c2); QVERIFY(c1 != i2); QVERIFY(c1 != c2); QVERIFY(i2 != i1); QVERIFY(i2 != c1); QVERIFY(c2 != i1); QVERIFY(c2 != c1); QString x1 = *i1; QString x2 = *i2; QString y1 = *c1; QString y2 = *c2; QCOMPARE(x1, y1); QCOMPARE(x2, y2); int i1Size = i1->size(); int i2Size = i2->size(); int c1Size = c1->size(); int c2Size = c2->size(); QCOMPARE(i1Size, c1Size); QCOMPARE(i2Size, c2Size); } { const int resultCount = 20; QFutureInterface<int> e; e.reportStarted(); QFuture<int> f = e.future(); for (int i = 0; i < resultCount; ++i) { e.reportResult(i); } e.reportFinished(); { QFutureIterator<int> it(f); QFutureIterator<int> it2(it); } { QFutureIterator<int> it(f); for (int i = 0; i < resultCount - 1; ++i) { QVERIFY(it.hasNext()); QCOMPARE(it.peekNext(), i); QCOMPARE(it.next(), i); } QVERIFY(it.hasNext()); QCOMPARE(it.peekNext(), resultCount - 1); QCOMPARE(it.next(), resultCount - 1); QVERIFY(!it.hasNext()); } { QFutureIterator<int> it(f); QVERIFY(it.hasNext()); it.toBack(); QVERIFY(!it.hasNext()); it.toFront(); QVERIFY(it.hasNext()); } } }
/* Test out-of-order result reporting using indexes */ void tst_QFuture::indexedResults() { { QFutureInterface<QChar> Interface; QFuture<QChar> f; QVERIFY(f.isStarted()); Interface.reportStarted(); f = Interface.future(); QVERIFY(f.isStarted()); QChar result; result = 'B'; Interface.reportResult(&result, 1); QCOMPARE(f.resultAt(1), result); result = 'A'; Interface.reportResult(&result, 0); QCOMPARE(f.resultAt(0), result); result = 'C'; Interface.reportResult(&result); // no index QCOMPARE(f.resultAt(2), result); Interface.reportFinished(); QCOMPARE(f.results(), QList<QChar>() << 'A' << 'B' << 'C'); } { // Test result reporting with a missing result in the middle QFutureInterface<int> Interface; Interface.reportStarted(); QFuture<int> f = Interface.future(); int result; result = 0; Interface.reportResult(&result, 0); QVERIFY(f.isResultReadyAt(0)); QCOMPARE(f.resultAt(0), 0); result = 3; Interface.reportResult(&result, 3); QVERIFY(f.isResultReadyAt(3)); QCOMPARE(f.resultAt(3), 3); result = 2; Interface.reportResult(&result, 2); QVERIFY(f.isResultReadyAt(2)); QCOMPARE(f.resultAt(2), 2); result = 4; Interface.reportResult(&result); // no index QVERIFY(f.isResultReadyAt(4)); QCOMPARE(f.resultAt(4), 4); Interface.reportFinished(); QCOMPARE(f.results(), QList<int>() << 0 << 2 << 3 << 4); } }
void tst_QFuture::cancel() { { QFuture<void> f; QFutureInterface<void> result; result.reportStarted(); f = result.future(); QVERIFY(!f.isCanceled()); result.reportCanceled(); QVERIFY(f.isCanceled()); result.reportFinished(); QVERIFY(f.isCanceled()); f.waitForFinished(); QVERIFY(f.isCanceled()); } // Cancel from the QFuture side and test if the result // interface detects it. { QFutureInterface<void> result; QFuture<void> f; QVERIFY(f.isStarted()); result.reportStarted(); f = result.future(); QVERIFY(f.isStarted()); QVERIFY(!result.isCanceled()); f.cancel(); QVERIFY(result.isCanceled()); result.reportFinished(); } // Test that finished futures can be canceled. { QFutureInterface<void> result; QFuture<void> f; QVERIFY(f.isStarted()); result.reportStarted(); f = result.future(); QVERIFY(f.isStarted()); result.reportFinished(); f.cancel(); QVERIFY(result.isCanceled()); QVERIFY(f.isCanceled()); } // Results reported after canceled is called should not be propagated. { QFutureInterface<int> futureInterface; futureInterface.reportStarted(); QFuture<int> f = futureInterface.future(); int result = 0; futureInterface.reportResult(&result); result = 1; futureInterface.reportResult(&result); f.cancel(); result = 2; futureInterface.reportResult(&result); result = 3; futureInterface.reportResult(&result); futureInterface.reportFinished(); QCOMPARE(f.results(), QList<int>()); } }
void tst_QFuture::futureInterface() { { QFuture<void> future; { QFutureInterface<void> i; i.reportStarted(); future = i.future(); i.reportFinished(); } } { QFuture<int> future; { QFutureInterface<int> i; i.reportStarted(); i.reportResult(10); future = i.future(); i.reportFinished(); } QCOMPARE(future.resultAt(0), 10); } { QFuture<int> intFuture; QCOMPARE(intFuture.isStarted(), true); QCOMPARE(intFuture.isFinished(), true); IntResult result; result.reportStarted(); intFuture = result.future(); QCOMPARE(intFuture.isStarted(), true); QCOMPARE(intFuture.isFinished(), false); result.reportFinished(&value); QCOMPARE(intFuture.isStarted(), true); QCOMPARE(intFuture.isFinished(), true); int e = intFuture.result(); QCOMPARE(intFuture.isStarted(), true); QCOMPARE(intFuture.isFinished(), true); QCOMPARE(intFuture.isCanceled(), false); QCOMPARE(e, value); intFuture.waitForFinished(); IntResult intAlgo; intFuture = intAlgo.run(); QFuture<int> intFuture2(intFuture); QCOMPARE(intFuture.result(), value); QCOMPARE(intFuture2.result(), value); intFuture.waitForFinished(); VoidResult a; a.run().waitForFinished(); } }