[+] Added async task (this should be job) private

[+] Added ToWorkResultT for apps using BasicWorkCtx
This commit is contained in:
Reece Wilson 2021-09-29 11:47:54 +01:00
parent 95b0e1135c
commit dca4ca195b
3 changed files with 95 additions and 16 deletions

View File

@ -22,6 +22,11 @@ namespace Aurora::Async
using WorkerId_t = AuPair<ThreadGroup_t, ThreadId_t>;
using DispatchTarget_t = AuPair<ThreadGroup_t, AuOptional<ThreadId_t>>;
struct WorkPriv
{
AuUInt32 magic;
};
struct IWorkItemHandler
{
enum class EProcessNext
@ -48,6 +53,8 @@ namespace Aurora::Async
virtual void DispatchFrame(ProcessInfo &info) = 0;
virtual void Shutdown() = 0;
virtual void *GetPrivateData() { return nullptr; }
};
template<class Info_t = AVoid, class Result_t = AVoid>
@ -69,9 +76,21 @@ namespace Aurora::Async
{
std::function<AuOptional<Result_t>(const Info_t &)> onFrame = 0;
};
using FVoidTask = FTask<AVoid, AVoid>;
template<class In_t>
static inline FTask<In_t, AVoid> TaskFromConsumerRefT(const AuConsumer<const In_t &> &func)
{
FTask<In_t, AVoid> ret;
ret.onFrame = [=](const In_t &a) -> AuOptional<AVoid>
{
func(a);
return AVoid{};
};
return ret;
}
template<class Info_t = AVoid, class Result_t = AVoid>
struct CTask
{
@ -96,6 +115,9 @@ namespace Aurora::Async
virtual bool HasFinished() = 0;
virtual bool HasFailed() = 0;
virtual void Cancel() = 0;
virtual void *GetPrivateData() = 0;
virtual AuOptional<void *> ToWorkResultT() = 0;
};
AUKN_SYM AuSPtr<IWorkItem> NewWorkItem(const DispatchTarget_t &worker, const AuSPtr<IWorkItemHandler> &task, bool supportsBlocking = false);
@ -148,7 +170,21 @@ namespace Aurora::Async
#endif
};
#if !defined(_CPPSHARP)
/// @hideinitializer
struct BasicWorkCtx : WorkPriv
{
BasicWorkCtx()
{
magic = AuConvertMagicTag32("BWOT");
opt = nullptr;
}
void *opt;
};
/// @hideinitializer
template<typename Info_t, typename Result_t, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>>
struct BasicWorkCallback : IWorkItemHandler, std::enable_shared_from_this<IWorkItemHandler>
{
@ -162,10 +198,10 @@ namespace Aurora::Async
caller = GetAsyncApp()->GetCurrentThread();
}
Info_t input;
Task_t task;
Job_t callback;
Info_t input;
BasicWorkCallback<Info_t, Result_t, Task_t, Job_t> &SetTask(const Task_t &task)
{
@ -178,26 +214,31 @@ namespace Aurora::Async
this->callback = callback;
return *this;
}
private:
static constexpr bool IsCallbackPtr = std::is_pointer_v<Job_t> || AuIsBaseOfTemplate<std::shared_ptr, Job_t>::value;
static constexpr bool IsTaskPtr = std::is_pointer_v<Task_t> || AuIsBaseOfTemplate<std::shared_ptr, Task_t>::value;
WorkerId_t caller;
BasicWorkCtx secretContext_;
AuOptional<Result_t> resultValue_;
virtual void *GetPrivateData() override { return &secretContext_; }
void DispatchFrame(ProcessInfo &info) override
{
AuOptional<Result_t> ret;
try
{
if constexpr (IsTaskPtr)
{
ret = task->onFrame(input);
resultValue_ = task->onFrame(input);
}
else
{
ret = task.onFrame(input);
resultValue_ = task.onFrame(input);
}
}
catch (...)
@ -208,19 +249,20 @@ namespace Aurora::Async
auto pin = std::static_pointer_cast<std::remove_pointer_t<decltype(this)>>(this->shared_from_this());
std::function<void()> func = [ret, pin]()
std::function<void()> func = [resultValue_, pin]()
{
try
{
if (ret.has_value())
if (resultValue_.has_value())
{
pin->secretContext_.opt = resultValue_.value();
if constexpr (IsCallbackPtr)
{
pin->callback->onSuccess(pin->input, *ret);
pin->callback->onSuccess(pin->input, *resultValue_);
}
else
{
pin->callback.onSuccess(pin->input, *ret);
pin->callback.onSuccess(pin->input, *resultValue_);
}
}
else
@ -298,8 +340,9 @@ namespace Aurora::Async
}
};
/// @hideinitializer
template<typename Frame_t = std::function<void()>, typename Cleanup_t = std::function<void()>>
struct WorkItemCallabale : IWorkItemHandler
struct WorkItemCallable : IWorkItemHandler
{
Frame_t frame;
Cleanup_t cleanup;
@ -321,9 +364,9 @@ namespace Aurora::Async
#define ASYNC_FINISH if constexpr (std::is_same_v<T, bool>) { return true; }
template<typename T = void, typename... Args, AU_TEMPLATE_ENABLE_WHEN(std::is_same_v<T, bool> || std::is_void<T>::value)>
static std::function<T(Args...)> TranslateAsyncFunctionToDispatcherWithThread(WorkerId_t id, std::function<void(Args...)> func)
static std::function<T(Args&&...)> TranslateAsyncFunctionToDispatcherWithThread(WorkerId_t id, std::function<void(Args...)> func)
{
return [=](Args... in) -> T
return [=](Args&&... in) -> T
{
auto work = AuMakeShared<BasicWorkStdFunc>([=]() -> void {
func(in...);
@ -337,9 +380,9 @@ namespace Aurora::Async
}
template<typename T = void, typename... Args, AU_TEMPLATE_ENABLE_WHEN(std::is_same_v<T, bool> || std::is_void<T>::value)>
static std::function<T(Args...)> TranslateAsyncFunctionToDispatcher(std::function<void(Args...)> func)
static std::function<T(Args&&...)> TranslateAsyncFunctionToDispatcher(std::function<void(Args...)> func)
{
return TranslateAsyncFunctionToDispatcherWithThread<T, Args>(GetAsyncApp()->GetCurrentThread(), func);
return TranslateAsyncFunctionToDispatcherWithThread(GetAsyncApp()->GetCurrentThread(), func);
}
template<typename B = void, typename T, typename... Args, AU_TEMPLATE_ENABLE_WHEN(std::is_same_v<T, bool> || std::is_void<T>::value)>
@ -367,7 +410,7 @@ namespace Aurora::Async
template<typename B = void, typename T, typename... Args, AU_TEMPLATE_ENABLE_WHEN(std::is_same_v<T, bool> || std::is_void<T>::value)>
static std::function<T(std::function<void(const B&)>, Args...)> TranslateAsyncReturnableFunctionToDispatcher(std::function<AuOptional<B>(Args...)> func)
{
return TranslateAsyncReturnableFunctionToDispatcherWithThread<B, T, Args>(GetAsyncApp()->GetCurrentThread(), func);
return TranslateAsyncReturnableFunctionToDispatcherWithThread(GetAsyncApp()->GetCurrentThread(), func);
}
#undef ASYNC_ERROR

View File

@ -301,4 +301,36 @@ namespace Aurora::Async
}
return AuMakeShared<WorkItem>(worker, task, supportsBlocking);
}
void *WorkItem::GetPrivateData()
{
if (!this->task_)
{
return nullptr;
}
return this->task_->GetPrivateData();
}
AuOptional<void *> WorkItem::ToWorkResultT()
{
if (!this->task_)
{
return nullptr;
}
auto priv = reinterpret_cast<Async::WorkPriv *>(this->task_->GetPrivateData());
if (!priv)
{
return nullptr;
}
if (priv->magic == AuConvertMagicTag32("BWOT"))
{
return reinterpret_cast<Async::BasicWorkCtx *>(priv)->opt;
}
return {};
}
}

View File

@ -34,6 +34,10 @@ namespace Aurora::Async
void RunAsync() override;
void CancelAsync() override;
void *GetPrivateData() override;
AuOptional<void *> ToWorkResultT() override;
private:
void DispatchEx(bool check);
AuSPtr<IWorkItemHandler> task_;