5#ifndef QFUNCTIONS_WINRT_P_H
6#define QFUNCTIONS_WINRT_P_H
19#include <QtCore/private/qglobal_p.h>
21#if defined(Q_OS_WIN) && defined(Q_CC_MSVC)
23#include <QtCore/QCoreApplication>
24#include <QtCore/QThread>
25#include <QtCore/QAbstractEventDispatcher>
26#include <QtCore/QElapsedTimer>
27#include <QtCore/qt_windows.h>
28#include <QtCore/private/qcomptr_p.h>
30#include <windows.foundation.h>
33#define RETURN_IF_FAILED(msg, ret)
35 qErrnoWarning(hr, msg);
39#define RETURN_IF_FAILED_WITH_ARGS(msg, ret, ...)
41 qErrnoWarning(hr, msg, __VA_ARGS__);
45#define RETURN_HR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return hr)
46#define RETURN_OK_IF_FAILED(msg) RETURN_IF_FAILED(msg, return S_OK)
47#define RETURN_FALSE_IF_FAILED(msg) RETURN_IF_FAILED(msg, return false)
48#define RETURN_VOID_IF_FAILED(msg) RETURN_IF_FAILED(msg, return)
49#define RETURN_HR_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return hr, __VA_ARGS__)
50#define RETURN_OK_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return S_OK, __VA_ARGS__)
51#define RETURN_FALSE_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return false, __VA_ARGS__)
52#define RETURN_VOID_IF_FAILED_WITH_ARGS(msg, ...) RETURN_IF_FAILED_WITH_ARGS(msg, return, __VA_ARGS__)
54#define Q_ASSERT_SUCCEEDED(hr)
55 Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
59namespace QWinRTFunctions {
65 ProcessThreadEvents = 1,
66 ProcessMainThreadEvents = 2
69using EarlyExitConditionFunction = std::function<
bool(
void)>;
72static inline HRESULT _await_impl(
const ComPtr<T> &asyncOp, AwaitStyle awaitStyle, uint timeout,
73 EarlyExitConditionFunction func)
75 ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo;
76 HRESULT hr = asyncOp.As(&asyncInfo);
85 case ProcessMainThreadEvents:
86 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
87 QCoreApplication::processEvents();
90 if (timeout && t.hasExpired(timeout))
91 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
94 case ProcessThreadEvents:
95 if (QAbstractEventDispatcher *dispatcher = QThread::currentThread()->eventDispatcher()) {
96 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
97 dispatcher->processEvents(QEventLoop::AllEvents);
100 if (timeout && t.hasExpired(timeout))
101 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
108 while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) {
109 QThread::yieldCurrentThread();
110 if (timeout && t.hasExpired(timeout))
111 return HRESULT_FROM_WIN32(ERROR_TIMEOUT);
116 if (FAILED(hr) || status != AsyncStatus::Completed) {
118 hr = asyncInfo->get_ErrorCode(&ec);
121 hr = asyncInfo->Close();
131static inline HRESULT await(
const ComPtr<T> &asyncOp, AwaitStyle awaitStyle = YieldThread,
132 uint timeout = 0, EarlyExitConditionFunction func =
nullptr)
134 HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func);
138 return asyncOp->GetResults();
141template<
typename T,
typename U>
142static inline HRESULT await(
const ComPtr<T> &asyncOp, U *results,
143 AwaitStyle awaitStyle = YieldThread, uint timeout = 0,
144 EarlyExitConditionFunction func =
nullptr)
146 HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout, func);
150 return asyncOp->GetResults(results);