AUI Framework  develop
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
AComplexFutureOperation.h
    1#pragma once
    2
    3#include "AFuture.h"
    4#include "AAsyncHolder.h"
    5
   19template<typename T>
   20class AComplexFutureOperation {
   21public:
   22    class NoValueException: AException {
   23    public:
   24        NoValueException(): AException("no value") {}
   25    };
   26
   27    AComplexFutureOperation(): mFutureWeakReference(mFutureStrongReference.inner().weak()) {}
   28
   29    ~AComplexFutureOperation() {
   30        AUI_ASSERTX(mFutureStrongReference.inner() == nullptr, "makeFuture() is not called. Please check docs");
   31        if (auto f = mFutureWeakReference.lock()) {
   32            if (!(*f)->hasResult()) {
   33                try {
   34                    throw NoValueException();
   35                } catch (...) {
   36                    (*f)->reportException();
   37                }
   38            }
   39        }
   40    }
   41
   47    [[nodiscard]]
   48    AFuture<T> makeFuture() noexcept {
   49        auto r = std::move(mFutureStrongReference);
   50        AUI_ASSERT(mFutureStrongReference.inner() == nullptr);
   51        return r;
   52    }
   53
   61    template<typename OtherT>
   62    AComplexFutureOperation& operator<<(AFuture<OtherT> rhs) {
   63        rhs.onError([weakRef = mFutureWeakReference](const AException& e) {
   64            if (auto f = weakRef.lock()) {
   65                if ((*f)->hasResult()) {
   66                    return;
   67                }
   68                try {
   69                    throw e;
   70                } catch (...) {
   71                    (*f)->reportException();
   72                }
   73            }
   74        });
   75        mAsyncHolder << std::move(rhs);
   76        return *this;
   77    }
   78
   83    void supplyValue(T value) {
   84        if (auto l = mFutureWeakReference.lock()) {
   85            auto& inner = *l;
   86            std::unique_lock lock(inner->mutex);
   87            inner->value = std::move(value);
   88            inner->cv.notify_all();
   89            inner->notifyOnSuccessCallback(lock);
   90        }
   91    }
   92
   96    void supplyException() {
   97        if (auto l = mFutureWeakReference.lock()) {
   98            auto& inner = *l;
   99            inner->reportException();
  100        }
  101    }
  102
  103private:
  104    AFuture<T> mFutureStrongReference;
  105    AAsyncHolder mAsyncHolder;
  106
  107    /*
  108     * Avoid holding a strong reference - we need to keep future cancellation on reference count exceeding
  109     * even while actual future execution.
  110     */
  111    _weak<typename AFuture<T>::Inner> mFutureWeakReference;
  112};
Holds a set of futures keeping them valid.
Definition AAsyncHolder.h:31
Helper class to construct AFuture values.
Definition AComplexFutureOperation.h:20
AComplexFutureOperation & operator<<(AFuture< OtherT > rhs)
Adds a direct dependency on other AFuture<T>.
Definition AComplexFutureOperation.h:62
void supplyException()
Pushes the result of operation to it's AFuture<T>.
Definition AComplexFutureOperation.h:96
void supplyValue(T value)
Pushes the result of operation to it's AFuture<T>.
Definition AComplexFutureOperation.h:83
AFuture< T > makeFuture() noexcept
Creates AFuture<T> object for this operation.
Definition AComplexFutureOperation.h:48
Abstract AUI exception.
Definition AException.h:28
Represents a value that will be available at some point in the future.
Definition AFuture.h:621
const AFuture & onError(Callback &&callback) const noexcept
Add onError callback to the future.
Definition AFuture.h:734
#define AUI_ASSERT(condition)
Asserts that the passed condition evaluates to true.
Definition Assert.h:55
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition Assert.h:74
An std::weak_ptr with AUI extensions.
Definition SharedPtrTypes.h:52