File indexing completed on 2024-09-22 04:41:26

0001 /*
0002     SPDX-FileCopyrightText: 2015 Daniel Vrátil <dvratil@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QObject>
0010 #include <QThread>
0011 
0012 #include <atomic>
0013 #include <type_traits>
0014 
0015 namespace Akonadi
0016 {
0017 namespace Server
0018 {
0019 
0020 class AkThread : public QObject
0021 {
0022     Q_OBJECT
0023 public:
0024     enum StartMode {
0025         AutoStart,
0026         ManualStart,
0027         NoThread // for unit-tests
0028     };
0029 
0030     template<typename T, typename... Args>
0031     static std::enable_if_t<std::is_base_of_v<AkThread, T>, std::unique_ptr<T>> create(Args &&...args) noexcept
0032     {
0033         // Workaround T having a protected constructor
0034         struct TConstructor : T {
0035             explicit TConstructor(Args &&...args)
0036                 : T(std::forward<Args>(args)...)
0037             {
0038             }
0039         };
0040         std::unique_ptr<T> thread = std::make_unique<TConstructor>(std::forward<Args>(args)...);
0041         if (thread->m_startMode == AkThread::AutoStart) {
0042             thread->startThread();
0043         }
0044         return thread;
0045     }
0046 
0047     ~AkThread() override;
0048 
0049     bool isInitialized() const
0050     {
0051         return m_initialized;
0052     }
0053 
0054     void waitForInitialized();
0055 
0056 Q_SIGNALS:
0057     void initialized();
0058 
0059 protected:
0060     explicit AkThread(const QString &objectName, QThread::Priority priority = QThread::InheritPriority, QObject *parent = nullptr);
0061     explicit AkThread(const QString &objectName, StartMode startMode, QThread::Priority priority = QThread::InheritPriority, QObject *parent = nullptr);
0062 
0063     void quitThread();
0064     void startThread();
0065 
0066 protected Q_SLOTS:
0067     virtual void init();
0068     virtual void quit();
0069 
0070 private:
0071     StartMode m_startMode = AutoStart;
0072     bool m_quitCalled = false;
0073     std::atomic_bool m_initialized = false;
0074 };
0075 
0076 } // namespace Server
0077 } // namespace Akonadi