[Telepathy-commits] [telepathy-qt4/master] Add Connection::optionalInterface() and friends

Olli Salli olli.salli at collabora.co.uk
Mon Sep 8 08:38:07 PDT 2008


---
 TelepathyQt4/cli-connection.cpp |   62 ++++++++++++++++++++++++++++++--------
 TelepathyQt4/cli-connection.h   |   53 +++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/TelepathyQt4/cli-connection.cpp b/TelepathyQt4/cli-connection.cpp
index b2782fc..f6d6e52 100644
--- a/TelepathyQt4/cli-connection.cpp
+++ b/TelepathyQt4/cli-connection.cpp
@@ -25,10 +25,11 @@
 #include <TelepathyQt4/_gen/cli-connection.moc.hpp>
 #include <TelepathyQt4/cli-connection.moc.hpp>
 
+#include <QMap>
 #include <QQueue>
+#include <QString>
 #include <QtGlobal>
 
-#include "cli-dbus.h"
 #include "debug-internal.hpp"
 
 namespace Telepathy
@@ -42,10 +43,10 @@ struct Connection::Private
     Connection& parent;
 
     // Optional interface proxies
-    ConnectionInterfaceAliasingInterface aliasing;
-    ConnectionInterfacePresenceInterface presence;
-    ConnectionInterfaceSimplePresenceInterface simplePresence;
-    DBus::PropertiesInterface properties;
+    QMap<QString, QDBusAbstractInterface*> optionalInterfaces;
+    ConnectionInterfaceAliasingInterface* aliasing;
+    ConnectionInterfacePresenceInterface* presence;
+    DBus::PropertiesInterface* properties;
 
     // Introspection
     bool initialIntrospection;
@@ -61,12 +62,12 @@ struct Connection::Private
     SimpleStatusSpecMap simplePresenceStatuses;
 
     Private(Connection &parent)
-        : parent(parent),
-          aliasing(parent),
-          presence(parent),
-          simplePresence(parent),
-          properties(parent)
+        : parent(parent)
     {
+        aliasing = 0;
+        presence = 0;
+        properties = 0;
+
         initialIntrospection = false;
         readiness = ReadinessJustCreated;
         status = ConnectionStatusDisconnected;
@@ -96,9 +97,14 @@ struct Connection::Private
             return;
         }
 
+        if (!aliasing) {
+            aliasing = parent.aliasingInterface();
+            Q_ASSERT(aliasing != 0);
+        }
+
         debug() << "Calling GetAliasFlags()";
         QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(aliasing.GetAliasFlags(), &parent);
+            new QDBusPendingCallWatcher(aliasing->GetAliasFlags(), &parent);
         parent.connect(watcher,
                        SIGNAL(finished(QDBusPendingCallWatcher*)),
                        SLOT(gotAliasFlags(QDBusPendingCallWatcher*)));
@@ -125,9 +131,14 @@ struct Connection::Private
             return;
         }
 
+        if (!presence) {
+            presence = parent.presenceInterface();
+            Q_ASSERT(presence != 0);
+        }
+
         debug() << "Calling GetStatuses() (legacy)";
         QDBusPendingCallWatcher* watcher =
-            new QDBusPendingCallWatcher(presence.GetStatuses(), &parent);
+            new QDBusPendingCallWatcher(presence->GetStatuses(), &parent);
         parent.connect(watcher,
                        SIGNAL(finished(QDBusPendingCallWatcher*)),
                        SLOT(gotStatuses(QDBusPendingCallWatcher*)));
@@ -135,9 +146,14 @@ struct Connection::Private
 
     void introspectSimplePresence()
     {
+        if (!properties) {
+            properties = parent.propertiesInterface();
+            Q_ASSERT(properties != 0);
+        }
+
         debug() << "Getting available SimplePresence statuses";
         QDBusPendingCall call =
-            properties.Get(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
+            properties->Get(TELEPATHY_INTERFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
                            "Statuses");
         QDBusPendingCallWatcher* watcher =
             new QDBusPendingCallWatcher(call, &parent);
@@ -248,6 +264,26 @@ SimpleStatusSpecMap Connection::simplePresenceStatuses() const
     return mPriv->simplePresenceStatuses;
 }
 
+QDBusAbstractInterface* Connection::internalCachedInterface(const QString& name) const
+{
+    if (mPriv->optionalInterfaces.contains(name)) {
+        debug() << "Returning cached interface for" << name;
+        return mPriv->optionalInterfaces.value(name);
+    } else {
+        debug() << "No interface found for" << name;
+        return 0;
+    }
+}
+
+void Connection::internalInterfaceCache(QDBusAbstractInterface* interface) const
+{
+    QString name = interface->interface();
+    Q_ASSERT(!mPriv->optionalInterfaces.contains(name));
+
+    debug() << "Caching interface" << name;
+    mPriv->optionalInterfaces[name] = interface;
+}
+
 void Connection::onStatusChanged(uint status, uint reason)
 {
     debug() << "Status changed from" << mPriv->status << "to" << status << "because of" << reason;
diff --git a/TelepathyQt4/cli-connection.h b/TelepathyQt4/cli-connection.h
index 4fece7c..7de0bf1 100644
--- a/TelepathyQt4/cli-connection.h
+++ b/TelepathyQt4/cli-connection.h
@@ -47,6 +47,7 @@
 #include <QStringList>
 
 #include <TelepathyQt4/Constants>
+#include <TelepathyQt4/Client/DBus>
 
 namespace Telepathy
 {
@@ -235,6 +236,55 @@ public:
      */
     SimpleStatusSpecMap simplePresenceStatuses() const;
 
+    template <class Interface>
+    inline Interface* optionalInterface(bool forcePresent = true) const
+    {
+        // Check for the remote object supporting the interface
+        QString name(Interface::staticInterfaceName());
+        if (!forcePresent && !interfaces().contains(name))
+            return 0;
+
+        // If there is a interface cached already, return it
+        QDBusAbstractInterface* cached = internalCachedInterface(name);
+        if (cached)
+            return static_cast<Interface*>(cached);
+
+        // Otherwise, cache and return a newly constructed proxy
+        Interface* interface = new Interface(*this, 0);
+        internalInterfaceCache(interface);
+        return interface;
+    }
+
+    inline ConnectionInterfaceAliasingInterface* aliasingInterface(bool forcePresent = true) const
+    {
+        return optionalInterface<ConnectionInterfaceAliasingInterface>(forcePresent);
+    }
+
+    inline ConnectionInterfaceAvatarsInterface* avatarsInterface(bool forcePresent = true) const
+    {
+        return optionalInterface<ConnectionInterfaceAvatarsInterface>(forcePresent);
+    }
+
+    inline ConnectionInterfaceCapabilitiesInterface* capabilitiesInterface(bool forcePresent = true) const
+    {
+        return optionalInterface<ConnectionInterfaceCapabilitiesInterface>(forcePresent);
+    }
+
+    inline ConnectionInterfacePresenceInterface* presenceInterface(bool forcePresent = true) const
+    {
+        return optionalInterface<ConnectionInterfacePresenceInterface>(forcePresent);
+    }
+
+    inline ConnectionInterfaceSimplePresenceInterface* simplePresenceInterface(bool forcePresent = true) const
+    {
+        return optionalInterface<ConnectionInterfaceSimplePresenceInterface>(forcePresent);
+    }
+
+    inline DBus::PropertiesInterface* propertiesInterface(bool forcePresent = true) const
+    {
+        return optionalInterface<DBus::PropertiesInterface>(forcePresent);
+    }
+
 Q_SIGNALS:
     /**
      * Emitted whenever the readiness of the Connection changes.
@@ -252,6 +302,9 @@ private Q_SLOTS:
     void gotSimpleStatuses(QDBusPendingCallWatcher* watcher);
 
 private:
+    QDBusAbstractInterface* internalCachedInterface(const QString& name) const;
+    void internalInterfaceCache(QDBusAbstractInterface* interface) const;
+
     struct Private;
     friend struct Private;
     Private *mPriv;
-- 
1.5.6.5




More information about the Telepathy-commits mailing list