libQuotient
A Qt library for building matrix clients
|
A job pointer and a QFuture in a single package. More...
#include <jobhandle.h>
Public Types | |
using | pointer_type = QPointer< JobT > |
using | future_value_type = JobT * |
using | future_type = QFuture< future_value_type > |
Public Member Functions | |
Q_IMPLICIT | JobHandle (JobT *job=nullptr) |
template<typename ConfigT , ResultHandler< JobT > FnT> | |
auto | onResult (ConfigT config, FnT &&fn) |
Attach a continuation to a successful or unsuccessful completion of the future. More... | |
template<BoundResultHandler< JobT > FnT> | |
auto | onResult (FnT &&fn) |
The overload for onResult matching 1-arg QFuture::then. More... | |
template<typename ConfigT , ResultHandler< JobT > SuccessFnT, ResultHandler< JobT > FailureFnT = Skip> | |
auto | then (ConfigT config, SuccessFnT &&onSuccess, FailureFnT &&onFailure={}) requires requires(future_type f) |
Attach continuations depending on the job success or failure. More... | |
template<BoundResultHandler< JobT > SuccessFnT, BoundResultHandler< JobT > FailureFnT = Skip> | |
auto | then (SuccessFnT &&onSuccess, FailureFnT &&onFailure={}) |
The overload making the combined continuation as if with 1-arg QFuture::then. More... | |
template<typename FnT > | |
auto | onFailure (auto config, FnT &&fn) |
Same as then(config, [] {}, fn) More... | |
template<typename FnT > | |
auto | onFailure (FnT &&fn) |
Same as then([] {}, fn) More... | |
template<typename FnT > | |
auto | onCanceled (QObject *context, FnT &&fn) |
template<typename FnT > | |
auto | onCanceled (FnT &&fn) |
auto | responseFuture () |
Get a QFuture for the value returned by collectResponse() called on the underlying job. More... | |
void | abandon () |
Abandon the underlying job, if there's one pending. More... | |
A job pointer and a QFuture in a single package.
This class wraps a pointer to any job the same way QPointer does: it turns to nullptr when the job is destroyed. On top of that though, it provides you with an interface of QFuture as-if obtained by calling QtFuture::connect(job, &BaseJob::result).then([job] { return job; });
before any other slot is connected to it. In the end, you (still) get the interface of JobT
at handle->
, and handle.
gives you the interface (very close to that, read below for differences) of QFuture<JobT*>
.
You can mix usage of the two interfaces, bearing in mind that any continuation attached via the future interface will overtake anything connected to BaseJob::result
but come behind anything connected to BaseJob::finished
(that applies to onCanceled()
, too).
QFuture is somewhat rigid in terms of what it accepts for (normal, i.e. not cancelled) continuations: the continuation function must accept a single argument of the type carried by the future, or of the future type itself. JobHandle allows normal continuation functions (i.e. those passed to then()
, onResult()
and onFailure()
) to accept:
JobT*
or any pointer it is convertible to (const JobT*
, BaseJob*
etc.);collectResponse()
with the above pointer as the parameter.Aside from free functions and function objects (including lambdas), you can also pass member functions of QObject-derived classes (connect()
slot style) to all continuations, including onCanceled().
JobHandle doesn't support passing its full type to continuation functions like QFuture does, as there's no case for that (we don't need to deal with exceptions).
This extended interface helps with migration of the current code that connect()
s to the job completion signals. The existing code will (mostly) run fine without changes; the only thing that will stop working is using auto*
for a variable initialised from Connection::callApi
(plain auto
still works). If you want to migrate the existing code to the future-like interface, just replace:
with callApi<Job>(jobParams...).onResult(object, slot);
- that's all. If you have a connection to BaseJob::success
, use then()
instead of onResult()
, and if you only connect to BaseJob::failure
, onFailure()
is at your service. And you can also combine the two using then()
, e.g.:
One more extension to QFuture is the way the returned value is treated:
void
the continuation will have type JobHandler<JobT>
and carry the same pointer as before;JobHandle
(e.g. from another call to Connection::callApi
), it will be automatically rewrapped into a QFuture
, because QFuture<JobHandle<AnotherJobT>>
is rather unwieldy for any intents and purposes, and JobHandle<AnotherJobT>
would have a very weird QPointer interface as that new job doesn't even exist when continuation is constructed;Definition at line 73 of file jobhandle.h.
using Quotient::JobHandle< JobT >::future_type = QFuture<future_value_type> |
Definition at line 77 of file jobhandle.h.
using Quotient::JobHandle< JobT >::future_value_type = JobT* |
Definition at line 76 of file jobhandle.h.
using Quotient::JobHandle< JobT >::pointer_type = QPointer<JobT> |
Definition at line 75 of file jobhandle.h.
|
inline |
Definition at line 93 of file jobhandle.h.
|
inline |
Abandon the underlying job, if there's one pending.
Unlike cancel() that only applies to the current future object but not the upstream chain, this actually goes up to the job and calls abandon() on it, thereby cancelling the entire chain of futures attached to it.
Definition at line 201 of file jobhandle.h.
|
inline |
Same as QFuture::onCanceled but accepts QObject-derived member functions and rewraps returned values
Definition at line 184 of file jobhandle.h.
|
inline |
Same as QFuture::onCanceled but accepts QObject-derived member functions and rewraps returned values
Definition at line 175 of file jobhandle.h.
|
inline |
Same as then(config, [] {}, fn)
Definition at line 160 of file jobhandle.h.
|
inline |
Same as then([] {}, fn)
Definition at line 167 of file jobhandle.h.
|
inline |
Attach a continuation to a successful or unsuccessful completion of the future.
The continuation passed via fn
should be an invokable that accepts one of the following: 1) no arguments - this is meant to simplify transition from job completion handlers connect()ed to BaseJob::result, BaseJob::success or BaseJob::failure. 2) a pointer to a (const, if you want) job object - this can be either BaseJob*
, JobT*
(recommended), or anything in between. Unlike slot functions connected to BaseJob signals, this option allows you to access the specific job type so you don't need to carry the original job pointer in a lambda - JobHandle does it for you. This is meant to be a transitional form on the way to (3); eventually we should migrate to (1)+(3) entirely. 3) the type returned by collectResponse()
if it's well-formed (it is for all generated jobs, needs overloading for manual jobs).
config | passed directly to QFuture::then() as the first argument (see the documentation on QFuture::then() for accepted types) and can also be used as the object for a slot-like member function in QObject::connect() fashion |
fn | the continuation function to attach to the future; can be a member function if config is a pointer to an QObject-derived class |
fn
returns void
, a new JobHandle for the same job, with the continuation attached; otherwise, the return value of fn
wrapped in a plain QFuture Definition at line 122 of file jobhandle.h.
|
inline |
The overload for onResult matching 1-arg QFuture::then.
Definition at line 129 of file jobhandle.h.
|
inline |
Get a QFuture for the value returned by collectResponse()
called on the underlying job.
Definition at line 190 of file jobhandle.h.
|
inline |
Attach continuations depending on the job success or failure.
This is inspired by then()
in JavaScript; beyond the first argument passed through to QFuture::then
, it accepts two more arguments (onFailure
is optional), combining them in a single continuation: if the job ends with success, onSuccess
is called; if the job fails, onFailure
is called. The requirements to both functions are the same as to the single function passed to onResult().
Definition at line 142 of file jobhandle.h.
|
inline |
The overload making the combined continuation as if with 1-arg QFuture::then.
Definition at line 152 of file jobhandle.h.