#pragma once namespace Aurora::Async { #define ASYNC_ERROR(exp) { if constexpr (AuIsSame_v) { SysPushErrorGen(exp); return {}; } else { throw AuString(exp); } } #define ASYNC_FINISH { if constexpr (AuIsSame_v) { return true; } } template || AuIsVoid_v)> static AuFunction TranslateAsyncFunctionToDispatcherWithThread(WorkerId_t id, AuFunction func) { if (!func) return {}; return [=](Args&&... in) -> T { auto work = AuMakeShared([=]() -> void { func(in...); }); if (!work) ASYNC_ERROR("can't dispatch async call. out of memory"); auto workItem = NewWorkItem(id, work); if (!workItem) ASYNC_ERROR("can't dispatch async call. out of memory"); workItem->Dispatch(); ASYNC_FINISH; }; } /// Async app only template || AuIsVoid_v)> static AuFunction TranslateAsyncFunctionToDispatcher(AuFunction func) { return TranslateAsyncFunctionToDispatcherWithThread(GetAsyncApp()->GetCurrentThread(), func); } /// Async app only template || AuIsVoid_v)> static AuFunction, Args...)> TranslateAsyncReturnableFunctionToDispatcherWithThread(WorkerId_t id, AuFunction func) { return [=](AuFunction callback, Args... in) -> T { auto work = AuMakeShared>(); if (!work) ASYNC_ERROR("can't dispatch async call; out of memory"); work.task.onProcess = [=](const AVoid &) -> B { if (!func) return B{}; return func(in...); }; work.callback.onSuccess = [=](const AVoid &, const B &ret) { callback(ret); }; auto workItem = NewWorkItem(id, work); if (!workItem) ASYNC_ERROR("can't dispatch async call; out of memory"); workItem->Dispatch(); ASYNC_FINISH; }; } #undef ASYNC_ERROR #undef ASYNC_FINISH #pragma endregion EASE_OF_READING }