From 160255f96e46818b6df63b00f17f502df9ab0a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Fri, 3 Apr 2015 17:55:23 +0200 Subject: Async: move as much Future code as possible from public header to .cpp --- async/src/future.cpp | 92 ++++++++++++++++++++++++++++++---- async/src/future.h | 136 ++++++++++++++++++++------------------------------- 2 files changed, 135 insertions(+), 93 deletions(-) (limited to 'async/src') diff --git a/async/src/future.cpp b/async/src/future.cpp index 50a326a..970060b 100644 --- a/async/src/future.cpp +++ b/async/src/future.cpp @@ -20,11 +20,41 @@ using namespace Async; +FutureBase::PrivateBase::PrivateBase(const Private::ExecutionPtr &execution) + : finished(false) + , errorCode(0) + , mExecution(execution) +{ +} + +FutureBase::PrivateBase::~PrivateBase() +{ + Private::ExecutionPtr executionPtr = mExecution.toStrongRef(); + if (executionPtr) { + executionPtr->releaseFuture(); + releaseExecution(); + } +} + +void FutureBase::PrivateBase::releaseExecution() +{ + mExecution.clear(); +} + + + FutureBase::FutureBase() + : d(nullptr) +{ +} + +FutureBase::FutureBase(FutureBase::PrivateBase *dd) + : d(dd) { } FutureBase::FutureBase(const Async::FutureBase &other) + : d(other.d) { } @@ -32,35 +62,77 @@ FutureBase::~FutureBase() { } -FutureBase::PrivateBase::PrivateBase(const Private::ExecutionPtr &execution) - : mExecution(execution) +void FutureBase::releaseExecution() { + d->releaseExecution(); } -FutureBase::PrivateBase::~PrivateBase() +void FutureBase::setFinished() { - Private::ExecutionPtr executionPtr = mExecution.toStrongRef(); - if (executionPtr) { - executionPtr->releaseFuture(); - releaseExecution(); + if (isFinished()) { + return; + } + d->finished = true; + for (auto watcher : d->watchers) { + if (watcher) { + watcher->futureReadyCallback(); + } } } -void FutureBase::PrivateBase::releaseExecution() +bool FutureBase::isFinished() const { - mExecution.clear(); + return d->finished; +} + +void FutureBase::setError(int code, const QString &message) +{ + d->errorCode = code; + d->errorMessage = message; + setFinished(); +} + +int FutureBase::errorCode() const +{ + return d->errorCode; +} + +QString FutureBase::errorMessage() const +{ + return d->errorMessage; } +void FutureBase::addWatcher(FutureWatcherBase* watcher) +{ + d->watchers.append(QPointer(watcher)); +} + + + + FutureWatcherBase::FutureWatcherBase(QObject *parent) : QObject(parent) + , d(new FutureWatcherBase::Private) { } FutureWatcherBase::~FutureWatcherBase() { + delete d; } +void FutureWatcherBase::futureReadyCallback() +{ + Q_EMIT futureReady(); +} -#include "future.moc" +void FutureWatcherBase::setFutureImpl(const FutureBase &future) +{ + d->future = future; + d->future.addWatcher(this); + if (future.isFinished()) { + futureReadyCallback(); + } +} diff --git a/async/src/future.h b/async/src/future.h index cadd96d..bc18f00 100644 --- a/async/src/future.h +++ b/async/src/future.h @@ -29,28 +29,32 @@ class QEventLoop; namespace Async { +class FutureWatcherBase; +template +class FutureWatcher; + namespace Private { class Execution; class ExecutorBase; typedef QSharedPointer ExecutionPtr; - -} +} // namespace Private class FutureBase { friend class Async::Private::Execution; + friend class FutureWatcherBase; public: virtual ~FutureBase(); - virtual void setFinished() = 0; - virtual bool isFinished() const = 0; - virtual void setError(int code = 1, const QString &message = QString()) = 0; + void setFinished(); + bool isFinished() const; + void setError(int code = 1, const QString &message = QString()); + int errorCode() const; + QString errorMessage() const; protected: - virtual void releaseExecution() = 0; - class PrivateBase : public QSharedData { public: @@ -59,12 +63,24 @@ protected: void releaseExecution(); + bool finished; + int errorCode; + QString errorMessage; + + QVector> watchers; private: QWeakPointer mExecution; }; FutureBase(); + FutureBase(FutureBase::PrivateBase *dd); FutureBase(const FutureBase &other); + + void addWatcher(Async::FutureWatcherBase *watcher); + void releaseExecution(); + +protected: + QExplicitlySharedDataPointer d; }; template @@ -79,41 +95,6 @@ class FutureGeneric : public FutureBase friend class FutureWatcher; public: - void setFinished() - { - if (d->finished) { - return; - } - d->finished = true; - for (auto watcher : d->watchers) { - if (watcher) { - watcher->futureReadyCallback(); - } - } - } - - bool isFinished() const - { - return d->finished; - } - - void setError(int errorCode, const QString &message) - { - d->errorCode = errorCode; - d->errorMessage = message; - setFinished(); - } - - int errorCode() const - { - return d->errorCode; - } - - QString errorMessage() const - { - return d->errorMessage; - } - void waitForFinished() { if (isFinished()) { @@ -129,46 +110,27 @@ public: protected: FutureGeneric(const Async::Private::ExecutionPtr &execution) - : FutureBase() - , d(new Private(execution)) + : FutureBase(new Private(execution)) {} FutureGeneric(const FutureGeneric &other) : FutureBase(other) - , d(other.d) {} +protected: class Private : public FutureBase::PrivateBase { public: Private(const Async::Private::ExecutionPtr &execution) : FutureBase::PrivateBase(execution) - , finished(false) - , errorCode(0) {} typename std::conditional::value, int /* dummy */, T>::type value; - - QVector>> watchers; - bool finished; - int errorCode; - QString errorMessage; }; - - QExplicitlySharedDataPointer d; - - void releaseExecution() - { - d->releaseExecution(); - } - - void addWatcher(FutureWatcher *watcher) - { - d->watchers.append(QPointer>(watcher)); - } }; + template class Future : public FutureGeneric { @@ -188,12 +150,12 @@ public: void setValue(const T &value) { - this->d->value = value; + static_cast::Private*>(this->d.data())->value = value; } T value() const { - return this->d->value; + return static_cast::Private*>(this->d.data())->value; } protected: @@ -208,9 +170,6 @@ class Future : public FutureGeneric { friend class Async::Private::ExecutorBase; - template - friend class Async::FutureWatcher; - public: Future() : FutureGeneric(Async::Private::ExecutionPtr()) @@ -227,16 +186,36 @@ protected: }; + + + class FutureWatcherBase : public QObject { Q_OBJECT + friend class FutureBase; + +Q_SIGNALS: + void futureReady(); + protected: FutureWatcherBase(QObject *parent = nullptr); virtual ~FutureWatcherBase(); -Q_SIGNALS: - void futureReady(); + void futureReadyCallback(); + + void setFutureImpl(const Async::FutureBase &future); + +protected: + class Private { + public: + Async::FutureBase future; + }; + + Private * const d; + +private: + Q_DISABLE_COPY(FutureWatcherBase); }; template @@ -254,25 +233,16 @@ public: void setFuture(const Async::Future &future) { - mFuture = future; - mFuture.addWatcher(this); - if (future.isFinished()) { - futureReadyCallback(); - } + setFutureImpl(*static_cast(&future)); } Async::Future future() const { - return mFuture; + return *static_cast*>(&d->future); } private: - void futureReadyCallback() - { - Q_EMIT futureReady(); - } - - Async::Future mFuture; + Q_DISABLE_COPY(FutureWatcher); }; } // namespace Async -- cgit v1.2.3