Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:11:37

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/qbasictimer.h>
0011 #include <QtCore/qcoreapplication.h>
0012 #include <QtCore/qeventloop.h>
0013 #include <QtCore/qobject.h>
0014 #include <QtCore/qpointer.h>
0015 #include <QtCore/qthread.h>
0016 
0017 QT_BEGIN_NAMESPACE
0018 
0019 
0020 class Q_TESTLIB_EXPORT QTestEventLoop : public QObject
0021 {
0022     Q_OBJECT
0023 
0024 public:
0025     QTestEventLoop(QObject *parent = nullptr)
0026         : QObject(parent), _timeout(false)
0027     {}
0028 
0029     void enterLoopMSecs(int ms) { enterLoop(std::chrono::milliseconds{ms}); }
0030     void enterLoop(int secs) { enterLoop(std::chrono::seconds{secs}); }
0031     inline void enterLoop(std::chrono::milliseconds msecs);
0032 
0033     inline void changeInterval(int secs)
0034     { changeInterval(std::chrono::seconds{secs}); }
0035 
0036     void changeInterval(std::chrono::nanoseconds nsecs)
0037     { timer.start(nsecs, this); }
0038 
0039     inline bool timeout() const
0040     { return _timeout; }
0041 
0042     inline static QTestEventLoop &instance()
0043     {
0044         Q_CONSTINIT static QPointer<QTestEventLoop> testLoop;
0045         if (testLoop.isNull())
0046             testLoop = new QTestEventLoop(QCoreApplication::instance());
0047         return *static_cast<QTestEventLoop *>(testLoop);
0048     }
0049 
0050 public Q_SLOTS:
0051     inline void exitLoop();
0052 
0053 protected:
0054     inline void timerEvent(QTimerEvent *e) override;
0055 
0056 private:
0057     QEventLoop *loop = nullptr;
0058     QBasicTimer timer;
0059     uint _timeout   :1;
0060     Q_DECL_UNUSED_MEMBER uint reserved   :31;
0061 };
0062 
0063 inline void QTestEventLoop::enterLoop(std::chrono::milliseconds msecs)
0064 {
0065     Q_ASSERT(!loop);
0066     _timeout = false;
0067 
0068     if (QTest::runningTest() && QTest::currentTestResolved())
0069         return;
0070 
0071     using namespace std::chrono_literals;
0072     QEventLoop l;
0073     // if tests want to measure sub-second precision, use a precise timer
0074     timer.start(msecs, msecs < 1s ? Qt::PreciseTimer : Qt::CoarseTimer, this);
0075 
0076     loop = &l;
0077     l.exec();
0078     loop = nullptr;
0079 }
0080 
0081 inline void QTestEventLoop::exitLoop()
0082 {
0083     if (thread() != QThread::currentThread())
0084     {
0085         QMetaObject::invokeMethod(this, "exitLoop", Qt::QueuedConnection);
0086         return;
0087     }
0088 
0089     timer.stop();
0090 
0091     if (loop)
0092         loop->exit();
0093 }
0094 
0095 inline void QTestEventLoop::timerEvent(QTimerEvent *e)
0096 {
0097     if (e->id() != timer.id())
0098         return;
0099     _timeout = true;
0100     exitLoop();
0101 }
0102 
0103 QT_END_NAMESPACE
0104 
0105 #endif