Albert
Loading...
Searching...
No Matches
backgroundexecutor.h
1// SPDX-FileCopyrightText: 2025 Manuel Schneider
2// SPDX-License-Identifier: MIT
3
4#pragma once
5#include <QFutureWatcher>
6#include <QtConcurrentRun>
7#include <atomic>
8#include <functional>
9
10namespace albert
11{
12
20template<typename T>
22{
23 std::unique_ptr<QFutureWatcher<T>> future_watcher_;
24 bool rerun_ = false;
25 std::atomic_bool stop_ = false;
26
27public:
28
34 std::function<T(const bool &abort)> parallel;
35
42 std::function<void()> finish;
43
44
46 BackgroundExecutor() = default;
47
55 {
56 stop_ = true;
57 rerun_ = false;
58
59 // Qt 6.4 QFutureWatcher is broken.
60 // isFinished returns wrong values and waitForFinished blocks forever on finished futures.
61 // TODO(26.04): Remove workaround when dropping Qt < 6.5 support.
62 if (future_watcher_
63#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
64 && !future_watcher_->isFinished())
65#else
66 && future_watcher_->isRunning())
67#endif
68 future_watcher_->waitForFinished();
69 }
70
77 void run()
78 {
79 if (isRunning())
80 {
81 stop_ = true;
82 rerun_ = true;
83 }
84 else
85 {
86 stop_ = false;
87 rerun_ = false;
88
89 future_watcher_ = std::make_unique<QFutureWatcher<T>>();
90
91 QObject::connect(future_watcher_.get(), &QFutureWatcher<T>::finished,
92 future_watcher_.get(), [this]
93 {
94 if (rerun_)
95 {
96 future_watcher_.reset();
97 run(); // discard results and rerun
98 }
99 else
100 {
101 try {
102 finish(); // may throw
103 } catch (...) {}
104 future_watcher_.reset();
105 }
106 });
107
108 future_watcher_->setFuture(QtConcurrent::run([this]{ return parallel(stop_); }));
109
110 }
111 }
112
114 inline void stop() { stop_ = true; }
115
117 inline bool isRunning() const { return future_watcher_.get(); }
118
120 inline void waitForFinished()
121 {
122 if (future_watcher_)
123 future_watcher_->waitForFinished();
124 }
125
131 inline T takeResult() { return future_watcher_->future().takeResult(); }
132
133};
134
135}
Convenience class for recurring indexing tasks.
Definition backgroundexecutor.h:22
bool isRunning() const
Returns true if the asynchronous computation is currently running; otherwise returns false.
Definition backgroundexecutor.h:117
void waitForFinished()
Blocks until the current task finished.
Definition backgroundexecutor.h:120
~BackgroundExecutor()
Destructs the background executor.
Definition backgroundexecutor.h:54
std::function< T(const bool &abort)> parallel
The task to be executed in a thread.
Definition backgroundexecutor.h:34
void stop()
Stops the current execution.
Definition backgroundexecutor.h:114
std::function< void()> finish
The finish callback.
Definition backgroundexecutor.h:42
void run()
Run or schedule a rerun of the task.
Definition backgroundexecutor.h:77
T takeResult()
Takes the result from the future.
Definition backgroundexecutor.h:131
BackgroundExecutor()=default
Constructs the background executor.
The Albert namespace.
Definition app.h:55