#pragma once
#include "pch.h"
#include <ppl.h>
#include <ppltasks.h>
#include <type_traits>
#include "Common/Log.h"
#include "UWPUtil.h"
template<typename T>
struct is_winrt_class : std::bool_constant<std::is_base_of_v<winrt::Windows::Foundation::IUnknown, T>> {};
template<typename T>
T ExecuteAsyncWithPump(winrt::Windows::Foundation::IAsyncOperation<T> asyncOp)
{
T result{ nullptr };
bool done = false;
asyncOp.Completed([&](auto&& sender, winrt::Windows::Foundation::AsyncStatus status) {
if (status == winrt::Windows::Foundation::AsyncStatus::Completed) {
try {
result = sender.GetResults();
}
catch (const winrt::hresult_error& e) {
ERROR_LOG(Log::FileSystem, "%s", winrt::to_string(e.message()).c_str());
}
}
done = true;
});
winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread();
while (!done)
{
try {
if (corewindow) {
corewindow.Dispatcher().ProcessEvents(winrt::Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent);
}
else {
corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread();
}
}
catch (...) {
}
}
return result;
}
template<typename T>
T ExecuteAsyncWithPumpValue(winrt::Windows::Foundation::IAsyncOperation<T> asyncOp, T def)
{
T result = def;
bool done = false;
asyncOp.Completed([&](auto&& sender, winrt::Windows::Foundation::AsyncStatus status) {
if (status == winrt::Windows::Foundation::AsyncStatus::Completed) {
try {
result = sender.GetResults();
}
catch (const winrt::hresult_error& e) {
ERROR_LOG(Log::FileSystem, "%s", winrt::to_string(e.message()).c_str());
}
}
done = true;
});
winrt::Windows::UI::Core::CoreWindow corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread();
while (!done)
{
try {
if (corewindow) {
corewindow.Dispatcher().ProcessEvents(winrt::Windows::UI::Core::CoreProcessEventsOption::ProcessAllIfPresent);
}
else {
corewindow = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread();
}
}
catch (...) {
}
}
return result;
}
bool ActionPass(winrt::Windows::Foundation::IAsyncAction action);
template<typename T, std::enable_if_t<is_winrt_class<T>::value, int> = 0>
void ExecuteTask(T& out, winrt::Windows::Foundation::IAsyncOperation<T> task)
{
try {
out = ExecuteAsyncWithPump<T>(task);
}
catch (...) {
out = nullptr;
}
}
template<typename T, std::enable_if_t<!is_winrt_class<T>::value, int> = 0>
void ExecuteTask(T& out, winrt::Windows::Foundation::IAsyncOperation<T> task)
{
try {
out = ExecuteAsyncWithPumpValue<T>(task, T{});
}
catch (...) {
out = T{};
}
}
template<typename T>
void ExecuteTask(T& out, winrt::Windows::Foundation::IAsyncOperation<T> task, T def)
{
try {
out = ExecuteAsyncWithPumpValue<T>(task, def);
}
catch (...) {
out = def;
}
}
bool ExecuteTask(winrt::Windows::Foundation::IAsyncAction action);