[telepathy-qt4/master] MethodInvocationContext: Added class.

Andre Moreira Magalhaes (andrunko) andre.magalhaes at collabora.co.uk
Thu May 14 13:13:03 PDT 2009


MethodInvocationContext is a class used to represent a context of a D-Bus
method call. It's main use is to handle async replies, where when the reply is
known, the methos MethodInvocationContext::setFinished/WithError should be
called, which will send the reply over D-Bus.

It's a template class to avoid replying with unknown/wrong types. It accepts all
types known by Qt MetaType System.
---
 TelepathyQt4/Makefile.am                 |    2 +
 TelepathyQt4/MethodInvocationContext     |   13 ++
 TelepathyQt4/method-invocation-context.h |  184 ++++++++++++++++++++++++++++++
 TelepathyQt4/types.h                     |   17 +++
 4 files changed, 216 insertions(+), 0 deletions(-)
 create mode 100644 TelepathyQt4/MethodInvocationContext
 create mode 100644 TelepathyQt4/method-invocation-context.h

diff --git a/TelepathyQt4/Makefile.am b/TelepathyQt4/Makefile.am
index 9633212..0b76a1f 100644
--- a/TelepathyQt4/Makefile.am
+++ b/TelepathyQt4/Makefile.am
@@ -172,6 +172,7 @@ tpqt4include_HEADERS = \
     MediaSessionHandler \
     MediaStreamHandler \
     Message \
+    MethodInvocationContext \
     OptionalInterfaceFactory \
     PendingAccount \
     PendingChannel \
@@ -259,6 +260,7 @@ tpqt4include_HEADERS = \
     media-session-handler.h \
     media-stream-handler.h \
     message.h \
+    method-invocation-context.h \
     optional-interface-factory.h \
     pending-account.h \
     pending-channel.h \
diff --git a/TelepathyQt4/MethodInvocationContext b/TelepathyQt4/MethodInvocationContext
new file mode 100644
index 0000000..fbb425a
--- /dev/null
+++ b/TelepathyQt4/MethodInvocationContext
@@ -0,0 +1,13 @@
+#ifndef _TelepathyQt4_Client_MethodInvocationContext_HEADER_GUARD_
+#define _TelepathyQt4_Client_MethodInvocationContext_HEADER_GUARD_
+
+#ifndef IN_TELEPATHY_QT4_HEADER
+#define IN_TELEPATHY_QT4_HEADER
+#endif
+
+#include <TelepathyQt4/method-invocation-context.h>
+
+#undef IN_TELEPATHY_QT4_HEADER
+
+#endif
+// vim:set ft=cpp:
diff --git a/TelepathyQt4/method-invocation-context.h b/TelepathyQt4/method-invocation-context.h
new file mode 100644
index 0000000..1c80929
--- /dev/null
+++ b/TelepathyQt4/method-invocation-context.h
@@ -0,0 +1,184 @@
+/*
+ * This file is part of TelepathyQt4
+ *
+ * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2009 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_method_invocation_context_h_HEADER_GUARD_
+#define _TelepathyQt4_cli_method_invocation_context_h_HEADER_GUARD_
+
+#ifndef IN_TELEPATHY_QT4_HEADER
+#error IN_TELEPATHY_QT4_HEADER
+#endif
+
+#include <QtDBus>
+#include <QtCore>
+
+namespace Tp
+{
+
+namespace MethodInvocationContextTypes
+{
+
+struct Nil
+{
+};
+
+template<int Index,
+         typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7, typename T8>
+struct Select
+{
+    typedef Select<Index - 1, T2, T3, T4, T5, T6, T7, T8, Nil> Next;
+    typedef typename Next::Type Type;
+};
+template<typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7, typename T8>
+struct Select<0, T1, T2, T3, T4, T5, T6, T7, T8>
+{
+    typedef T1 Type;
+};
+
+template<typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7, typename T8>
+struct ForEach
+{
+    typedef ForEach<T2, T3, T4, T5, T6, T7, T8, Nil> Next;
+    enum { Total = Next::Total + 1 };
+};
+template<>
+struct ForEach<Nil, Nil, Nil, Nil, Nil, Nil, Nil, Nil>
+{
+    enum { Total = 0 };
+};
+
+}
+
+template<typename T1 = MethodInvocationContextTypes::Nil, typename T2 = MethodInvocationContextTypes::Nil,
+         typename T3 = MethodInvocationContextTypes::Nil, typename T4 = MethodInvocationContextTypes::Nil,
+         typename T5 = MethodInvocationContextTypes::Nil, typename T6 = MethodInvocationContextTypes::Nil,
+         typename T7 = MethodInvocationContextTypes::Nil, typename T8 = MethodInvocationContextTypes::Nil>
+class MethodInvocationContext : public RefCounted
+{
+    template<int Index>
+    struct Select : MethodInvocationContextTypes::Select<Index, T1, T2, T3, T4, T5, T6, T7, T8>
+    {
+    };
+
+    typedef MethodInvocationContextTypes::ForEach<T1, T2, T3, T4, T5, T6, T7, T8> ForEach;
+    enum { Count = ForEach::Total };
+
+public:
+    MethodInvocationContext(const QDBusConnection &bus, const QDBusMessage &message)
+        : mBus(bus), mMessage(message), mFinished(false)
+    {
+    }
+
+    virtual ~MethodInvocationContext()
+    {
+        if (!mFinished) {
+            setFinishedWithError(QString(), QString());
+        }
+    }
+
+    bool isFinished() const { return mFinished; }
+    bool isError() const { return !mErrorName.isEmpty(); }
+    QString errorName() const { return mErrorName; }
+    QString errorMessage() const { return mErrorMessage; }
+
+    void setFinished(const T1 &t1 = T1(), const T2 &t2 = T2(), const T3 &t3 = T3(),
+                     const T4 &t4 = T4(), const T5 &t5 = T5(), const T6 &t6 = T6(),
+                     const T7 &t7 = T7(), const T8 &t8 = T8())
+    {
+        if (mFinished) {
+            return;
+        }
+
+        mFinished = true;
+
+        setReplyValue(0, qVariantFromValue(t1));
+        setReplyValue(1, qVariantFromValue(t2));
+        setReplyValue(2, qVariantFromValue(t3));
+        setReplyValue(3, qVariantFromValue(t4));
+        setReplyValue(4, qVariantFromValue(t5));
+        setReplyValue(5, qVariantFromValue(t6));
+        setReplyValue(6, qVariantFromValue(t7));
+        setReplyValue(7, qVariantFromValue(t8));
+
+        if (mReply.isEmpty()) {
+            mBus.send(mMessage.createReply());
+        } else {
+            mBus.send(mMessage.createReply(mReply));
+        }
+        onFinished();
+    }
+
+    void setFinishedWithError(const QString &errorName,
+            const QString &errorMessage)
+    {
+        if (mFinished) {
+            return;
+        }
+
+        mFinished = true;
+
+        if (errorName.isEmpty()) {
+            mErrorName = "org.freedesktop.Telepathy.Qt4.ErrorHandlingError";
+        } else {
+            mErrorName = errorName;
+        }
+        mErrorMessage = errorMessage;
+
+        mBus.send(mMessage.createErrorReply(mErrorName, mErrorMessage));
+        onFinished();
+    }
+
+    template<int Index> inline
+    typename Select<Index>::Type argumentAt() const
+    {
+        Q_ASSERT(Index >= 0 && Index < Count);
+        return qvariant_cast<typename Select<Index>::Type>(mReply.value(Index));
+    }
+
+protected:
+    virtual void onFinished() {}
+
+private:
+    Q_DISABLE_COPY(MethodInvocationContext)
+
+    void setReplyValue(int index, const QVariant &value)
+    {
+        if (index >= Count) {
+            return;
+        }
+        mReply.insert(index, value);
+    }
+
+    QDBusConnection mBus;
+    QDBusMessage mMessage;
+    bool mFinished;
+    QList<QVariant> mReply;
+    QString mErrorName;
+    QString mErrorMessage;
+};
+
+} // Tp
+
+Q_DECLARE_METATYPE(Tp::MethodInvocationContextTypes::Nil)
+
+#endif
diff --git a/TelepathyQt4/types.h b/TelepathyQt4/types.h
index 8ed82fa..49634ba 100644
--- a/TelepathyQt4/types.h
+++ b/TelepathyQt4/types.h
@@ -29,6 +29,7 @@
 #include <TelepathyQt4/_gen/types.h>
 
 #include <TelepathyQt4/SharedPtr>
+#include <TelepathyQt4/MethodInvocationContext>
 
 namespace Tp
 {
@@ -63,6 +64,22 @@ typedef SharedPtr<MediaStream> MediaStreamPtr;
 typedef SharedPtr<StreamedMediaChannel> StreamedMediaChannelPtr;
 typedef SharedPtr<TextChannel> TextChannelPtr;
 
+template<typename T1 = MethodInvocationContextTypes::Nil, typename T2 = MethodInvocationContextTypes::Nil,
+         typename T3 = MethodInvocationContextTypes::Nil, typename T4 = MethodInvocationContextTypes::Nil,
+         typename T5 = MethodInvocationContextTypes::Nil, typename T6 = MethodInvocationContextTypes::Nil,
+         typename T7 = MethodInvocationContextTypes::Nil, typename T8 = MethodInvocationContextTypes::Nil>
+class MethodInvocationContextPtr : public SharedPtr<MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> >
+{
+public:
+    inline MethodInvocationContextPtr() { }
+    explicit inline MethodInvocationContextPtr(MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> *d)
+        : SharedPtr<MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> >(d) { }
+    inline MethodInvocationContextPtr(const SharedPtr<MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> > &o)
+        : SharedPtr<MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> >(o) { }
+    explicit inline MethodInvocationContextPtr(const WeakPtr<MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> > &o)
+        : SharedPtr<MethodInvocationContext<T1, T2, T3, T4, T5, T6, T7, T8> >(o) { }
+};
+
 } // Tp
 
 #endif
-- 
1.5.6.5




More information about the telepathy-commits mailing list