Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:12:23

0001 // Copyright (C) 2021 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
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     // if tests want to measure sub-second precision, use a precise timer
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