File indexing completed on 2025-02-21 10:12:23
0001
0002
0003
0004 #ifndef QTESTEVENTLOOP_H
0005 #define QTESTEVENTLOOP_H
0006
0007 #include <QtTest/qttestglobal.h>
0008 #include <QtTest/qtestcase.h>
0009
0010 #include <QtCore/qcoreapplication.h>
0011 #include <QtCore/qeventloop.h>
0012 #include <QtCore/qobject.h>
0013 #include <QtCore/qpointer.h>
0014 #include <QtCore/qthread.h>
0015
0016 QT_BEGIN_NAMESPACE
0017
0018
0019 class Q_TESTLIB_EXPORT QTestEventLoop : public QObject
0020 {
0021 Q_OBJECT
0022
0023 public:
0024 QTestEventLoop(QObject *parent = nullptr)
0025 : QObject(parent), _timeout(false)
0026 {}
0027
0028 void enterLoopMSecs(int ms) { enterLoop(std::chrono::milliseconds{ms}); };
0029 void enterLoop(int secs) { enterLoop(std::chrono::seconds{secs}); }
0030 inline void enterLoop(std::chrono::milliseconds msecs);
0031
0032 inline void changeInterval(int secs)
0033 { killTimer(timerId); timerId = startTimer(secs * 1000); }
0034
0035 inline bool timeout() const
0036 { return _timeout; }
0037
0038 inline static QTestEventLoop &instance()
0039 {
0040 Q_CONSTINIT static QPointer<QTestEventLoop> testLoop;
0041 if (testLoop.isNull())
0042 testLoop = new QTestEventLoop(QCoreApplication::instance());
0043 return *static_cast<QTestEventLoop *>(testLoop);
0044 }
0045
0046 public Q_SLOTS:
0047 inline void exitLoop();
0048
0049 protected:
0050 inline void timerEvent(QTimerEvent *e) override;
0051
0052 private:
0053 QEventLoop *loop = nullptr;
0054 int timerId = -1;
0055 uint _timeout :1;
0056 Q_DECL_UNUSED_MEMBER uint reserved :31;
0057 };
0058
0059 inline void QTestEventLoop::enterLoop(std::chrono::milliseconds msecs)
0060 {
0061 Q_ASSERT(!loop);
0062 _timeout = false;
0063
0064 if (QTest::runningTest() && QTest::currentTestResolved())
0065 return;
0066
0067 using namespace std::chrono_literals;
0068 QEventLoop l;
0069
0070 timerId = startTimer(msecs, msecs < 1s ? Qt::PreciseTimer : Qt::CoarseTimer);
0071
0072 loop = &l;
0073 l.exec();
0074 loop = nullptr;
0075 }
0076
0077 inline void QTestEventLoop::exitLoop()
0078 {
0079 if (thread() != QThread::currentThread())
0080 {
0081 QMetaObject::invokeMethod(this, "exitLoop", Qt::QueuedConnection);
0082 return;
0083 }
0084
0085 if (timerId != -1)
0086 killTimer(timerId);
0087 timerId = -1;
0088
0089 if (loop)
0090 loop->exit();
0091 }
0092
0093 inline void QTestEventLoop::timerEvent(QTimerEvent *e)
0094 {
0095 if (e->timerId() != timerId)
0096 return;
0097 _timeout = true;
0098 exitLoop();
0099 }
0100
0101 QT_END_NAMESPACE
0102
0103 #endif