// Thanks to RetroArch/Libretro team for this idea // This is improved version of the original idea #pragma once #include "pch.h" #include #include #include #include #include "Common/Log.h" #include "UWPUtil.h" using namespace Windows::UI::Core; // Don't add 'using' 'Windows::Foundation' // it might cause confilct with some types like 'Point' #pragma region Async Handlers template T TaskHandler(std::function()> wtask, T def) { T result = def; bool done = false; wtask().then([&](concurrency::task t) { try { result = t.get(); } catch (Platform::Exception^ exception_) { ERROR_LOG(FILESYS, FromPlatformString(exception_->Message).c_str()); } done = true; }); CoreWindow^ corewindow = CoreWindow::GetForCurrentThread(); while (!done) { try { if (corewindow) { corewindow->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); } else { corewindow = CoreWindow::GetForCurrentThread(); } } catch (...) { } } return result; }; template T TaskPass(Windows::Foundation::IAsyncOperation^ task, T def) { return TaskHandler([&]() { return concurrency::create_task(task).then([](T res) { return res; }); }, def); } bool ActionPass(Windows::Foundation::IAsyncAction^ action); #pragma endregion // Now it's more simple to execute async task // @out: output variable // @task: async task template void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task) { try { out = TaskPass(task, T()); } catch (...) { out = T(); } }; // For specific return default value // @out: output variable // @task: async task // @def: default value when fail template void ExecuteTask(T& out, Windows::Foundation::IAsyncOperation^ task, T def) { try{ out = TaskPass(task, def); } catch (...) { out = def; } }; // Async action such as 'Delete' file // @action: async action // return false when action failed bool ExecuteTask(Windows::Foundation::IAsyncAction^ action);