Skip to content
This repository was archived by the owner on Dec 12, 2023. It is now read-only.

v0.1 Release

Compare
Choose a tag to compare
@benlau benlau released this 19 Mar 18:14
· 225 commits to master since this release

Features

1. Convert a signal from QObject into a QFuture object

#include "asyncfuture.h"
using namespace AsyncFuture;

// Convert a signal from QObject into a QFuture object

QFuture<void> future = observe(timer,
                               &QTimer::timeout).future();

/* Listen from the future without using QFutureWatcher<T>*/
observe(future).subscribe([]() {
    // onCompleted. It is invoked when the observed future is finished successfully
    qDebug() << "onCompleted";
},[]() {
    // onCanceled
    qDebug() << "onCancel";
});

/* It is chainable. Listen from a timeout signal only once */
observe(timer, &QTimer::timeout).subscribe([=]() { /**/ });

2. Combine multiple futures with different type into a single future object

/* Combine multiple futures with different type into a single future */

QFuture<QImage> f1 = QtConcurrent::run(readImage, QString("image.jpg"));

QFuture<void> f2 = observe(timer, &QTimer::timeout).future();

(combine() << f1 << f2).subscribe([](QVariantList result){
    // Read an image
    // result[0] = QImage
    qDebug() << result;
});

3. Advanced multi-threading model

/* Start a thread and process its result in main thread */

QFuture<QImage> reading = QtConcurrent::run(readImage, QString("image.jpg"));

QFuture<bool> validating = observe(reading).context(contextObject, validator).future();

    // Read image by a thread, when it is ready, run the validator function
    // in the thread of the contextObject(e.g main thread)
    // And it return another QFuture to represent the final result.

/* Start a thread and process its result in main thread, then start another thread. */

QFuture<int> f1 = QtConcurrent::mapped(input, mapFunc);

QFuture<int> f2 = observe(f1).context(contextObject, [=](QFuture<int> future) {
    // You may use QFuture as the input argument of your callback function
    // It will be set to the observed future object. So that you may obtain
    // the value of results()

    qDebug() << future.results();

    // Return another QFuture is possible.
    return QtConcurrent::run(reducerFunc, future.results());
}).future();

// f2 is constructed before the QtConcurrent::run statement
// But its value is equal to the result of reducerFunc

4. Promise like interface

The deferred() function return a Deferred object that allows you to manipulate a QFuture manually. The future() function return a forever running QFuture unless you have called Deferred.complete() / Deferred.cancel() manually, or the Deferred object is destroyed without observed any future.

The usage of complete/cancel with a Deferred object is pretty similar to the resolve/reject in a Promise object. You could complete a future by calling complete with a result value. If you give it another future, then it will observe the input future and change status once that is finished.

Complete / cancel a future on your own choice

// Complete / cancel a future on your own choice
auto d = deferred<bool>();

observe(d.future()).subscribe([]() {
    qDebug() << "onCompleted";
}, []() {
    qDebug() << "onCancel";
});

d.complete(true); // or d.cancel();

QCOMPARE(d.future().isFinished(), true);
QCOMPARE(d.future().isCanceled(), false);

Complete / cancel a future according to another future object.

// Complete / cancel a future according to another future object.

auto d = deferred<void>();

d.complete(QtConcurrent::run(timeout));

QCOMPARE(d.future().isFinished(), true);
QCOMPARE(d.future().isCanceled(), false);

Read a file. If timeout, cancel it.

auto timeout = observe(timer, &QTimer::timeout).future();

auto defer = deferred<QString>();

defer.complete(QtConcurrent::run(readFileworker, fileName));
defer.cancel(timeout);

return defer.future();

More examples are available at : asyncfuture/example.cpp at master · benlau/asyncfuture

Installation

AsyncFuture is a single header library. You could just download the asyncfuture.h in your source tree or install it via qpm

qpm install async.future.pri 

or

wget https://raw.githubusercontent.com/benlau/asyncfuture/master/asyncfuture.h