#pragma once /** * @RDE_HEADER@ * Function which waits (QEventLoop) for a success signal or a cancelation signal, optionally with a timeout * Useful for blocking on async things * $Id: connection.h 45834 2019-03-01 12:56:15Z ehrlicher $ * $HeadURL: svn://192.168.133.21/TDS/branches/product/features/swp_2023_devel/Lts/Common/LtsUtils/LtsUtilsCore/connection.h $ * $Author: ehrlicher $ * * Created by Mike Wille, ESZS, 2024-03-03 */ #include #include #include #include namespace LtsUtils { template void addConnect(QEventLoop &x, bool &success, const typename QtPrivate::FunctionPointer::Object *sender, Func signal, bool isSuccess) { if (isSuccess) { QObject::connect(sender, signal, &x, [&success]() { //fprintf(stderr, "await: success!\n"); success = true; }); } QObject::connect(sender, signal, &x, &QEventLoop::quit, Qt::QueuedConnection); } template void addConnect(QEventLoop &x, bool &success, const typename QtPrivate::FunctionPointer::Object *sender, Func signal, bool isSuccess, Connect... connects) { addConnect(x, success, sender, signal, isSuccess); addConnect(x, success, connects...); } template // a 'Connect' consists of a Qt sender, a Qt signal and a bool if this signal is a signal for success or for failure. void await(Connect... connects) noexcept(false) { QEventLoop x; bool success = false; addConnect(x, success, connects...); // fprintf(stderr, "await: now waiting...\n"); x.exec(); // fprintf(stderr, "await: done! success? %d\n", success); if (!success) { // fprintf(stderr, "await: !success - throwing error!\n"); throw std::runtime_error("Failed."); } } template void awaitTimeout(const int timeoutMs, Connect... connects) noexcept(false) { std::unique_ptr t(new QTimer); bool timeout = false; if (timeoutMs > -1) { t->setInterval(timeoutMs); t->setSingleShot(true); QObject::connect(t.get(), &QTimer::timeout, t.get(), [&timeout](){ fprintf(stderr, "awaitTimeout: timed out!\n"); timeout = true; }); t->start(); } await(t.get(), &QTimer::timeout, false, connects...); // throws // fprintf(stderr, "awaitTimeout: done waiting - timeout? %d\n", timeout); if (timeout) { // fprintf(stderr, "await: timed out - throwing error!\n"); throw std::runtime_error("Timeout."); } } //// non-looping version of the classic wait stdlib function which enters the event loop to prevent the application from hanging //void waitEventLoop(const int timeoutMs); //{ // try // { // awaitTimeout(timeoutMs); // } // catch(...){} //} // 2024.11.29 Norbert Thoden // awaitWithCancelationSignal scheint unter Windows nicth zu funktioneren. // Siehe auch GUEZE-3155 Replay auf ABT nicht funktional // deprecated, do not use template void awaitWithCancelationSignal(const typename QtPrivate::FunctionPointer::Object *sender1, Func1 signal1, const typename QtPrivate::FunctionPointer::Object *sender2, Func2 signal2, const int timeoutMs = 0) noexcept(false) { if (timeoutMs > 0) { awaitTimeout(timeoutMs, sender1, signal1, true, sender2, signal2, false); return; } await(sender1, signal1, true, sender2, signal2, false); } } // namespace LtsUtils