[Telepathy-commits] [telepathy-qt4/master] PendingOperation: add an abstract base class for pending operations, and a trivial subclass
Simon McVittie
simon.mcvittie at collabora.co.uk
Mon Dec 1 06:33:04 PST 2008
---
TelepathyQt4/Client/PendingOperation | 6 +
TelepathyQt4/Makefile.am | 6 +-
TelepathyQt4/cli-pending-operation.cpp | 158 ++++++++++++++++++++++++++++++
TelepathyQt4/cli-pending-operation.h | 165 ++++++++++++++++++++++++++++++++
4 files changed, 334 insertions(+), 1 deletions(-)
create mode 100644 TelepathyQt4/Client/PendingOperation
create mode 100644 TelepathyQt4/cli-pending-operation.cpp
create mode 100644 TelepathyQt4/cli-pending-operation.h
diff --git a/TelepathyQt4/Client/PendingOperation b/TelepathyQt4/Client/PendingOperation
new file mode 100644
index 0000000..9ac8eba
--- /dev/null
+++ b/TelepathyQt4/Client/PendingOperation
@@ -0,0 +1,6 @@
+#ifndef _TelepathyQt4_Client_PendingOperation_HEADER_GUARD_
+#define _TelepathyQt4_Client_PendingOperation_HEADER_GUARD_
+
+#include <TelepathyQt4/cli-pending-operation.h>
+
+#endif
diff --git a/TelepathyQt4/Makefile.am b/TelepathyQt4/Makefile.am
index 93363fc..d2ca9bf 100644
--- a/TelepathyQt4/Makefile.am
+++ b/TelepathyQt4/Makefile.am
@@ -42,6 +42,7 @@ libtelepathy_qt4_la_SOURCES = \
cli-media-session-handler.cpp \
cli-media-stream-handler.cpp \
cli-optional-interface-factory.cpp \
+ cli-pending-operation.cpp \
cli-properties.cpp \
debug.cpp \
debug-internal.hpp \
@@ -67,7 +68,8 @@ nodist_libtelepathy_qt4_la_SOURCES = \
_gen/cli-properties.moc.hpp \
_gen/types-body.hpp \
cli-channel.moc.hpp \
- cli-connection.moc.hpp
+ cli-connection.moc.hpp \
+ cli-pending-operation.moc.hpp
tpqt4include_HEADERS = \
Constants \
@@ -80,6 +82,7 @@ tpqt4include_HEADERS = \
cli-media-session-handler.h \
cli-media-stream-handler.h \
cli-optional-interface-factory.h \
+ cli-pending-operation.h \
cli-properties.h \
constants.h \
debug.h \
@@ -94,6 +97,7 @@ tpqt4clientinclude_HEADERS = \
Client/MediaSessionHandler \
Client/MediaStreamHandler \
Client/OptionalInterfaceFactory \
+ Client/PendingOperation \
Client/Properties
nodist_geninclude_HEADERS = \
diff --git a/TelepathyQt4/cli-pending-operation.cpp b/TelepathyQt4/cli-pending-operation.cpp
new file mode 100644
index 0000000..9b6568c
--- /dev/null
+++ b/TelepathyQt4/cli-pending-operation.cpp
@@ -0,0 +1,158 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "cli-pending-operation.h"
+
+#include <QDBusPendingCall>
+#include <QDBusPendingCallWatcher>
+
+#include "cli-pending-operation.moc.hpp"
+#include "debug-internal.hpp"
+
+namespace Telepathy
+{
+namespace Client
+{
+
+
+struct PendingOperation::Private
+{
+ inline Private()
+ : errorName(QString()),
+ errorMessage(QString()),
+ finished(false)
+ { }
+
+ QString errorName;
+ QString errorMessage;
+ bool finished;
+};
+
+
+PendingOperation::PendingOperation(DBusProxy* proxy)
+ : QObject(proxy),
+ mPriv(new Private())
+{
+ connect(this, SIGNAL(destroyed(QObject*)),
+ this, SLOT(selfDestroyed(QObject*)));
+}
+
+
+PendingOperation::~PendingOperation()
+{
+ delete mPriv;
+}
+
+
+void PendingOperation::setFinished()
+{
+ mPriv->finished = true;
+}
+
+
+void PendingOperation::setError(const QString& name, const QString& message)
+{
+ Q_ASSERT(!name.isEmpty());
+ mPriv->errorName = name;
+ mPriv->errorMessage = message;
+}
+
+
+void PendingOperation::setError(const QDBusError& error)
+{
+ setError(error.name(), error.message());
+}
+
+
+DBusProxy* PendingOperation::proxy() const
+{
+ return QObject::parent();
+}
+
+
+bool PendingOperation::isSuccessful() const
+{
+ Q_ASSERT(mPriv->finished);
+ return (mPriv->errorName.isEmpty());
+}
+
+
+bool PendingOperation::isError() const
+{
+ Q_ASSERT(mPriv->finished);
+ return (!mPriv->errorName.isEmpty());
+}
+
+
+QString PendingOperation::errorName() const
+{
+ Q_ASSERT(mPriv->finished);
+ return mPriv->errorName;
+}
+
+
+QString PendingOperation::errorMessage() const
+{
+ Q_ASSERT(mPriv->finished);
+ return mPriv->errorMessage;
+}
+
+
+void PendingOperation::selfDestroyed(QObject* self)
+{
+ // FIXME: signal finished with a synthetic error here?
+}
+
+
+PendingVoidMethodCall::PendingVoidMethodCall(DBusProxy* proxy,
+ QDBusPendingCall call)
+ : PendingOperation(proxy),
+ mPriv(0)
+{
+ connect(new QDBusPendingCallWatcher(call),
+ SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this,
+ SLOT(watcherFinished(QDBusPendingCallWatcher*)));
+}
+
+
+void PendingVoidMethodCall::watcherFinished(QDBusPendingCallWatcher* watcher)
+{
+ setFinished();
+
+ if (watcher->isError())
+ {
+ setError(watcher->error());
+ Q_ASSERT(isError());
+ emit finished(this, false);
+ }
+ else
+ {
+ Q_ASSERT(isSuccessful());
+ emit finished(this, true);
+ }
+
+ deleteLater();
+}
+
+
+} // Telepathy::Client
+} // Telepathy
diff --git a/TelepathyQt4/cli-pending-operation.h b/TelepathyQt4/cli-pending-operation.h
new file mode 100644
index 0000000..3dca707
--- /dev/null
+++ b/TelepathyQt4/cli-pending-operation.h
@@ -0,0 +1,165 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _TelepathyQt4_cli_pending_operation_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_pending_operation_h_HEADER_GUARD_
+
+#include <QObject>
+
+class QDBusError;
+class QDBusPendingCall;
+class QDBusPendingCallWatcher;
+
+namespace Telepathy
+{
+namespace Client
+{
+
+// TODO: remove this when we have the DBusProxy class
+typedef QObject DBusProxy;
+
+/**
+ * Abstract base class for pending asynchronous operations.
+ *
+ * This class represents an incomplete asynchronous operation, such as a
+ * D-Bus method call. When the operation has finished, it emits
+ * #finished. The slot or slots connected to the #finished() signal may obtain
+ * additional information from the %PendingOperation.
+ *
+ * In simple cases, like a D-Bus method with no 'out' arguments or for which
+ * all 'out' arguments are to be ignored (so the possible results are
+ * success with no extra information, or failure with an error code), the
+ * trivial subclass %PendingVoidMethodCall can be used.
+ *
+ * For pending operations that produce a result, another subclass of
+ * %PendingOperation can be used, with additional methods that provide that
+ * result to the library user.
+ *
+ * After #finished() is emitted, the %PendingOperation is automatically
+ * deleted using #deleteLater(), so library users must not explicitly
+ * delete this object.
+ *
+ * The design is loosely based on KDE's KJob.
+ */
+class PendingOperation : public QObject
+{
+ Q_OBJECT
+
+protected:
+ PendingOperation(DBusProxy* proxy);
+ void setFinished();
+ void setError(const QString& name, const QString& message);
+ void setError(const QDBusError& error);
+
+public:
+ virtual ~PendingOperation();
+
+ DBusProxy* proxy() const;
+
+ /**
+ * Returns true if the pending operation has finished successfully.
+ *
+ * This should only be called from a slot connected to #finished(),
+ * where it is equivalent to to (!isError()).
+ *
+ * \return true if the pending operation has finished and was successful
+ */
+ // FIXME: do we want this or isError() or both? KJob only has error()
+ bool isSuccessful() const;
+
+ /**
+ * Returns true if the pending operation has finished unsuccessfully.
+ *
+ * This should only be called from a slot connected to #finished(),
+ * where it is equivalent to to (!isSuccessful()).
+ *
+ * \return true if the pending operation has finished but was unsuccessful
+ */
+ bool isError() const;
+
+ /**
+ * If #isError() would return true, returns the D-Bus error with which
+ * the operation failed. If the operation succeeded, returns an empty
+ * string.
+ *
+ * This should only be called from a slot connected to #finished().
+ *
+ * \return a D-Bus error name or an empty string
+ */
+ // FIXME: in KJob it is an error to call this if !isError()
+ QString errorName() const;
+
+ /**
+ * If isError() would return true, returns a debugging message associated
+ * with the error, which may be an empty string. Otherwise, return an
+ * empty string.
+ *
+ * This should only be called from a slot connected to #finished().
+ *
+ * \return a debugging message or an empty string
+ */
+ // FIXME: in KJob it is an error to call this if !isError()
+ QString errorMessage() const;
+
+Q_SIGNALS:
+ /**
+ * Emitted when the pending operation finishes, i.e. when #isFinished()
+ * changes from false to true.
+ *
+ * \param operation This operation object, from which further information
+ * may be obtained
+ * \param successful true if the operation was successful (the same as
+ * operation->isSuccessful())
+ */
+ // FIXME: would bool error be better? KJob only has error()
+ void finished(PendingOperation* operation, bool successful);
+
+private slots:
+ void selfDestroyed(QObject* self);
+
+private:
+ struct Private;
+ friend struct Private;
+ Private *mPriv;
+};
+
+
+class PendingVoidMethodCall : public PendingOperation
+{
+ Q_OBJECT
+
+public:
+ PendingVoidMethodCall(DBusProxy* proxy, QDBusPendingCall call);
+
+private Q_SLOTS:
+ void watcherFinished(QDBusPendingCallWatcher*);
+
+private:
+ // just ABI padding at the moment
+ struct Private;
+ friend struct Private;
+ Private *mPriv;
+};
+
+} // Telepathy::Client
+} // Telepathy
+
+#endif
--
1.5.6.5
More information about the Telepathy-commits
mailing list