#pragma once #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]() { 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 void await(Connect... connects) noexcept(false) { QEventLoop x; bool success = false; addConnect(x, success, connects...); x.exec(); if (!success) { 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...); if (timeout) { throw std::runtime_error("Timeout."); } } 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); } }