#ifndef FUTURE_SCHEDULER_H #define FUTURE_SCHEDULER_H #include #include #include #include #include #include #include #include class FutureScheduler : public QObject { Q_OBJECT public: FutureScheduler(QObject *parent); ~FutureScheduler(); void shutdownWaitForFinished() noexcept; QPair> run(std::function function) noexcept; QPair> run(std::function function, const QJSValue &callback); private: bool add() noexcept; void done() noexcept; template QFutureWatcher *newWatcher() { QFutureWatcher *watcher = new QFutureWatcher(); QThread *schedulerThread = this->thread(); if (watcher->thread() != schedulerThread) { watcher->moveToThread(schedulerThread); } watcher->setParent(this); return watcher; } template QPair> execute(std::function(QFutureWatcher *)> makeFuture) noexcept { if (add()) { try { auto *watcher = newWatcher(); watcher->setFuture(makeFuture(watcher)); connect(watcher, &QFutureWatcher::finished, [this, watcher] { watcher->deleteLater(); }); return qMakePair(true, watcher->future()); } catch (const std::exception &exception) { qCritical() << "Failed to schedule async function: " << exception.what(); done(); } } return qMakePair(false, QFuture()); } QFutureWatcher schedule(std::function function); QFutureWatcher schedule(std::function function, const QJSValue &callback); private: size_t Alive; QWaitCondition Condition; QMutex Mutex; bool Stopping; }; #endif // FUTURE_SCHEDULER_H