60 lines
2.5 KiB
C++
60 lines
2.5 KiB
C++
|
#pragma once
|
||
|
|
||
|
namespace Aurora::Async
|
||
|
{
|
||
|
#define ASYNC_ERROR(exp) { if constexpr (AuIsSame_v<T, bool>) { SysPushErrorGen(exp); return {}; } else { throw AuString(exp); } }
|
||
|
#define ASYNC_FINISH { if constexpr (AuIsSame_v<T, bool>) { return true; } }
|
||
|
|
||
|
template<typename T = void, typename... Args, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<T, bool> || AuIsVoid_v<T>)>
|
||
|
static AuFunction<T(Args&&...)> TranslateAsyncFunctionToDispatcherWithThread(WorkerId_t id, AuFunction<void(Args...)> func)
|
||
|
{
|
||
|
if (!func) return {};
|
||
|
return [=](Args&&... in) -> T
|
||
|
{
|
||
|
auto work = AuMakeShared<BasicWorkStdFunc>([=]() -> 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<typename T = void, typename... Args, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<T, bool> || AuIsVoid_v<T>)>
|
||
|
static AuFunction<T(Args&&...)> TranslateAsyncFunctionToDispatcher(AuFunction<void(Args...)> func)
|
||
|
{
|
||
|
return TranslateAsyncFunctionToDispatcherWithThread(GetAsyncApp()->GetCurrentThread(), func);
|
||
|
}
|
||
|
|
||
|
/// Async app only
|
||
|
template<typename B = void, typename T, typename... Args, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<T, bool> || AuIsVoid_v<T>)>
|
||
|
static AuFunction<T(AuFunction<void(const B&)>, Args...)> TranslateAsyncReturnableFunctionToDispatcherWithThread(WorkerId_t id, AuFunction<B(Args...)> func)
|
||
|
{
|
||
|
return [=](AuFunction<T(const B&)> callback, Args... in) -> T
|
||
|
{
|
||
|
auto work = AuMakeShared<WorkPairImpl<AVoid, B>>();
|
||
|
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
|
||
|
}
|