aboutsummaryrefslogtreecommitdiffstats
path: root/tests/manual/tasking/demo/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/tasking/demo/main.cpp')
-rw-r--r--tests/manual/tasking/demo/main.cpp285
1 files changed, 285 insertions, 0 deletions
diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp
new file mode 100644
index 00000000000..c4b885efe2f
--- /dev/null
+++ b/tests/manual/tasking/demo/main.cpp
@@ -0,0 +1,285 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "taskwidget.h"
+
+#include <tasking/tasktree.h>
+
+#include <QApplication>
+#include <QBoxLayout>
+#include <QGroupBox>
+#include <QProgressBar>
+#include <QScrollArea>
+#include <QTimer>
+#include <QToolButton>
+
+using namespace Tasking;
+
+using namespace std::chrono;
+
+static QWidget *hr()
+{
+ auto frame = new QFrame;
+ frame->setFrameShape(QFrame::HLine);
+ frame->setFrameShadow(QFrame::Sunken);
+ return frame;
+}
+
+QWidget *taskGroup(QWidget *groupWidget, const QList<QWidget *> &widgets)
+{
+ QWidget *widget = new QWidget;
+ QBoxLayout *layout = new QHBoxLayout(widget);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(groupWidget);
+ QGroupBox *groupBox = new QGroupBox;
+ QBoxLayout *subLayout = new QVBoxLayout(groupBox);
+ for (int i = 0; i < widgets.size(); ++i) {
+ if (i > 0)
+ subLayout->addWidget(hr());
+ subLayout->addWidget(widgets.at(i));
+ }
+ layout->addWidget(groupBox);
+ return widget;
+}
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QWidget mainWidget;
+ mainWidget.setWindowTitle("Task Tree Demo");
+
+ // Non-task GUI
+
+ QToolButton *startButton = new QToolButton;
+ startButton->setText("Start");
+ QToolButton *stopButton = new QToolButton;
+ stopButton->setText("Stop");
+ QToolButton *resetButton = new QToolButton;
+ resetButton->setText("Reset");
+ QProgressBar *progressBar = new QProgressBar;
+ QScrollArea *scrollArea = new QScrollArea;
+ scrollArea->setWidgetResizable(true);
+ QWidget *scrollAreaWidget = new QWidget;
+
+ // Task GUI
+
+ QList<StateWidget *> allStateWidgets;
+
+ auto createGroupWidget = [&allStateWidgets] {
+ auto *widget = new GroupWidget();
+ allStateWidgets.append(widget);
+ return widget;
+ };
+ auto createTaskWidget = [&allStateWidgets] {
+ auto *widget = new TaskWidget();
+ allStateWidgets.append(widget);
+ return widget;
+ };
+
+ GroupWidget *rootGroup = createGroupWidget();
+
+ GroupWidget *groupTask_1 = createGroupWidget();
+ TaskWidget *task_1_1 = createTaskWidget();
+ TaskWidget *task_1_2 = createTaskWidget();
+ TaskWidget *task_1_3 = createTaskWidget();
+
+ TaskWidget *task_2 = createTaskWidget();
+ TaskWidget *task_3 = createTaskWidget();
+
+ GroupWidget *groupTask_4 = createGroupWidget();
+ TaskWidget *task_4_1 = createTaskWidget();
+ TaskWidget *task_4_2 = createTaskWidget();
+ GroupWidget *groupTask_4_3 = createGroupWidget();
+ TaskWidget *task_4_3_1 = createTaskWidget();
+ TaskWidget *task_4_3_2 = createTaskWidget();
+ TaskWidget *task_4_3_3 = createTaskWidget();
+ TaskWidget *task_4_3_4 = createTaskWidget();
+ TaskWidget *task_4_4 = createTaskWidget();
+ TaskWidget *task_4_5 = createTaskWidget();
+
+ TaskWidget *task_5 = createTaskWidget();
+
+ // Task initial configuration
+
+ task_1_2->setBusyTime(2);
+ task_1_2->setSuccess(false);
+ task_1_3->setBusyTime(3);
+ task_4_3_1->setBusyTime(4);
+ task_4_3_2->setBusyTime(2);
+ task_4_3_3->setBusyTime(1);
+ task_4_3_4->setBusyTime(3);
+ task_4_3_4->setSuccess(false);
+ task_4_4->setBusyTime(6);
+ task_4_4->setBusyTime(3);
+
+ groupTask_1->setWorkflowPolicy(WorkflowPolicy::ContinueOnDone);
+ groupTask_4->setWorkflowPolicy(WorkflowPolicy::FinishAllAndDone);
+ groupTask_4_3->setExecuteMode(ExecuteMode::Parallel);
+ groupTask_4_3->setWorkflowPolicy(WorkflowPolicy::StopOnError);
+
+ // Task layout
+
+ {
+ QWidget *taskTree = taskGroup(rootGroup, {
+ taskGroup(groupTask_1, {
+ task_1_1,
+ task_1_2,
+ task_1_3
+ }),
+ task_2,
+ task_3,
+ taskGroup(groupTask_4, {
+ task_4_1,
+ task_4_2,
+ taskGroup(groupTask_4_3, {
+ task_4_3_1,
+ task_4_3_2,
+ task_4_3_3,
+ task_4_3_4,
+ }),
+ task_4_4,
+ task_4_5
+ }),
+ task_5
+ });
+ QBoxLayout *scrollLayout = new QVBoxLayout(scrollAreaWidget);
+ scrollLayout->addWidget(taskTree);
+ scrollLayout->addStretch();
+ scrollArea->setWidget(scrollAreaWidget);
+
+ QBoxLayout *mainLayout = new QVBoxLayout(&mainWidget);
+ QBoxLayout *subLayout = new QHBoxLayout;
+ subLayout->addWidget(startButton);
+ subLayout->addWidget(stopButton);
+ subLayout->addWidget(resetButton);
+ subLayout->addWidget(progressBar);
+ mainLayout->addLayout(subLayout);
+ mainLayout->addWidget(hr());
+ mainLayout->addWidget(scrollArea);
+ }
+
+ // Task tree (takes initial configuation from GUI)
+
+ std::unique_ptr<TaskTree> taskTree;
+
+ const auto createTask = [](TaskWidget *widget) -> TaskItem {
+ const auto setupTask = [](TaskWidget *widget) {
+ return [widget](milliseconds &taskObject) {
+ taskObject = milliseconds{widget->busyTime() * 1000};
+ widget->setState(State::Running);
+ };
+ };
+ if (widget->isSuccess()) {
+ return TimeoutTask(setupTask(widget),
+ [widget](const milliseconds &) { widget->setState(State::Done); },
+ [widget](const milliseconds &) { widget->setState(State::Error); });
+ }
+ const Group root {
+ finishAllAndError,
+ TimeoutTask(setupTask(widget)),
+ onGroupDone([widget] { widget->setState(State::Done); }),
+ onGroupError([widget] { widget->setState(State::Error); })
+ };
+ return root;
+ };
+
+ auto treeRoot = [&] {
+
+ const Group root {
+ rootGroup->executeMode(),
+ rootGroup->workflowPolicy(),
+ onGroupSetup([rootGroup] { rootGroup->setState(State::Running); }),
+ onGroupDone([rootGroup] { rootGroup->setState(State::Done); }),
+ onGroupError([rootGroup] { rootGroup->setState(State::Error); }),
+
+ Group {
+ groupTask_1->executeMode(),
+ groupTask_1->workflowPolicy(),
+ onGroupSetup([groupTask_1] { groupTask_1->setState(State::Running); }),
+ onGroupDone([groupTask_1] { groupTask_1->setState(State::Done); }),
+ onGroupError([groupTask_1] { groupTask_1->setState(State::Error); }),
+
+ createTask(task_1_1),
+ createTask(task_1_2),
+ createTask(task_1_3)
+ },
+ createTask(task_2),
+ createTask(task_3),
+ Group {
+ groupTask_4->executeMode(),
+ groupTask_4->workflowPolicy(),
+ onGroupSetup([groupTask_4] { groupTask_4->setState(State::Running); }),
+ onGroupDone([groupTask_4] { groupTask_4->setState(State::Done); }),
+ onGroupError([groupTask_4] { groupTask_4->setState(State::Error); }),
+
+ createTask(task_4_1),
+ createTask(task_4_2),
+ Group {
+ groupTask_4_3->executeMode(),
+ groupTask_4_3->workflowPolicy(),
+ onGroupSetup([groupTask_4_3] { groupTask_4_3->setState(State::Running); }),
+ onGroupDone([groupTask_4_3] { groupTask_4_3->setState(State::Done); }),
+ onGroupError([groupTask_4_3] { groupTask_4_3->setState(State::Error); }),
+
+ createTask(task_4_3_1),
+ createTask(task_4_3_2),
+ createTask(task_4_3_3),
+ createTask(task_4_3_4)
+ },
+ createTask(task_4_4),
+ createTask(task_4_5)
+ },
+ createTask(task_5)
+ };
+ return root;
+ };
+
+ // Non-task GUI handling
+
+ auto createTaskTree = [&] {
+ TaskTree *taskTree = new TaskTree(treeRoot());
+ progressBar->setMaximum(taskTree->progressMaximum());
+ QObject::connect(taskTree, &TaskTree::progressValueChanged,
+ progressBar, &QProgressBar::setValue);
+ return taskTree;
+ };
+
+ auto stopTaskTree = [&] {
+ if (taskTree)
+ taskTree->stop();
+ // TODO: unlock GUI controls?
+ };
+
+ auto resetTaskTree = [&] {
+ if (!taskTree)
+ return;
+
+ stopTaskTree();
+ taskTree.reset();
+ for (StateWidget *widget : allStateWidgets)
+ widget->setState(State::Initial);
+ progressBar->setValue(0);
+ };
+
+ auto startTaskTree = [&] {
+ resetTaskTree();
+ taskTree.reset(createTaskTree());
+ taskTree->start();
+ // TODO: lock GUI controls?
+ };
+
+ QObject::connect(startButton, &QAbstractButton::clicked, startTaskTree);
+ QObject::connect(stopButton, &QAbstractButton::clicked, stopTaskTree);
+ QObject::connect(resetButton, &QAbstractButton::clicked, resetTaskTree);
+
+ // Hack in order to show initial size minimal, but without scrollbars.
+ // Apparently setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow) doesn't work.
+ const int margin = 4;
+ scrollArea->setMinimumSize(scrollAreaWidget->minimumSizeHint().grownBy({0, 0, margin, margin}));
+ QTimer::singleShot(0, scrollArea, [&] { scrollArea->setMinimumSize({0, 0}); });
+
+ mainWidget.show();
+
+ return app.exec();
+}