32 #include <type_traits>
35 #include <QFutureWatcher>
36 #include <QtConcurrentRun>
69 template<
typename RetType,
typename ResultHandler>
72 void operator() (
const ResultHandler& rh, QFutureWatcher<RetType> *watcher)
const
74 rh (watcher->result ());
78 template<
typename ResultHandler>
81 void operator() (
const ResultHandler& rh, QFutureWatcher<void>*)
const
111 template<
typename Executor,
typename ResultHandler,
typename... Args>
115 "The passed functor should return a QFuture.");
120 const auto watcher =
new QFutureWatcher<RetType_t> { parent };
126 SIGNAL (finished ()),
130 watcher->setFuture (f (args...));
147 template<
typename Executor,
typename... Args>
153 using FutureType_t =
typename std::result_of<Executor (Args...)>::type;
160 const std::function<FutureType_t ()> Functor_;
161 QFutureWatcher<RetType_t> BaseWatcher_;
162 QObject *LastWatcher_ = &BaseWatcher_;
172 , Functor_ { [f, args...] {
return f (args...); } }
173 , BaseWatcher_ {
this }
184 BaseWatcher_.setFuture (Functor_ ());
207 template<
typename RetT,
typename ArgT>
208 void Then (
const std::function<
QFuture<RetT> (ArgT)>& action)
210 const auto last =
dynamic_cast<QFutureWatcher<ArgT>*
> (LastWatcher_);
214 throw std::runtime_error { std::string {
"invalid type in " } + Q_FUNC_INFO };
217 const auto watcher =
new QFutureWatcher<RetT> {
this };
218 LastWatcher_ = watcher;
220 new SlotClosure<DeleteLaterPolicy>
222 [
this, last, watcher, action]
224 if (last != &BaseWatcher_)
225 last->deleteLater ();
226 watcher->setFuture (action (last->result ()));
229 SIGNAL (finished ()),
254 template<
typename ArgT>
255 void Then (
const std::function<
void (ArgT)>& action)
257 const auto last =
dynamic_cast<QFutureWatcher<ArgT>*
> (LastWatcher_);
261 throw std::runtime_error { std::string {
"invalid type in " } + Q_FUNC_INFO };
264 new SlotClosure<DeleteLaterPolicy>
268 action (last->result ());
272 SIGNAL (finished ()),
294 template<
typename Ret,
typename E0,
typename... A0>
297 std::shared_ptr<void> ExecuteGuard_;
301 : ExecuteGuard_ { guard }
314 : ExecuteGuard_ {
nullptr, [sequencer] (
void*) { sequencer->Start (); } }
324 SequenceProxy (
const SequenceProxy& proxy) =
default;
331 SequenceProxy (SequenceProxy&& proxy) =
default;
351 return { ExecuteGuard_, Seq_ };
367 auto Then (
const F& f) ->
typename std::enable_if<std::is_same<void, decltype (f (std::declval<Ret> ()))>::value>::type
369 Seq_->template Then<Ret> (f);
441 template<
typename Executor,
typename... Args>
A proxy object allowing type-checked sequencing of actions and responsible for starting the initial a...
typename UnwrapFutureType< T >::type UnwrapFutureType_t
static constexpr bool Result_
SequenceProxy(Sequencer< E0, A0...> *sequencer)
Constructs a sequencer proxy managing the given sequencer.
Incapsulates the sequencing logic of asynchronous actions.
Executes a given functor upon a signal (or a list of signals).
auto Then(const F &f) -> typename std::enable_if< std::is_same< void, decltype(f(std::declval< Ret >()))>::value >::type
Adds the funtor f to the chain of actions and closes the chain.
detail::SequenceProxy< typename detail::Sequencer< Executor, Args...>::RetType_t, Executor, Args...> Sequence(QObject *parent, Executor f, Args...args)
Creates a sequencer that allows chaining multiple futures.
UnwrapFutureType_t< FutureType_t > RetType_t
The type instantinating the QFuture returned by the Executor.
Sequencer(Executor f, Args...args, QObject *parent)
Constructs the sequencer.
auto Then(const F &f) -> SequenceProxy< UnwrapFutureType_t< decltype(f(std::declval< Ret >()))>, E0, A0...>
Adds the functor f to the chain of actions.
void ExecuteFuture(Executor f, ResultHandler rh, QObject *parent, Args...args)
Runs a QFuture-returning function and feeding the future to a handler when it is ready.
void operator()(const ResultHandler &rh, QFutureWatcher< RetType > *watcher) const
typename std::result_of< E0(Args...)>::type FutureType_t
The result of calling Executor with Args.