Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
tasktree.h
Go to the documentation of this file.
1// Copyright (C) 2024 Jarek Kobus
2// Copyright (C) 2024 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef TASKING_TASKTREE_H
6#define TASKING_TASKTREE_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "tasking_global.h"
20
21#include <QtCore/QList>
22#include <QtCore/QObject>
23
24#include <memory>
25
27template <class T>
28class QFuture;
29
30namespace Tasking {
31
33
34// WorkflowPolicy:
35// 1. When all children finished with success -> report success, otherwise:
36// a) Report error on first error and stop executing other children (including their subtree).
37// b) On first error - continue executing all children and report error afterwards.
38// 2. When all children finished with error -> report error, otherwise:
39// a) Report success on first success and stop executing other children (including their subtree).
40// b) On first success - continue executing all children and report success afterwards.
41// 3. Stops on first finished child. In sequential mode it will never run other children then the first one.
42// Useful only in parallel mode.
43// 4. Always run all children, let them finish, ignore their results and report success afterwards.
44// 5. Always run all children, let them finish, ignore their results and report error afterwards.
45
47{
48 StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success).
49 ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children.
50 StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error).
51 ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children.
52 StopOnSuccessOrError, // 3 - Stops on first finished child and report its result.
53 FinishAllAndSuccess, // 4 - Reports success after all children finished.
54 FinishAllAndError // 5 - Reports error after all children finished.
55};
57
58enum class SetupResult
59{
63};
65
66enum class DoneResult
67{
68 Success,
69 Error
70};
72
73enum class DoneWith
74{
75 Success,
76 Error,
77 Cancel
78};
80
81enum class CallDoneIf
82{
84 Success,
85 Error
86};
88
90
91class LoopData;
92class StorageData;
93class TaskTreePrivate;
94
96{
98
101
102private:
103 template <typename Task, typename Deleter> friend class TaskAdapter;
104 friend class TaskTreePrivate;
105 TaskInterface() = default;
106#ifdef Q_QDOC
107protected:
108#endif
109 virtual void start() = 0;
110};
111
113{
114public:
115 using Condition = std::function<bool(int)>; // Takes iteration, called prior to each iteration.
116 using ValueGetter = std::function<const void *(int)>; // Takes iteration, returns ptr to ref.
117
118 int iteration() const;
119
120protected:
121 Loop(); // LoopForever
122 Loop(int count, const ValueGetter &valueGetter = {}); // LoopRepeat, LoopList
123 Loop(const Condition &condition); // LoopUntil
124
125 const void *valuePtr() const;
126
127private:
129 friend class TaskTreePrivate;
130 std::shared_ptr<LoopData> m_loopData;
131};
132
133class TASKING_EXPORT LoopForever final : public Loop
134{
135public:
137};
138
139class TASKING_EXPORT LoopRepeat final : public Loop
140{
141public:
143};
144
145class TASKING_EXPORT LoopUntil final : public Loop
146{
147public:
149};
150
151template <typename T>
152class LoopList final : public Loop
153{
154public:
155 LoopList(const QList<T> &list) : Loop(list.size(), [list](int i) { return &list.at(i); }) {}
156 const T *operator->() const { return static_cast<const T *>(valuePtr()); }
157 const T &operator*() const { return *static_cast<const T *>(valuePtr()); }
158};
159
161{
162private:
163 using StorageConstructor = std::function<void *(void)>;
164 using StorageDestructor = std::function<void(void *)>;
165 using StorageHandler = std::function<void(void *)>;
166
167 StorageBase(const StorageConstructor &ctor, const StorageDestructor &dtor);
168
169 void *activeStorageVoid() const;
170
171 friend bool operator==(const StorageBase &first, const StorageBase &second)
172 { return first.m_storageData == second.m_storageData; }
173
174 friend bool operator!=(const StorageBase &first, const StorageBase &second)
175 { return first.m_storageData != second.m_storageData; }
176
177 friend size_t qHash(const StorageBase &storage, uint seed = 0)
178 { return size_t(storage.m_storageData.get()) ^ seed; }
179
180 std::shared_ptr<StorageData> m_storageData;
181
182 template <typename StorageStruct> friend class Storage;
184 friend class StorageData;
185 friend class RuntimeContainer;
186 friend class TaskTree;
187 friend class TaskTreePrivate;
188};
189
190template <typename StorageStruct>
191class Storage final : public StorageBase
192{
193public:
194 Storage() : StorageBase(Storage::ctor(), Storage::dtor()) {}
195 StorageStruct &operator*() const noexcept { return *activeStorage(); }
196 StorageStruct *operator->() const noexcept { return activeStorage(); }
197 StorageStruct *activeStorage() const {
198 return static_cast<StorageStruct *>(activeStorageVoid());
199 }
200
201private:
202 static StorageConstructor ctor() { return [] { return new StorageStruct(); }; }
203 static StorageDestructor dtor() {
204 return [](void *storage) { delete static_cast<StorageStruct *>(storage); };
205 }
206};
207
209{
210public:
211 // Called when group entered, after group's storages are created
212 using GroupSetupHandler = std::function<SetupResult()>;
213 // Called when group done, before group's storages are deleted
214 using GroupDoneHandler = std::function<DoneResult(DoneWith)>;
215
216 template <typename StorageStruct>
217 GroupItem(const Storage<StorageStruct> &storage)
218 : m_type(Type::Storage)
219 , m_storageList{storage} {}
220
221 GroupItem(const Loop &loop) : GroupItem(GroupData{{}, {}, {}, loop}) {}
222
223 // TODO: Add tests.
224 GroupItem(const QList<GroupItem> &children) : m_type(Type::List) { addChildren(children); }
225 GroupItem(std::initializer_list<GroupItem> children) : m_type(Type::List) { addChildren(children); }
226
227protected:
228 // Internal, provided by CustomTask
229 using InterfaceCreateHandler = std::function<TaskInterface *(void)>;
230 // Called prior to task start, just after createHandler
232 // Called on task done, just before deleteLater
233 using InterfaceDoneHandler = std::function<DoneResult(const TaskInterface &, DoneWith)>;
234
235 struct TaskHandler {
237 InterfaceSetupHandler m_setupHandler = {};
238 InterfaceDoneHandler m_doneHandler = {};
239 CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError;
240 };
241
244 GroupDoneHandler m_doneHandler = {};
245 CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError;
246 };
247
248 struct GroupData {
249 GroupHandler m_groupHandler = {};
250 std::optional<int> m_parallelLimit = {};
251 std::optional<WorkflowPolicy> m_workflowPolicy = {};
252 std::optional<Loop> m_loop = {};
253 };
254
255 enum class Type {
256 List,
257 Group,
258 GroupData,
259 Storage,
261 };
262
263 GroupItem() = default;
264 GroupItem(Type type) : m_type(type) { }
266 : m_type(Type::GroupData)
267 , m_groupData(data) {}
268 GroupItem(const TaskHandler &handler)
269 : m_type(Type::TaskHandler)
270 , m_taskHandler(handler) {}
271 void addChildren(const QList<GroupItem> &children);
272
273 static GroupItem groupHandler(const GroupHandler &handler) { return GroupItem({handler}); }
274 static GroupItem parallelLimit(int limit) { return GroupItem({{}, limit}); }
276
277 // Checks if Function may be invoked with Args and if Function's return type is Result.
278 template <typename Result, typename Function, typename ...Args,
279 typename DecayedFunction = std::decay_t<Function>>
280 static constexpr bool isInvocable()
281 {
282 // Note, that std::is_invocable_r_v doesn't check Result type properly.
283 if constexpr (std::is_invocable_r_v<Result, DecayedFunction, Args...>)
284 return std::is_same_v<Result, std::invoke_result_t<DecayedFunction, Args...>>;
285 return false;
286 }
287
288private:
289 friend class ContainerNode;
290 friend class TaskNode;
291 friend class TaskTreePrivate;
292 Type m_type = Type::Group;
293 QList<GroupItem> m_children;
294 GroupData m_groupData;
295 QList<StorageBase> m_storageList;
296 TaskHandler m_taskHandler;
297};
298
300{
301public:
302 ExecutableItem withTimeout(std::chrono::milliseconds timeout,
303 const std::function<void()> &handler = {}) const;
304 ExecutableItem withLog(const QString &logName) const;
305 template <typename SenderSignalPairGetter>
306 ExecutableItem withCancel(SenderSignalPairGetter &&getter) const
307 {
308 const auto connectWrapper = [getter](QObject *guard, const std::function<void()> &trigger) {
309 const auto senderSignalPair = getter();
310 QObject::connect(senderSignalPair.first, senderSignalPair.second, guard, [trigger] {
311 trigger();
313 };
314 return withCancelImpl(connectWrapper);
315 }
316
317protected:
318 ExecutableItem() = default;
319 ExecutableItem(const TaskHandler &handler) : GroupItem(handler) {}
320
321private:
322 ExecutableItem withCancelImpl(
323 const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const;
324};
325
327{
328public:
329 Group(const QList<GroupItem> &children) { addChildren(children); }
330 Group(std::initializer_list<GroupItem> children) { addChildren(children); }
331
332 // GroupData related:
333 template <typename Handler>
334 static GroupItem onGroupSetup(Handler &&handler) {
335 return groupHandler({wrapGroupSetup(std::forward<Handler>(handler))});
336 }
337 template <typename Handler>
338 static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) {
339 return groupHandler({{}, wrapGroupDone(std::forward<Handler>(handler)), callDoneIf});
340 }
341 using GroupItem::parallelLimit; // Default: 1 (sequential). 0 means unlimited (parallel).
342 using GroupItem::workflowPolicy; // Default: WorkflowPolicy::StopOnError.
343
344private:
345 template <typename Handler>
346 static GroupSetupHandler wrapGroupSetup(Handler &&handler)
347 {
348 // R, V stands for: Setup[R]esult, [V]oid
349 static constexpr bool isR = isInvocable<SetupResult, Handler>();
350 static constexpr bool isV = isInvocable<void, Handler>();
351 static_assert(isR || isV,
352 "Group setup handler needs to take no arguments and has to return void or SetupResult. "
353 "The passed handler doesn't fulfill these requirements.");
354 return [handler] {
355 if constexpr (isR)
356 return std::invoke(handler);
357 std::invoke(handler);
358 return SetupResult::Continue;
359 };
360 }
361 template <typename Handler>
362 static GroupDoneHandler wrapGroupDone(Handler &&handler)
363 {
364 // R, V, D stands for: Done[R]esult, [V]oid, [D]oneWith
365 static constexpr bool isRD = isInvocable<DoneResult, Handler, DoneWith>();
366 static constexpr bool isR = isInvocable<DoneResult, Handler>();
367 static constexpr bool isVD = isInvocable<void, Handler, DoneWith>();
368 static constexpr bool isV = isInvocable<void, Handler>();
369 static_assert(isRD || isR || isVD || isV,
370 "Group done handler needs to take (DoneWith) or (void) as an argument and has to "
371 "return void or DoneResult. The passed handler doesn't fulfill these requirements.");
372 return [handler](DoneWith result) {
373 if constexpr (isRD)
374 return std::invoke(handler, result);
375 if constexpr (isR)
376 return std::invoke(handler);
377 if constexpr (isVD)
378 std::invoke(handler, result);
379 else if constexpr (isV)
380 std::invoke(handler);
381 return result == DoneWith::Success ? DoneResult::Success : DoneResult::Error;
382 };
383 }
384};
385
386template <typename Handler>
387static GroupItem onGroupSetup(Handler &&handler)
388{
389 return Group::onGroupSetup(std::forward<Handler>(handler));
390}
391
392template <typename Handler>
393static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
394{
395 return Group::onGroupDone(std::forward<Handler>(handler), callDoneIf);
396}
397
398TASKING_EXPORT GroupItem parallelLimit(int limit);
399TASKING_EXPORT GroupItem workflowPolicy(WorkflowPolicy policy);
400
401TASKING_EXPORT extern const GroupItem nullItem;
402
403TASKING_EXPORT extern const GroupItem sequential;
404TASKING_EXPORT extern const GroupItem parallel;
405TASKING_EXPORT extern const GroupItem parallelIdealThreadCountLimit;
406
407TASKING_EXPORT extern const GroupItem stopOnError;
408TASKING_EXPORT extern const GroupItem continueOnError;
409TASKING_EXPORT extern const GroupItem stopOnSuccess;
410TASKING_EXPORT extern const GroupItem continueOnSuccess;
411TASKING_EXPORT extern const GroupItem stopOnSuccessOrError;
412TASKING_EXPORT extern const GroupItem finishAllAndSuccess;
413TASKING_EXPORT extern const GroupItem finishAllAndError;
414
415class TASKING_EXPORT Forever final : public Group
416{
417public:
418 Forever(const QList<GroupItem> &children) : Group({LoopForever(), children}) {}
419 Forever(std::initializer_list<GroupItem> children) : Group({LoopForever(), children}) {}
420};
421
422// Synchronous invocation. Similarly to Group - isn't counted as a task inside taskCount()
424{
425public:
426 template <typename Handler>
427 Sync(Handler &&handler) {
428 addChildren({ onGroupSetup(wrapHandler(std::forward<Handler>(handler))) });
429 }
430
431private:
432 template <typename Handler>
433 static GroupSetupHandler wrapHandler(Handler &&handler) {
434 // R, V stands for: Done[R]esult, [V]oid
435 static constexpr bool isR = isInvocable<DoneResult, Handler>();
436 static constexpr bool isV = isInvocable<void, Handler>();
437 static_assert(isR || isV,
438 "Sync handler needs to take no arguments and has to return void or DoneResult. "
439 "The passed handler doesn't fulfill these requirements.");
440 return [handler] {
441 if constexpr (isR) {
442 return std::invoke(handler) == DoneResult::Success ? SetupResult::StopWithSuccess
443 : SetupResult::StopWithError;
444 }
445 std::invoke(handler);
446 return SetupResult::StopWithSuccess;
447 };
448 }
449};
450
451template <typename Task, typename Deleter = std::default_delete<Task>>
453{
454protected:
455 TaskAdapter() : m_task(new Task) {}
456 Task *task() { return m_task.get(); }
457 const Task *task() const { return m_task.get(); }
458
459private:
460 using TaskType = Task;
461 using DeleterType = Deleter;
462 template <typename Adapter> friend class CustomTask;
463 std::unique_ptr<Task, Deleter> m_task;
464};
465
466template <typename Adapter>
467class CustomTask final : public ExecutableItem
468{
469public:
470 using Task = typename Adapter::TaskType;
471 using Deleter = typename Adapter::DeleterType;
472 static_assert(std::is_base_of_v<TaskAdapter<Task, Deleter>, Adapter>,
473 "The Adapter type for the CustomTask<Adapter> needs to be derived from "
474 "TaskAdapter<Task>.");
475 using TaskSetupHandler = std::function<SetupResult(Task &)>;
476 using TaskDoneHandler = std::function<DoneResult(const Task &, DoneWith)>;
477
478 template <typename SetupHandler = TaskSetupHandler, typename DoneHandler = TaskDoneHandler>
479 CustomTask(SetupHandler &&setup = TaskSetupHandler(), DoneHandler &&done = TaskDoneHandler(),
480 CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
481 : ExecutableItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)),
482 wrapDone(std::forward<DoneHandler>(done)), callDoneIf})
483 {}
484
485private:
486 static Adapter *createAdapter() { return new Adapter; }
487
488 template <typename Handler>
489 static InterfaceSetupHandler wrapSetup(Handler &&handler) {
490 if constexpr (std::is_same_v<Handler, TaskSetupHandler>)
491 return {}; // When user passed {} for the setup handler.
492 // R, V stands for: Setup[R]esult, [V]oid
493 static constexpr bool isR = isInvocable<SetupResult, Handler, Task &>();
494 static constexpr bool isV = isInvocable<void, Handler, Task &>();
495 static_assert(isR || isV,
496 "Task setup handler needs to take (Task &) as an argument and has to return void or "
497 "SetupResult. The passed handler doesn't fulfill these requirements.");
498 return [handler](TaskInterface &taskInterface) {
499 Adapter &adapter = static_cast<Adapter &>(taskInterface);
500 if constexpr (isR)
501 return std::invoke(handler, *adapter.task());
502 std::invoke(handler, *adapter.task());
503 return SetupResult::Continue;
504 };
505 }
506
507 template <typename Handler>
508 static InterfaceDoneHandler wrapDone(Handler &&handler) {
509 if constexpr (std::is_same_v<Handler, TaskDoneHandler>)
510 return {}; // When user passed {} for the done handler.
511 // R, V, T, D stands for: Done[R]esult, [V]oid, [T]ask, [D]oneWith
512 static constexpr bool isRTD = isInvocable<DoneResult, Handler, const Task &, DoneWith>();
513 static constexpr bool isRT = isInvocable<DoneResult, Handler, const Task &>();
514 static constexpr bool isRD = isInvocable<DoneResult, Handler, DoneWith>();
515 static constexpr bool isR = isInvocable<DoneResult, Handler>();
516 static constexpr bool isVTD = isInvocable<void, Handler, const Task &, DoneWith>();
517 static constexpr bool isVT = isInvocable<void, Handler, const Task &>();
518 static constexpr bool isVD = isInvocable<void, Handler, DoneWith>();
519 static constexpr bool isV = isInvocable<void, Handler>();
520 static_assert(isRTD || isRT || isRD || isR || isVTD || isVT || isVD || isV,
521 "Task done handler needs to take (const Task &, DoneWith), (const Task &), "
522 "(DoneWith) or (void) as arguments and has to return void or DoneResult. "
523 "The passed handler doesn't fulfill these requirements.");
524 return [handler](const TaskInterface &taskInterface, DoneWith result) {
525 const Adapter &adapter = static_cast<const Adapter &>(taskInterface);
526 if constexpr (isRTD)
527 return std::invoke(handler, *adapter.task(), result);
528 if constexpr (isRT)
529 return std::invoke(handler, *adapter.task());
530 if constexpr (isRD)
531 return std::invoke(handler, result);
532 if constexpr (isR)
533 return std::invoke(handler);
534 if constexpr (isVTD)
535 std::invoke(handler, *adapter.task(), result);
536 else if constexpr (isVT)
537 std::invoke(handler, *adapter.task());
538 else if constexpr (isVD)
539 std::invoke(handler, result);
540 else if constexpr (isV)
541 std::invoke(handler);
542 return result == DoneWith::Success ? DoneResult::Success : DoneResult::Error;
543 };
544 }
545};
546
547class TASKING_EXPORT TaskTree final : public QObject
548{
550
551public:
552 TaskTree();
553 TaskTree(const Group &recipe);
554 ~TaskTree();
555
556 void setRecipe(const Group &recipe);
557
558 void start();
559 void cancel();
560 bool isRunning() const;
561
562 // Helper methods. They execute a local event loop with ExcludeUserInputEvents.
563 // The passed future is used for listening to the cancel event.
564 // Don't use it in main thread. To be used in non-main threads or in auto tests.
565 DoneWith runBlocking();
566 DoneWith runBlocking(const QFuture<void> &future);
567 static DoneWith runBlocking(const Group &recipe,
568 std::chrono::milliseconds timeout = std::chrono::milliseconds::max());
569 static DoneWith runBlocking(const Group &recipe, const QFuture<void> &future,
570 std::chrono::milliseconds timeout = std::chrono::milliseconds::max());
571
572 int asyncCount() const;
573 int taskCount() const;
574 int progressMaximum() const { return taskCount(); }
575 int progressValue() const; // all finished / skipped / stopped tasks, groups itself excluded
576
577 template <typename StorageStruct, typename Handler>
578 void onStorageSetup(const Storage<StorageStruct> &storage, Handler &&handler) {
579 static_assert(std::is_invocable_v<std::decay_t<Handler>, StorageStruct &>,
580 "Storage setup handler needs to take (Storage &) as an argument. "
581 "The passed handler doesn't fulfill this requirement.");
582 setupStorageHandler(storage,
583 wrapHandler<StorageStruct>(std::forward<Handler>(handler)), {});
584 }
585 template <typename StorageStruct, typename Handler>
586 void onStorageDone(const Storage<StorageStruct> &storage, Handler &&handler) {
587 static_assert(std::is_invocable_v<std::decay_t<Handler>, const StorageStruct &>,
588 "Storage done handler needs to take (const Storage &) as an argument. "
589 "The passed handler doesn't fulfill this requirement.");
590 setupStorageHandler(storage, {},
591 wrapHandler<const StorageStruct>(std::forward<Handler>(handler)));
592 }
593
595 void started();
598 void progressValueChanged(int value); // updated whenever task finished / skipped / stopped
599
600private:
601 void setupStorageHandler(const StorageBase &storage,
602 StorageBase::StorageHandler setupHandler,
603 StorageBase::StorageHandler doneHandler);
604 template <typename StorageStruct, typename Handler>
605 StorageBase::StorageHandler wrapHandler(Handler &&handler) {
606 return [handler](void *voidStruct) {
607 auto *storageStruct = static_cast<StorageStruct *>(voidStruct);
608 std::invoke(handler, *storageStruct);
609 };
610 }
611
612 TaskTreePrivate *d;
613};
614
616{
617public:
619
620private:
621 void start() final;
622};
623
624class TASKING_EXPORT TimeoutTaskAdapter : public TaskAdapter<std::chrono::milliseconds>
625{
626public:
629
630private:
631 void start() final;
632 std::optional<int> m_timerId;
633};
634
635using TaskTreeTask = CustomTask<TaskTreeTaskAdapter>;
636using TimeoutTask = CustomTask<TimeoutTaskAdapter>;
637
638} // namespace Tasking
639
641
642#endif // TASKING_TASKTREE_H
const_reference at(qsizetype i) const noexcept
Definition qlist.h:447
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:468
typename Adapter::TaskType Task
Definition tasktree.h:470
typename Adapter::DeleterType Deleter
Definition tasktree.h:471
std::function< DoneResult(const Task &, DoneWith)> TaskDoneHandler
Definition tasktree.h:476
std::function< SetupResult(Task &)> TaskSetupHandler
Definition tasktree.h:475
CustomTask(SetupHandler &&setup=TaskSetupHandler(), DoneHandler &&done=TaskDoneHandler(), CallDoneIf callDoneIf=CallDoneIf::SuccessOrError)
\typealias CustomTask::Task
Definition tasktree.h:479
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:300
ExecutableItem(const TaskHandler &handler)
Definition tasktree.h:319
ExecutableItem withCancel(SenderSignalPairGetter &&getter) const
Definition tasktree.h:306
Forever(std::initializer_list< GroupItem > children)
Definition tasktree.h:419
Forever(const QList< GroupItem > &children)
Definition tasktree.h:418
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:209
std::function< SetupResult()> GroupSetupHandler
Definition tasktree.h:212
std::function< DoneResult(const TaskInterface &, DoneWith)> InterfaceDoneHandler
Definition tasktree.h:233
std::function< SetupResult(TaskInterface &)> InterfaceSetupHandler
Definition tasktree.h:231
GroupItem(const Loop &loop)
Definition tasktree.h:221
GroupItem(std::initializer_list< GroupItem > children)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tasktree.h:225
GroupItem(const TaskHandler &handler)
Definition tasktree.h:268
GroupItem(const GroupData &data)
Definition tasktree.h:265
GroupItem(Type type)
Definition tasktree.h:264
static GroupItem parallelLimit(int limit)
Definition tasktree.h:274
GroupItem(const QList< GroupItem > &children)
Constructs a GroupItem element with a given list of items.
Definition tasktree.h:224
static GroupItem workflowPolicy(WorkflowPolicy policy)
Definition tasktree.h:275
std::function< DoneResult(DoneWith)> GroupDoneHandler
Definition tasktree.h:214
static GroupItem groupHandler(const GroupHandler &handler)
Definition tasktree.h:273
std::function< TaskInterface *(void)> InterfaceCreateHandler
Definition tasktree.h:229
GroupItem(const Storage< StorageStruct > &storage)
Constructs a GroupItem element holding the storage object.
Definition tasktree.h:217
static constexpr bool isInvocable()
Definition tasktree.h:280
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:327
static GroupItem onGroupSetup(Handler &&handler)
Definition tasktree.h:334
static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf=CallDoneIf::SuccessOrError)
Definition tasktree.h:338
Group(std::initializer_list< GroupItem > children)
Constructs a group from std::initializer_list given by children.
Definition tasktree.h:330
Group(const QList< GroupItem > &children)
Constructs a group with a given list of children.
Definition tasktree.h:329
const T & operator*() const
Definition tasktree.h:157
LoopList(const QList< T > &list)
Definition tasktree.h:155
const T * operator->() const
Definition tasktree.h:156
LoopRepeat(int count)
Definition tasktree.h:142
LoopUntil(const Condition &condition)
Definition tasktree.h:148
std::function< const void *(int)> ValueGetter
Definition tasktree.h:116
std::function< bool(int)> Condition
Definition tasktree.h:115
const void * valuePtr() const
friend bool operator==(const StorageBase &first, const StorageBase &second)
Definition tasktree.h:171
friend size_t qHash(const StorageBase &storage, uint seed=0)
Definition tasktree.h:177
friend bool operator!=(const StorageBase &first, const StorageBase &second)
Definition tasktree.h:174
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:192
StorageStruct & operator*() const noexcept
Returns a reference to the active StorageStruct object, created by the running task tree.
Definition tasktree.h:195
StorageStruct * operator->() const noexcept
Returns a pointer to the active StorageStruct object, created by the running task tree.
Definition tasktree.h:196
Storage()
Creates a storage for the given StorageStruct type.
Definition tasktree.h:194
StorageStruct * activeStorage() const
Returns a pointer to the active StorageStruct object, created by the running task tree.
Definition tasktree.h:197
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:424
Sync(Handler &&handler)
Constructs an element that executes a passed handler synchronously.
Definition tasktree.h:427
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:453
const Task * task() const
Definition tasktree.h:457
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:96
void done(DoneResult result)
Emit this signal from the TaskAdapter<Task>'s subclass, when the Task is finished.
virtual void start()=0
This method is called by the running TaskTree for starting the Task instance.
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:548
void done(DoneWith result)
This signal is emitted when the task tree finished, passing the final result of the execution.
int progressMaximum() const
Returns the maximum progressValue().
Definition tasktree.h:574
void asyncCountChanged(int count)
This signal is emitted when the running task tree is about to return control to the caller's event lo...
static DoneWith runBlocking(const Group &recipe, const QFuture< void > &future, std::chrono::milliseconds timeout=std::chrono::milliseconds::max())
void started()
This signal is emitted when the task tree is started.
void onStorageSetup(const Storage< StorageStruct > &storage, Handler &&handler)
Installs a storage setup handler for the storage to pass the initial data dynamically to the running ...
Definition tasktree.h:578
static DoneWith runBlocking(const Group &recipe, std::chrono::milliseconds timeout=std::chrono::milliseconds::max())
void progressValueChanged(int value)
This signal is emitted when the running task tree finished, canceled, or skipped some tasks.
void onStorageDone(const Storage< StorageStruct > &storage, Handler &&handler)
Installs a storage done handler for the storage to retrieve the final data dynamically from the runni...
Definition tasktree.h:586
Combined button and popup list for selecting options.
ConnectionType
@ SingleShotConnection
@ QueuedConnection
\inmodule TaskingSolution
Definition barrier.cpp:9
SetupResult
Definition tasktree.h:59
WorkflowPolicy
Definition tasktree.h:47
static GroupItem onGroupSetup(Handler &&handler)
\typealias GroupItem::GroupSetupHandler
Definition tasktree.h:387
CustomTask< TimeoutTaskAdapter > TimeoutTask
Definition tasktree.h:636
CustomTask< TaskTreeTaskAdapter > TaskTreeTask
Definition tasktree.h:635
DoneResult toDoneResult(bool success)
static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf=CallDoneIf::SuccessOrError)
Constructs a group's element holding the group done handler.
Definition tasktree.h:393
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum condition
GLenum GLenum GLsizei count
GLbitfield GLuint64 timeout
[4]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLuint start
GLint first
GLint limit
GLuint64EXT * result
[6]
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
static bool isRunning()
Definition main.cpp:452
#define Q_OBJECT
#define Q_ENUM_NS(x)
#define Q_SIGNALS
#define Q_NAMESPACE
unsigned int uint
Definition qtypes.h:34
QList< int > list
[14]
QFuture< void > future
[5]
future cancel()
QStorageInfo storage
[1]
QSizePolicy policy
GroupSetupHandler m_setupHandler
Definition tasktree.h:243
InterfaceCreateHandler m_createHandler
Definition tasktree.h:236
Definition moc.h:23
#define TASKING_EXPORT