[+] Futures with an error value
[+] Added (made public) AuFuture::CompleteCallback_f [+] Added (made public) AuFuture::ErrorCallback_f
This commit is contained in:
parent
7cf042d99c
commit
26f581736a
@ -7,8 +7,8 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
template<typename T>
|
||||
struct AuFuture : AuEnableSharedFromThis<AuFuture<T>>
|
||||
template<typename T, typename Error_t = void>
|
||||
struct AuFuture : AuEnableSharedFromThis<AuFuture<T, Error_t>>
|
||||
{
|
||||
private:
|
||||
template <typename A>
|
||||
@ -27,8 +27,13 @@ private:
|
||||
|
||||
|
||||
using Move_t = AuConditional_t<AuIsVoid_v<T>, typename CppFun<T>::B &&, T>;
|
||||
using CompleteCallback_f = AuConditional_t<AuIsVoid_v<T>, AuVoidFunc, AuConsumer<Move_t>>;
|
||||
using Move2_t = AuConditional_t<AuIsVoid_v<Error_t>, typename CppFun<Error_t>::B &&, Error_t>;
|
||||
using ErrorStore_t = AuConditional_t<AuIsVoid_v<Error_t>, typename CppFun<Error_t>::B, Error_t>;
|
||||
public:
|
||||
|
||||
using CompleteCallback_f = AuConditional_t<AuIsVoid_v<T>, AuVoidFunc, AuConsumer<Move_t>>;
|
||||
using ErrorCallback_f = AuConditional_t<AuIsVoid_v<Error_t>, AuVoidFunc, AuConsumer<Move2_t>>;
|
||||
|
||||
AU_NO_COPY_NO_MOVE(AuFuture);
|
||||
|
||||
void OnComplete(CompleteCallback_f callback)
|
||||
@ -38,6 +43,7 @@ public:
|
||||
if (this->bComplete)
|
||||
{
|
||||
SysAssert(!AuExchange(this->bDoneCb, true), "Future has already called a completion callback");
|
||||
|
||||
if constexpr (AuIsVoid_v<T>)
|
||||
{
|
||||
callback();
|
||||
@ -64,14 +70,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void OnFailure(AuVoidFunc onFailure)
|
||||
void OnFailure(ErrorCallback_f onFailure)
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex);
|
||||
|
||||
if (this->bFailed)
|
||||
{
|
||||
SysAssert(!AuExchange(this->bDoneCb, true), "Future has already called a completion callback");
|
||||
onFailure();
|
||||
|
||||
if constexpr (AuIsVoid_v<Error_t>)
|
||||
{
|
||||
onFailure();
|
||||
}
|
||||
else
|
||||
{
|
||||
onFailure(this->errorValue);
|
||||
}
|
||||
|
||||
DoWaterFalls();
|
||||
return;
|
||||
}
|
||||
@ -112,6 +127,19 @@ public:
|
||||
SubmitComplete();
|
||||
}
|
||||
|
||||
template<typename T1 = Error_t, AuEnableIf_t<!AuIsVoid_v<T1>> * = nullptr>
|
||||
void Fail(Move2_t error)
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex);
|
||||
SysAssert(!AuExchange(this->bDone, true), "Future has already finished");
|
||||
|
||||
this->errorValue = AuMove(error);
|
||||
this->bFailed = true;
|
||||
|
||||
SubmitComplete();
|
||||
}
|
||||
|
||||
template<typename T1 = Error_t, AuEnableIf_t<AuIsVoid_v<T1>> * = nullptr>
|
||||
void Fail()
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex);
|
||||
@ -122,26 +150,26 @@ public:
|
||||
SubmitComplete();
|
||||
}
|
||||
|
||||
static AuSPtr<AuFuture<T>> New()
|
||||
static AuSPtr<AuFuture<T, Error_t>> New()
|
||||
{
|
||||
AuDebug::AddMemoryCrunch();
|
||||
auto pRet = AuSPtr<AuFuture<T>>(new AuFuture(), AuDefaultDeleter<AuFuture<T>> {});
|
||||
auto pRet = AuSPtr<AuFuture<T, Error_t>>(new AuFuture(), AuDefaultDeleter<AuFuture<T, Error_t>> {});
|
||||
AuDebug::DecMemoryCrunch();
|
||||
return pRet;
|
||||
}
|
||||
|
||||
static AuSPtr<AuFuture<T>> New(AuConsumer<Move_t> callback)
|
||||
static AuSPtr<AuFuture<T, Error_t>> New(AuConsumer<Move_t> callback)
|
||||
{
|
||||
AuDebug::AddMemoryCrunch();
|
||||
auto pRet = AuSPtr<AuFuture<T>>(new AuFuture(callback), AuDefaultDeleter<AuFuture<T>> {});
|
||||
auto pRet = AuSPtr<AuFuture<T, Error_t>>(new AuFuture(callback), AuDefaultDeleter<AuFuture<T, Error_t>> {});
|
||||
AuDebug::DecMemoryCrunch();
|
||||
return pRet;
|
||||
}
|
||||
|
||||
static AuSPtr<AuFuture<T>> New(AuConsumer<Move_t> callback, AuVoidFunc onFailure)
|
||||
static AuSPtr<AuFuture<T, Error_t>> New(AuConsumer<Move_t> callback, ErrorCallback_f onFailure)
|
||||
{
|
||||
AuDebug::AddMemoryCrunch();
|
||||
auto pRet = AuSPtr<AuFuture<T>>(new AuFuture(callback, onFailure), AuDefaultDeleter<AuFuture<T>> {});
|
||||
auto pRet = AuSPtr<AuFuture<T, Error_t>>(new AuFuture(callback, onFailure), AuDefaultDeleter<AuFuture<T, Error_t>> {});
|
||||
AuDebug::DecMemoryCrunch();
|
||||
return pRet;
|
||||
}
|
||||
@ -178,7 +206,14 @@ private:
|
||||
{
|
||||
if (auto callback = AuExchange(this->onFailure, {}))
|
||||
{
|
||||
callback();
|
||||
if constexpr (AuIsVoid_v<Error_t>)
|
||||
{
|
||||
callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(this->errorValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,15 +272,16 @@ private:
|
||||
this->pid = AuAsync::GetCurrentWorkerPId();
|
||||
}
|
||||
|
||||
AuFuture(AuConsumer<Move_t> callback, AuVoidFunc onFailure) : callback(callback), onFailure(onFailure)
|
||||
AuFuture(AuConsumer<Move_t> callback, ErrorCallback_f onFailure) : callback(callback), onFailure(onFailure)
|
||||
{
|
||||
this->pid = AuAsync::GetCurrentWorkerPId();
|
||||
}
|
||||
|
||||
CppFun<T>::B value;
|
||||
ErrorStore_t errorValue;
|
||||
AuThreadPrimitives::Mutex mutex;
|
||||
CompleteCallback_f callback;
|
||||
AuVoidFunc onFailure;
|
||||
ErrorCallback_f onFailure;
|
||||
AuOptionalEx<AuAsync::WorkerPId_t> pid; // todo: make weak?
|
||||
bool bComplete {};
|
||||
bool bFailed {};
|
||||
@ -256,8 +292,8 @@ private:
|
||||
friend struct AuWaterfall;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using AuSharedFuture = AuSPtr<AuFuture<T>>;
|
||||
template<typename T, typename Error_t = void>
|
||||
using AuSharedFuture = AuSPtr<AuFuture<T, Error_t>>;
|
||||
|
||||
struct AuWaterfall : AuEnableSharedFromThis<AuWaterfall>
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user