[-] Engine 0.0/1.0 async
This commit is contained in:
parent
7739652ad3
commit
f6437ef66e
@ -14,9 +14,6 @@
|
|||||||
#include "IThreadPool.hpp"
|
#include "IThreadPool.hpp"
|
||||||
#include "IAsyncApp.hpp"
|
#include "IAsyncApp.hpp"
|
||||||
|
|
||||||
#include "Legacy/Jobs.hpp"
|
|
||||||
#include "Legacy/Tasks.hpp"
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
namespace Aurora::Async
|
||||||
{
|
{
|
||||||
AUKN_SYM IAsyncApp * GetAsyncApp();
|
AUKN_SYM IAsyncApp * GetAsyncApp();
|
||||||
@ -59,10 +56,4 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
#if !defined(_CPPSHARP)
|
#if !defined(_CPPSHARP)
|
||||||
#include "IPCPromises.hpp"
|
#include "IPCPromises.hpp"
|
||||||
|
|
||||||
#include "Legacy/JobFrom.hpp"
|
|
||||||
#include "Legacy/TaskFrom.hpp"
|
|
||||||
#include "Legacy/WorkPairImpl.hpp"
|
|
||||||
#include "Legacy/WorkBasic.hpp"
|
|
||||||
#include "Legacy/OldTrash.hpp"
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -265,11 +265,11 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuAsync::NewWorkItem(this->pid.value(), AuMakeSharedPanic<AuAsync::BasicWorkStdFunc>([pThat = this->SharedFromThis()]
|
AuAsync::DispatchOn(this->pid.value(), [pThat = this->SharedFromThis()]
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(pThat->mutex);
|
AU_LOCK_GUARD(pThat->mutex);
|
||||||
pThat->SubmitComplete();
|
pThat->SubmitComplete();
|
||||||
}))->Dispatch();
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,5 @@ namespace Aurora::Async
|
|||||||
virtual void Cancel() = 0;
|
virtual void Cancel() = 0;
|
||||||
|
|
||||||
virtual void *GetPrivateData() = 0;
|
virtual void *GetPrivateData() = 0;
|
||||||
virtual AuOptional<void *> ToWorkResultT() = 0;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,5 +0,0 @@
|
|||||||
> Deprecated APIs <
|
|
||||||
|
|
||||||
* Wont remove
|
|
||||||
* Powering old projects
|
|
||||||
* Sometimes used as shorthands internally
|
|
@ -1,184 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: JobFrom.hpp
|
|
||||||
Date: 2021-11-1
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid, class Callable_t>
|
|
||||||
static inline FJob<Info_t, Result_t> JobFromPairConsumer(const /*AuConsumer<const Info_t &, const Result_t &> */ Callable_t&onSuccess)
|
|
||||||
{
|
|
||||||
FJob<Info_t, Result_t> ret;
|
|
||||||
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
|
||||||
{
|
|
||||||
onSuccess(in, a);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid, class Callable_t>
|
|
||||||
static inline FJob<Info_t, Result_t> JobFromResultConsumer(/*AuConsumer<const Result_t &> */ Callable_t onSuccess)
|
|
||||||
{
|
|
||||||
FJob<Info_t, Result_t> ret;
|
|
||||||
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
|
||||||
{
|
|
||||||
onSuccess(a);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename ... Args, typename Callable_t>
|
|
||||||
FJob<AuTuple<Args...>, Out_t> JobFromTupleConsumer(/*AuConsumer<Args..., const Result_t &> */ Callable_t onSuccess)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<Args...>, Out_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<Args...> &in, const Out_t &a)
|
|
||||||
{
|
|
||||||
AuTupleApply(onSuccess, AuTupleCat(in, AuMakeTuple<const Out_t &>(a)));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename ... Args, typename Callable_t, typename FailureCallable_t>
|
|
||||||
FJob<AuTuple<Args...>, Out_t> JobFromTupleConsumerEx(/*AuConsumer<Args..., const Result_t &> */ Callable_t onSuccess, FailureCallable_t onFailure)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<Args...>, Out_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<Args...> &in, const Out_t &a)
|
|
||||||
{
|
|
||||||
AuTupleApply(onSuccess, AuTupleCat(in, AuMakeTuple<const Out_t &>(a)));
|
|
||||||
};
|
|
||||||
|
|
||||||
ret.onFailure = [=](const AuTuple<Args...> &in)
|
|
||||||
{
|
|
||||||
AuTupleApply(onFailure, in);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
static inline FJob<Info_t, Result_t> JobFromPairConsumerEx(const AuConsumer<const Info_t &, const Result_t &> &onSuccess, const AuConsumer<const Info_t &> &onFailure)
|
|
||||||
{
|
|
||||||
FJob<Info_t, Result_t> ret;
|
|
||||||
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
|
||||||
{
|
|
||||||
onSuccess(in, a);
|
|
||||||
};
|
|
||||||
ret.onFailure = [=](const Info_t &a)
|
|
||||||
{
|
|
||||||
onFailure(a);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
static inline FJob<Info_t, Result_t> JobFromConsumer(const AuConsumer<const Result_t &> &onSuccess, const AuVoidFunc &onFailure)
|
|
||||||
{
|
|
||||||
FJob<Info_t, Result_t> ret;
|
|
||||||
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
|
||||||
{
|
|
||||||
onSuccess(a);
|
|
||||||
};
|
|
||||||
ret.onFailure = [=](const Info_t &a)
|
|
||||||
{
|
|
||||||
onFailure();
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid, class BaseInfo_t = AVoid, class BaseResult_t = AVoid>
|
|
||||||
static inline FJob<Info_t, Result_t> JobFromDerivedJob(const FJob<BaseInfo_t, BaseResult_t> &reference)
|
|
||||||
{
|
|
||||||
FJob<Info_t, Result_t> ret;
|
|
||||||
ret.onSuccess = [=](const Info_t &in, const Result_t &a)
|
|
||||||
{
|
|
||||||
if (reference.onSuccess)
|
|
||||||
{
|
|
||||||
reference.onSuccess(in, a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ret.onFailure = [=](const Info_t &a)
|
|
||||||
{
|
|
||||||
if (reference.onFailure)
|
|
||||||
{
|
|
||||||
reference.onFailure(a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename Arg0_t, typename ... Args>
|
|
||||||
static inline FJob<AuTuple<Arg0_t, Args...>, ReturnValue_t> JobFromTupleClazz(const AuConsumer<const Arg0_t &, const ReturnValue_t &> &onSuccess)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<Arg0_t, Args...>, ReturnValue_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<Arg0_t, Args...> &in, const ReturnValue_t &out)
|
|
||||||
{
|
|
||||||
onSuccess(AuGet<0>(in), out);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename Arg0_t, typename ... Args>
|
|
||||||
static inline FJob<AuTuple<Arg0_t, Args...>, ReturnValue_t> JobFromTupleClazzEx(const AuConsumer<const Arg0_t &, const ReturnValue_t &> &onSuccess, const AuConsumer<const Arg0_t &> &onFailure)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<Arg0_t, Args...>, ReturnValue_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<Arg0_t, Args...> &in, const ReturnValue_t &out)
|
|
||||||
{
|
|
||||||
onSuccess(AuGet<0>(in), out);
|
|
||||||
};
|
|
||||||
|
|
||||||
ret.onFailure = [=](const AuTuple<Arg0_t, Args...> &in)
|
|
||||||
{
|
|
||||||
onFailure(AuGet<0>(in));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
template<typename ReturnValue_t = void, typename Clazz_t, typename ... Args>
|
|
||||||
static inline FJob<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t> JobFromTupleClazz(const AuConsumer<const ReturnValue_t &> &onSuccess)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<AuSPtr<Clazz_t>, Args...> &in, const ReturnValue_t &out)
|
|
||||||
{
|
|
||||||
onSuccess(out);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename Clazz_t, typename ... Args>
|
|
||||||
static inline FJob<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t> JobFromTupleClazz(const AuConsumer<Args..., const ReturnValue_t &> &onSuccess)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<AuSPtr<Clazz_t>, Args...> &in, const ReturnValue_t &out)
|
|
||||||
{
|
|
||||||
AuTupleApply(onSuccess, AuTupleCat(AuTuplePopFront(in), AuMakeTuple<const ReturnValue_t &>(out)));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename ... Args>
|
|
||||||
static inline FJob<AuTuple<Args...>, ReturnValue_t> JobFromTupleResultConsumer(const AuConsumer<const ReturnValue_t &> &onSuccess)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<Args...>, ReturnValue_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<Args...> &in, const ReturnValue_t &out)
|
|
||||||
{
|
|
||||||
onSuccess(out);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename ... Args>
|
|
||||||
static inline FJob<AuTuple<Args...>, ReturnValue_t> JobFromTuple(const AuConsumer<Args..., const ReturnValue_t &> &onSuccess)
|
|
||||||
{
|
|
||||||
FJob<AuTuple<Args...>, ReturnValue_t> ret;
|
|
||||||
ret.onSuccess = [=](const AuTuple<Args...> &in, const ReturnValue_t &out)
|
|
||||||
{
|
|
||||||
AuTupleApply(onSuccess, AuTupleCat(in, AuMakeTuple<const ReturnValue_t &>(out)));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: Jobs.hpp
|
|
||||||
Date: 2021-11-1
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
struct FJob
|
|
||||||
{
|
|
||||||
using InfoType_t = Info_t;
|
|
||||||
using ResultType_t = Result_t;
|
|
||||||
|
|
||||||
AuFunction<void(const Info_t &, const Result_t &)> onSuccess;
|
|
||||||
AuFunction<void(const Info_t &)> onFailure;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
struct CJob
|
|
||||||
{
|
|
||||||
using InfoType_t = Info_t;
|
|
||||||
using ResultType_t = Result_t;
|
|
||||||
|
|
||||||
void(* onSuccess)(const Info_t &, const Result_t &);
|
|
||||||
void(* onFailure)(const Info_t &);
|
|
||||||
};
|
|
||||||
|
|
||||||
using FVoidJob = FJob<AVoid, AVoid>;
|
|
||||||
}
|
|
@ -1,146 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
#pragma region EASE_OF_READING
|
|
||||||
struct BasicWorkStdFunc : IWorkItemHandler
|
|
||||||
{
|
|
||||||
AuFunction<void()> callback;
|
|
||||||
AuFunction<void()> shutdown; // error
|
|
||||||
|
|
||||||
inline BasicWorkStdFunc(AuFunction<void()> &&callback, AuFunction<void()> &&shutdown) : callback(std::move(callback)), shutdown(std::move(shutdown))
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline BasicWorkStdFunc(AuFunction<void()> &&callback) : callback(std::move(callback))
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline BasicWorkStdFunc(const AuFunction<void()> &callback) : callback(callback)
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline BasicWorkStdFunc(const AuFunction<void()> &callback, const AuFunction<void()> &shutdown) : callback(callback), shutdown(shutdown)
|
|
||||||
{}
|
|
||||||
|
|
||||||
private:
|
|
||||||
#if !defined(_CPPSHARP)
|
|
||||||
inline void DispatchFrame(ProcessInfo &info) override
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Debug::PrintError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void OnFailure() override
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (shutdown)
|
|
||||||
{
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Debug::PrintError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// @hideinitializer
|
|
||||||
template<typename Frame_t = AuFunction<void()>, typename Cleanup_t = AuFunction<void()>>
|
|
||||||
struct WorkItemCallable : IWorkItemHandler
|
|
||||||
{
|
|
||||||
Frame_t frame;
|
|
||||||
Cleanup_t cleanup;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void DispatchFrame(ProcessInfo &info) override
|
|
||||||
{
|
|
||||||
if constexpr (AuIsBaseOfTemplate<AuFunction, Frame_t>::value)
|
|
||||||
{
|
|
||||||
if (!frame)
|
|
||||||
{
|
|
||||||
info.type = ETickType::eFinished;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
frame();
|
|
||||||
info.type = ETickType::eFinished;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnFailure() override
|
|
||||||
{
|
|
||||||
if constexpr (AuIsBaseOfTemplate<AuFunction, Cleanup_t>::value)
|
|
||||||
{
|
|
||||||
if (!cleanup)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#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(WorkerPId_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(WorkerPId_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
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: TaskFrom.hpp
|
|
||||||
Date: 2021-11-1
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
template<typename Info_t = AVoid, typename Out_t = AVoid, class ClazzImpl>
|
|
||||||
FTask<Info_t, Out_t> TaskFromConsumerRefT(ClazzImpl func)
|
|
||||||
{
|
|
||||||
FTask<Info_t, Out_t> ret;
|
|
||||||
ret.onFrame = [=](const Info_t &in) -> Out_t
|
|
||||||
{
|
|
||||||
if constexpr (AuIsSame_v<Out_t, AVoid>)
|
|
||||||
{
|
|
||||||
func(in);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return func(in);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename ... Args, typename Functor>
|
|
||||||
FTask<AuTuple<Args...>, Out_t> TaskFromTupleCallable(Functor func)
|
|
||||||
{
|
|
||||||
FTask<AuTuple<Args...>, Out_t> ret;
|
|
||||||
ret.onFrame = [=](const AuTuple<Args...> &in) -> Out_t
|
|
||||||
{
|
|
||||||
return AuTupleApply(func, in);
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Out_t = AVoid, typename Owner_t, typename ... Args>
|
|
||||||
FTask<AuTuple<Args...>, Out_t> TaskFromTupleCallableWithOwnerArg(AuFunction<Out_t(Args...)> func, const Owner_t &ownerToPin)
|
|
||||||
{
|
|
||||||
FTask<AuTuple<Owner_t, Args...>, Out_t> ret;
|
|
||||||
ret.onFrame = [ownerToPin, callable = func](const AuTuple<Args...> &in) -> Out_t
|
|
||||||
{
|
|
||||||
return AuTupleApply(callable, AuTupleCat(AuMakeTuple<Owner_t>(ownerToPin), in));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Task_t, typename ReturnValue_t, typename ... Args, typename Functor>
|
|
||||||
Task_t TaskFromTupleCallableWithBindOwner(Functor func)
|
|
||||||
{
|
|
||||||
Task_t ret;
|
|
||||||
ret.onFrame = [=](const auto &in) -> ReturnValue_t
|
|
||||||
{
|
|
||||||
return AuTupleApply(func, AuTuplePopFront(in));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Task_t, typename ReturnValue_t, typename Functor>
|
|
||||||
Task_t TaskFromTupleCallableWithBindOwner2(Functor func)
|
|
||||||
{
|
|
||||||
Task_t ret;
|
|
||||||
ret.onFrame = [=](const auto &in) -> ReturnValue_t
|
|
||||||
{
|
|
||||||
return AuTupleApply(func, AuTuplePopFront(in));
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Out_t = AVoid>
|
|
||||||
FTask<Info_t, Out_t> TaskFromVoidVoid(const AuVoidFunc &func)
|
|
||||||
{
|
|
||||||
FTask<Info_t, Out_t> ret;
|
|
||||||
ret.onFrame = [callable = func](const Info_t &in) -> Out_t
|
|
||||||
{
|
|
||||||
callable();
|
|
||||||
return {};
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: Tasks.hpp
|
|
||||||
Date: 2021-11-1
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
struct ITask
|
|
||||||
{
|
|
||||||
virtual Result_t OnFrame(const Info_t &in) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
struct FTask final : ITask<Info_t, Result_t>
|
|
||||||
{
|
|
||||||
using InfoType_t = Info_t;
|
|
||||||
using ResultType_t = Result_t;
|
|
||||||
|
|
||||||
AuFunction<Result_t(const Info_t &)> onFrame;
|
|
||||||
|
|
||||||
virtual inline Result_t OnFrame(const Info_t &in) const override final
|
|
||||||
{
|
|
||||||
return onFrame(in);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Info_t = AVoid, class Result_t = AVoid>
|
|
||||||
struct CTask final : ITask<Info_t, Result_t>
|
|
||||||
{
|
|
||||||
using InfoType_t = Info_t;
|
|
||||||
using ResultType_t = Result_t;
|
|
||||||
|
|
||||||
Result_t(* onFrame)(const Info_t &) = 0;
|
|
||||||
|
|
||||||
virtual inline Result_t OnFrame(const Info_t &in) const override final
|
|
||||||
{
|
|
||||||
return onFrame(in);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using FVoidTask = FTask<AVoid, AVoid>;
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: WorkBasic.hpp
|
|
||||||
Date: 2021-11-1
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
|
|
||||||
/// --- THREAD POOL --
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a = const Job_t &, class b = Task_t &, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> NewWork(const WorkerPId_tt &worker, a task, b job, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return worker.pool->NewWorkItem(worker, AuMakeShared<WorkPairImpl<Info_t, Result_t, Task_t>>(task, job), enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a = const Job_t &, class b = Task_t &, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> DispatchWork(const WorkerPId_tt &worker, a task, b job, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, task, job, enableWait)->Dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a, class b = Job_t, class c, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> NewWork(const WorkerPId_tt &worker, a task, b job, c info, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return worker.pool->NewWorkItem(worker, AuMakeShared<WorkPairImpl<Info_t, Result_t, Task_t>>(task, job, info), enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a, class b = Job_t, class c, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> DispatchWork(const WorkerPId_tt &worker, a task, b job, c info, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, task, job, info, enableWait)->Dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, typename ClazzImpl, class a = const Job_t &, class b = const Info_t &, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
AuSPtr<IWorkItem> DispatchFunctional(const WorkerPId_tt &worker, ClazzImpl task, a job, b inputParameters, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, TaskFromConsumerRefT<Info_t, Result_t>(task), job, inputParameters, enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, typename ClazzImpl, class a = const Job_t &, class b = const Info_t &, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
AuSPtr<IWorkItem> DispatchFunctor(const WorkerPId_tt &worker, ClazzImpl task, a job, b inputParameters, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, TaskFromConsumerRefT<Info_t, Result_t>(task), job, inputParameters, enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, typename ClazzImpl, class a = const Job_t &, class b = const Info_t &, class WorkerPId_tt = WorkerPId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerPId_tt, WorkerPId_t>)>
|
|
||||||
AuSPtr<IWorkItem> DispatchVoid(const WorkerPId_tt &worker, ClazzImpl task, a job, b inputParameters, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, TaskFromVoidVoid<Info_t, Result_t>(task), job, inputParameters, enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// --- ASYNC APP --
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a = const Job_t &, class b = Task_t &, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> NewWork(const WorkerId_tt &worker, a task, b job, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWorkItem(worker, AuMakeShared<WorkPairImpl<Info_t, Result_t, Task_t>>(task, job), enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a = const Job_t &, class b = Task_t &, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> DispatchWork(const WorkerId_tt &worker, a task, b job, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, task, job, enableWait)->Dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a, class b = Job_t, class c, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> NewWork(const WorkerId_tt &worker, a task, b job, c info, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWorkItem(worker, AuMakeShared<WorkPairImpl<Info_t, Result_t, Task_t>>(task, job, info), enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, class a, class b = Job_t, class c, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
static AuSPtr<IWorkItem> DispatchWork(const WorkerId_tt &worker, a task, b job, c info, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, task, job, info, enableWait)->Dispatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, typename ClazzImpl, class a = const Job_t &, class b = const Info_t &, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
AuSPtr<IWorkItem> DispatchFunctional(const WorkerId_tt &worker, ClazzImpl task, a job, b inputParameters, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, TaskFromConsumerRefT<Info_t, Result_t>(task), job, inputParameters, enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, typename ClazzImpl, class a = const Job_t &, class b = const Info_t &, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
AuSPtr<IWorkItem> DispatchFunctor(const WorkerId_tt &worker, ClazzImpl task, a job, b inputParameters, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, TaskFromConsumerRefT<Info_t, Result_t>(task), job, inputParameters, enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>, typename ClazzImpl, class a = const Job_t &, class b = const Info_t &, class WorkerId_tt = WorkerId_t, AU_TEMPLATE_ENABLE_WHEN(AuIsSame_v<WorkerId_tt, WorkerId_t>)>
|
|
||||||
AuSPtr<IWorkItem> DispatchVoid(const WorkerId_t &worker, ClazzImpl task, a job, b inputParameters, bool enableWait = false)
|
|
||||||
{
|
|
||||||
return NewWork<Info_t, Result_t, Task_t, Job_t>(worker, TaskFromVoidVoid<Info_t, Result_t>(task), job, inputParameters, enableWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename ... Args, class Clazz_t, class FunctorTask_t, class FuckYou_t >
|
|
||||||
static AuSPtr<IWorkItem> DispathSmartWork(const WorkerId_t &worker, AuSPtr<Clazz_t> owner, FunctorTask_t task, FuckYou_t job, Args ... in)
|
|
||||||
{
|
|
||||||
return DispatchWork<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t>(worker,
|
|
||||||
TaskFromTupleCallableWithBindOwner2<FTask<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t>, ReturnValue_t, FunctorTask_t>(task),
|
|
||||||
Async::JobFromTupleClazz<ReturnValue_t, AuSPtr<Clazz_t>, Args...>(job),
|
|
||||||
AuMakeTuple<AuSPtr<Clazz_t>, Args...>(AU_FWD(owner), AuForward<Args>(in)...),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ReturnValue_t = void, typename ... Args, class Clazz_t, class FunctorTask_t, class FuckYou_t, class FuckYou2_t >
|
|
||||||
static AuSPtr<IWorkItem> DispathSmartWorkEx(const WorkerId_t &worker, AuSPtr<Clazz_t> owner, FunctorTask_t task, FuckYou_t success, FuckYou2_t failure, Args ... in)
|
|
||||||
{
|
|
||||||
return DispatchWork<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t>(worker,
|
|
||||||
TaskFromTupleCallableWithBindOwner2<FTask<AuTuple<AuSPtr<Clazz_t>, Args...>, ReturnValue_t>, ReturnValue_t, FunctorTask_t>(task),
|
|
||||||
Async::JobFromTupleClazzEx<ReturnValue_t, AuSPtr<Clazz_t>, Args...>(success, failure),
|
|
||||||
AuMakeTuple<AuSPtr<Clazz_t>, Args...>(AU_FWD(owner), AuForward<Args>(in)...),
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,226 +0,0 @@
|
|||||||
/***
|
|
||||||
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
||||||
|
|
||||||
File: WorkPairImpl.hpp
|
|
||||||
Date: 2021-11-1
|
|
||||||
Author: Reece
|
|
||||||
***/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Aurora::Threading::Primitives
|
|
||||||
{
|
|
||||||
class SpinLoop;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Aurora::Async
|
|
||||||
{
|
|
||||||
struct BasicWorkStdFunc;
|
|
||||||
|
|
||||||
/// @hideinitializer
|
|
||||||
struct BasicWorkCtx : WorkPriv
|
|
||||||
{
|
|
||||||
BasicWorkCtx()
|
|
||||||
{
|
|
||||||
magic = AuConvertMagicTag32("BWOT");
|
|
||||||
opt = nullptr;
|
|
||||||
}
|
|
||||||
void *opt;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @hideinitializer
|
|
||||||
template<typename Info_t = AVoid, typename Result_t = AVoid, typename Task_t = FTask<Info_t, Result_t>, typename Job_t = FJob<Info_t, Result_t>>
|
|
||||||
struct WorkPairImpl : IWorkItemHandler, AuEnableSharedFromThis<IWorkItemHandler>
|
|
||||||
{
|
|
||||||
WorkPairImpl() : caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(Task_t &&task) : task(AuMove(task)), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(Task_t &&task, Job_t &&callback) : task(AuMove(task)), callback(AuMove(callback)), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(const Task_t &task) : task(task), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(const Task_t &task, const Job_t &callback) : task(task), callback(callback), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(const Task_t &task, const Job_t &callback, const Info_t &info) : task(task), callback(callback), input(info), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(Task_t &&task, const Job_t &callback, const Info_t &info) : task(AuMove(task)), callback(callback), input(info), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(Task_t &&task, Job_t &&callback, const Info_t &info) : task(AuMove(task)), callback(AuMove(callback)), input(info), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(Task_t &&task, Job_t &&callback, Info_t &&info) : task(AuMove(task)), callback(AuMove(callback)), input(AuMove(info)), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
WorkPairImpl(const Task_t &task, const Job_t &callback, Info_t &&info) : task(task), callback(callback), input(info), caller_(Async::GetCurrentWorkerPId())
|
|
||||||
{}
|
|
||||||
|
|
||||||
Info_t input;
|
|
||||||
Task_t task;
|
|
||||||
Job_t callback;
|
|
||||||
|
|
||||||
|
|
||||||
WorkPairImpl<Info_t, Result_t, Task_t, Job_t> &SetTask(const Task_t &task)
|
|
||||||
{
|
|
||||||
this->task = task;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkPairImpl<Info_t, Result_t, Task_t, Job_t> &SetTask(const Job_t &callback)
|
|
||||||
{
|
|
||||||
this->callback = callback;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
static constexpr bool IsCallbackPtr = AuIsPointer_v<Job_t> || AuIsBaseOfTemplate<AURORA_RUNTIME_AU_SHARED_PTR, Job_t >::value || AuIsBaseOfTemplate<AURORA_RUNTIME_AU_UNIQUE_PTR, Job_t>::value;
|
|
||||||
static constexpr bool IsTaskPtr = AuIsPointer_v<Task_t> || AuIsBaseOfTemplate<AURORA_RUNTIME_AU_SHARED_PTR, Task_t>::value || AuIsBaseOfTemplate<AURORA_RUNTIME_AU_UNIQUE_PTR, Task_t>::value;
|
|
||||||
|
|
||||||
//WorkerId_t caller;
|
|
||||||
WorkerPId_t caller_;
|
|
||||||
Threading::Primitives::SpinLock lock_;
|
|
||||||
|
|
||||||
BasicWorkCtx secretContext_;
|
|
||||||
Result_t resultValue_;
|
|
||||||
|
|
||||||
virtual void *GetPrivateData() override { return &secretContext_; }
|
|
||||||
|
|
||||||
void DispatchFrame(ProcessInfo &info) override
|
|
||||||
{
|
|
||||||
AU_LOCK_GUARD(this->lock_);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if constexpr (IsTaskPtr)
|
|
||||||
{
|
|
||||||
if (task)
|
|
||||||
{
|
|
||||||
resultValue_ = task->OnFrame(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resultValue_ = task.OnFrame(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
task = {};
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Debug::PrintError();
|
|
||||||
ShutdownNoLock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pin = AuSharedFromThis();
|
|
||||||
AuFunction<void()> func = [pin]()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pin->secretContext_.opt = &pin->resultValue_;
|
|
||||||
if constexpr (IsCallbackPtr)
|
|
||||||
{
|
|
||||||
pin->callback->onSuccess(pin->input, pin->resultValue_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pin->callback.onSuccess)
|
|
||||||
{
|
|
||||||
pin->callback.onSuccess(pin->input,pin->resultValue_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Debug::PrintError();
|
|
||||||
}
|
|
||||||
|
|
||||||
pin->callback = {};
|
|
||||||
pin->caller_ = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (caller_ == Async::GetCurrentWorkerPId())
|
|
||||||
{
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuFunction<void()> err = [pin]()
|
|
||||||
{
|
|
||||||
pin->CallOnFailure();
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: this is somewhat evil. double alloc when we could reuse this
|
|
||||||
if (!caller_.pool->NewWorkItem(caller_, AuMakeShared<BasicWorkStdFunc>(func, err))->Dispatch())
|
|
||||||
{
|
|
||||||
pin->CallOnFailure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
caller_ = {};
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Debug::PrintError();
|
|
||||||
ShutdownNoLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnFailure() override
|
|
||||||
{
|
|
||||||
AU_LOCK_GUARD(this->lock_);
|
|
||||||
ShutdownNoLock();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ShutdownNoLock()
|
|
||||||
{
|
|
||||||
caller_ = {};
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CallOnFailure();
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Debug::PrintError();
|
|
||||||
}
|
|
||||||
callback = {};
|
|
||||||
task = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CallOnFailure()
|
|
||||||
{
|
|
||||||
if constexpr (IsCallbackPtr)
|
|
||||||
{
|
|
||||||
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_FUNC, decltype(callback->onFailure)>::value)
|
|
||||||
{
|
|
||||||
if (!callback->onFailure)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callback->onFailure(input);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_FUNC, decltype(callback.onFailure)>::value)
|
|
||||||
{
|
|
||||||
if (!callback.onFailure)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback.onFailure(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -173,7 +173,7 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
if (!AuExchange(gLockedPump, true))
|
if (!AuExchange(gLockedPump, true))
|
||||||
{
|
{
|
||||||
NewWorkItem(gMainThread.value(), AuMakeShared<BasicWorkStdFunc>(PumpSysThread))->Dispatch();
|
DispatchOn(gMainThread.value(), PumpSysThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
SchedNextTime(AuMSToNS<AuUInt64>(gRuntimeConfig.async.dwLegacyMainThreadSystemTickMS) + AuTime::SteadyClockNS());
|
SchedNextTime(AuMSToNS<AuUInt64>(gRuntimeConfig.async.dwLegacyMainThreadSystemTickMS) + AuTime::SteadyClockNS());
|
||||||
|
@ -998,14 +998,11 @@ namespace Aurora::Async
|
|||||||
AuSPtr<AuThreads::IThreadFeature> pFeature,
|
AuSPtr<AuThreads::IThreadFeature> pFeature,
|
||||||
bool bNonBlock)
|
bool bNonBlock)
|
||||||
{
|
{
|
||||||
auto work = AuMakeSharedThrow<BasicWorkStdFunc>(([=]()
|
auto pWorkItem = DispatchOn({ this->SharedFromThis(), id }, [=]()
|
||||||
{
|
{
|
||||||
GetThreadState()->features.push_back(pFeature);
|
GetThreadState()->features.push_back(pFeature);
|
||||||
pFeature->Init();
|
pFeature->Init();
|
||||||
}));
|
});
|
||||||
|
|
||||||
auto pWorkItem = this->NewWorkItem(id, work)->Dispatch();
|
|
||||||
SysAssert(pWorkItem);
|
|
||||||
|
|
||||||
if (!bNonBlock)
|
if (!bNonBlock)
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,7 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
WorkItem::~WorkItem()
|
WorkItem::~WorkItem()
|
||||||
{
|
{
|
||||||
|
|
||||||
//Fail();
|
//Fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +269,6 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
if (this->task_)
|
if (this->task_)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this->task_->DispatchFrame(info);
|
this->task_->DispatchFrame(info);
|
||||||
@ -306,20 +306,7 @@ namespace Aurora::Async
|
|||||||
IWorkItemHandler::ProcessInfo info(true);
|
IWorkItemHandler::ProcessInfo info(true);
|
||||||
info.pool = this->owner_->ToThreadPool();
|
info.pool = this->owner_->ToThreadPool();
|
||||||
|
|
||||||
if (this->task_)
|
DispatchTask(info);
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this->task_->DispatchFrame(info);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
// TODO: runtime config for root level exception caught behaviour
|
|
||||||
SysPushErrorCatch();
|
|
||||||
Fail();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AU_LOCK_GUARD(this->lock);
|
AU_LOCK_GUARD(this->lock);
|
||||||
RunAsyncLocked2(info);
|
RunAsyncLocked2(info);
|
||||||
@ -417,7 +404,12 @@ namespace Aurora::Async
|
|||||||
bool WorkItem::BlockUntilComplete()
|
bool WorkItem::BlockUntilComplete()
|
||||||
{
|
{
|
||||||
if (!this->finishedEvent_) return false;
|
if (!this->finishedEvent_) return false;
|
||||||
return this->owner_->WaitFor(this->worker_, AuUnsafeRaiiToShared(this->finishedEvent_.AsPointer()), 0);
|
if (!this->worker_)
|
||||||
|
{
|
||||||
|
this->finishedEvent_->Wait();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
return this->owner_->WaitFor(this->worker_.value(), AuUnsafeRaiiToShared(this->finishedEvent_.AsPointer()), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorkItem::HasFinished()
|
bool WorkItem::HasFinished()
|
||||||
@ -438,19 +430,19 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
bool WorkItem::Schedule()
|
bool WorkItem::Schedule()
|
||||||
{
|
{
|
||||||
return Async::Schedule(this->dispatchTimeNs_, this->owner_, this->worker_, AuSharedFromThis());
|
return Async::Schedule(this->dispatchTimeNs_, this->owner_, this->worker_.value(), AuSharedFromThis());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkItem::SendOff()
|
void WorkItem::SendOff()
|
||||||
{
|
{
|
||||||
if (!this->task_)
|
if (!this->worker_)
|
||||||
{
|
{
|
||||||
// If we aren't actually calling a task interface, we may as well just dispatch objects waiting on us from here
|
// If we aren't actually calling a task interface, we may as well just dispatch objects waiting on us from here
|
||||||
RunAsyncLocked2();
|
RunAsyncLocked2();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->owner_->Run(this->worker_, AuSharedFromThis());
|
this->owner_->Run(this->worker_.value(), AuSharedFromThis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,26 +545,4 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
return this->task_->GetPrivateData();
|
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 {};
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -45,7 +45,6 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
|
|
||||||
void *GetPrivateData() override;
|
void *GetPrivateData() override;
|
||||||
AuOptional<void *> ToWorkResultT() override;
|
|
||||||
|
|
||||||
EWorkPrio GetPrio() override;
|
EWorkPrio GetPrio() override;
|
||||||
void SetPrio(EWorkPrio prio) override;
|
void SetPrio(EWorkPrio prio) override;
|
||||||
@ -62,7 +61,7 @@ namespace Aurora::Async
|
|||||||
virtual void DispatchTask(IWorkItemHandler::ProcessInfo &info);
|
virtual void DispatchTask(IWorkItemHandler::ProcessInfo &info);
|
||||||
|
|
||||||
AuSPtr<IWorkItemHandler> task_;
|
AuSPtr<IWorkItemHandler> task_;
|
||||||
WorkerPId_t worker_;
|
AuOptionalEx<WorkerPId_t> worker_;
|
||||||
EWorkPrio prio_ = EWorkPrio::eNormalPrio;
|
EWorkPrio prio_ = EWorkPrio::eNormalPrio;
|
||||||
AuList<AuSPtr<IWorkItem>> waitOn_;
|
AuList<AuSPtr<IWorkItem>> waitOn_;
|
||||||
AuList<AuSPtr<IWorkItem>> waiters_;
|
AuList<AuSPtr<IWorkItem>> waiters_;
|
||||||
|
@ -175,7 +175,7 @@ namespace Aurora::Console::Commands
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NewWorkItem(gCommandDispatcher.value(), AuMakeShared<Async::BasicWorkStdFunc>(func))->Dispatch()->BlockUntilComplete();
|
DispatchOn(gCommandDispatcher.value(), func)->BlockUntilComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user