mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-25 18:25:42 +08:00
Issue #11 Improve CEventLoop API
This commit is contained in:
@@ -426,11 +426,12 @@ namespace BlackCore
|
|||||||
CStatusMessageList CApplication::waitForSetup(int timeoutMs)
|
CStatusMessageList CApplication::waitForSetup(int timeoutMs)
|
||||||
{
|
{
|
||||||
if (!m_setupReader) { return CStatusMessage(this).error(u"No setup reader"); }
|
if (!m_setupReader) { return CStatusMessage(this).error(u"No setup reader"); }
|
||||||
CEventLoop::processEventsUntil(this, &CApplication::setupHandlingCompleted, timeoutMs, [this]
|
CEventLoop eventLoop;
|
||||||
|
eventLoop.stopWhen(this, &CApplication::setupHandlingCompleted);
|
||||||
|
if (!m_setupReader->isSetupAvailable())
|
||||||
{
|
{
|
||||||
// init, if this is true event queue is not started
|
eventLoop.exec(timeoutMs);
|
||||||
return m_setupReader->isSetupAvailable();
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// setup handling completed with success or failure, or we run into time out
|
// setup handling completed with success or failure, or we run into time out
|
||||||
CStatusMessageList msgs;
|
CStatusMessageList msgs;
|
||||||
|
|||||||
@@ -152,7 +152,8 @@ namespace BlackCore::Db
|
|||||||
{
|
{
|
||||||
// just give the system some time to relax, consolidation is time consuming
|
// just give the system some time to relax, consolidation is time consuming
|
||||||
if (!this->doWorkCheck()) { return; }
|
if (!this->doWorkCheck()) { return; }
|
||||||
CEventLoop::processEventsFor(1000);
|
CEventLoop eventLoop;
|
||||||
|
eventLoop.exec(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,47 +25,41 @@ namespace BlackMisc
|
|||||||
class CEventLoop
|
class CEventLoop
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Deleted constructor
|
//! Event loop will stop if the given signal is received.
|
||||||
CEventLoop() = delete;
|
|
||||||
|
|
||||||
//! Wait for the given time, while processing events.
|
|
||||||
static void processEventsFor(int timeoutMs)
|
|
||||||
{
|
|
||||||
QEventLoop eventLoop;
|
|
||||||
QTimer::singleShot(timeoutMs, &eventLoop, &QEventLoop::quit);
|
|
||||||
eventLoop.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Block, but keep processing events, until sender emits the signal or the timeout expires.
|
|
||||||
//! Return true if the signal was emitted, false if the timeout expired.
|
|
||||||
template <typename T, typename F>
|
template <typename T, typename F>
|
||||||
static bool processEventsUntil(const T *sender, F signal, int timeoutMs)
|
void stopWhen(const T *sender, F signal)
|
||||||
{
|
{
|
||||||
return processEventsUntil(sender, signal, timeoutMs, [] {});
|
QObject::connect(sender, signal, &m_eventLoop, [this] { m_eventLoop.exit(GotSignal); });
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Overloaded version that executes an initial function after connecting the signal.
|
//! Event loop will stop if the given signal is received and condition returns true.
|
||||||
//! If the function's return type is convertible to bool, and it evaluates to true,
|
|
||||||
//! then the waiting will immediately time out and return true.
|
|
||||||
template <typename T, typename F1, typename F2>
|
template <typename T, typename F1, typename F2>
|
||||||
static bool processEventsUntil(const T *sender, F1 signal, int timeoutMs, F2 init)
|
void stopWhen(const T *sender, F1 signal, F2 &&condition)
|
||||||
{
|
{
|
||||||
QEventLoop eventLoop;
|
QObject::connect(sender, signal, &m_eventLoop, [this, condition = std::forward<F2>(condition)](auto &&... args)
|
||||||
bool result = false;
|
|
||||||
QObject::connect(sender, signal, &eventLoop, [ & ]
|
|
||||||
{
|
{
|
||||||
result = true;
|
if (condition(std::forward<decltype(args)>(args)...)) { m_eventLoop.exit(GotSignal); }
|
||||||
eventLoop.quit();
|
|
||||||
});
|
});
|
||||||
if constexpr (std::is_void_v<decltype(init())>) { init(); }
|
|
||||||
else if (init()) { return true; }
|
|
||||||
if (timeoutMs > 0)
|
|
||||||
{
|
|
||||||
QTimer::singleShot(timeoutMs, &eventLoop, &QEventLoop::quit);
|
|
||||||
}
|
|
||||||
eventLoop.exec();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Begin processing events until the timeout or stop condition occurs.
|
||||||
|
//! \return True if the signal was received, false if it timed out.
|
||||||
|
bool exec(int timeoutMs)
|
||||||
|
{
|
||||||
|
if (timeoutMs >= 0)
|
||||||
|
{
|
||||||
|
QTimer::singleShot(timeoutMs, &m_eventLoop, [this] { m_eventLoop.exit(TimedOut); });
|
||||||
|
}
|
||||||
|
return m_eventLoop.exec() == GotSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Result
|
||||||
|
{
|
||||||
|
GotSignal = 0,
|
||||||
|
TimedOut,
|
||||||
|
};
|
||||||
|
QEventLoop m_eventLoop;
|
||||||
};
|
};
|
||||||
} // ns
|
} // ns
|
||||||
|
|
||||||
|
|||||||
@@ -81,10 +81,11 @@ namespace BlackMisc::Network
|
|||||||
QObject::connect(&socket, &QTcpSocket::connected, &mapper, qOverload<>(&QSignalMapper::map));
|
QObject::connect(&socket, &QTcpSocket::connected, &mapper, qOverload<>(&QSignalMapper::map));
|
||||||
QObject::connect(&socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), &mapper, qOverload<>(&QSignalMapper::map));
|
QObject::connect(&socket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), &mapper, qOverload<>(&QSignalMapper::map));
|
||||||
mapper.setMapping(&socket, 0);
|
mapper.setMapping(&socket, 0);
|
||||||
const bool timedOut = !CEventLoop::processEventsUntil(&mapper, qOverload<int>(&QSignalMapper::mapped), timeoutMs, [&]
|
|
||||||
{
|
CEventLoop eventLoop;
|
||||||
socket.connectToHost(hostAddress, static_cast<quint16>(port));
|
eventLoop.stopWhen(&mapper, qOverload<int>(&QSignalMapper::mapped));
|
||||||
});
|
socket.connectToHost(hostAddress, static_cast<quint16>(port));
|
||||||
|
const bool timedOut = !eventLoop.exec(timeoutMs);
|
||||||
|
|
||||||
if (socket.state() != QTcpSocket::ConnectedState)
|
if (socket.state() != QTcpSocket::ConnectedState)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user