[Telepathy-commits] [telepathy-qt4/master] Return existing Contacts instead of always creating new ones if there are satisfying ones already in existence
Olli Salli
olli.salli at collabora.co.uk
Fri Jan 30 10:02:58 PST 2009
---
TelepathyQt4/Client/contact-manager.cpp | 74 ++++++++++++++++++++++++++----
TelepathyQt4/Client/contact-manager.h | 7 +++
TelepathyQt4/Client/pending-contacts.cpp | 38 +++++++++++----
TelepathyQt4/Client/pending-contacts.h | 7 ++-
TelepathyQt4/Makefile.am | 1 +
5 files changed, 106 insertions(+), 21 deletions(-)
diff --git a/TelepathyQt4/Client/contact-manager.cpp b/TelepathyQt4/Client/contact-manager.cpp
index 45735b9..14bff60 100644
--- a/TelepathyQt4/Client/contact-manager.cpp
+++ b/TelepathyQt4/Client/contact-manager.cpp
@@ -20,9 +20,12 @@
*/
#include <TelepathyQt4/Client/ContactManager>
+#include "TelepathyQt4/Client/_gen/contact-manager.moc.hpp"
#include <QMap>
#include <QString>
+#include <QSet>
+#include <QWeakPointer>
#include <TelepathyQt4/Client/Connection>
#include <TelepathyQt4/Client/PendingContactAttributes>
@@ -64,6 +67,7 @@ namespace Client
struct ContactManager::Private
{
Connection *conn;
+ QMap<uint, QWeakPointer<Contact> > contacts;
};
Connection *ContactManager::connection() const
@@ -104,20 +108,58 @@ PendingContacts *ContactManager::contactsForHandles(const UIntList &handles,
debug() << "Building contacts for" << handles.size() << "handles" << "with" << features.size()
<< "features";
- QSet<QString> interfaces;
- foreach (Contact::Feature feature, features) {
- if (true) { // TODO when not naive: if one or more of the contacts doesn't have the feature
- interfaces.insert(featureToInterface(feature));
+ QMap<uint, QSharedPointer<Contact> > satisfyingContacts;
+ QSet<uint> otherContacts;
+ QSet<Contact::Feature> missingFeatures;
+
+ foreach (uint handle, handles) {
+ QSharedPointer<Contact> contact = mPriv->contacts[handle].toStrongRef();
+ if (contact) {
+ if (true /* TODO: contact->hasFeatures(features) */) {
+ // Contact exists and has all the requested features
+ satisfyingContacts.insert(handle, contact);
+ } else {
+ // Contact exists but is missing features
+ otherContacts.insert(handle);
+ missingFeatures.unite(features /* TODO:- contact->features() */);
+ }
+ } else {
+ // Contact doesn't exist - we need to get all of the features (same as unite(features))
+ missingFeatures = features;
+ // It might be a weak pointer with 0 refs, make sure to remove it
+ mPriv->contacts.remove(handle);
+ // In either case, the contact needs to be fetched
+ otherContacts.insert(handle);
}
}
- PendingContactAttributes *attributes =
- mPriv->conn->getContactAttributes(handles, interfaces.toList(), true);
+ debug() << " " << satisfyingContacts.size() << "satisfying and"
+ << otherContacts.size() << "other contacts";
+ debug() << " " << missingFeatures.size() << "features missing";
- PendingContacts *contacts = new PendingContacts(this, handles, features);
- contacts->connect(attributes,
- SIGNAL(finished(Telepathy::Client::PendingOperation*)),
- SLOT(onAttributesFinished(Telepathy::Client::PendingOperation*)));
+ QSet<QString> interfaces;
+ foreach (Contact::Feature feature, missingFeatures) {
+ interfaces.insert(featureToInterface(feature));
+ }
+
+ PendingContacts *contacts = new PendingContacts(this, handles, features, satisfyingContacts);
+ connect(contacts,
+ SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+ SLOT(onPendingContactsFinished(Telepathy::Client::PendingOperation *)));
+
+ if (!otherContacts.isEmpty()) {
+ debug() << " Fetching" << interfaces.size() << "interfaces for"
+ << otherContacts.size() << "contacts";
+
+ PendingContactAttributes *attributes =
+ mPriv->conn->getContactAttributes(otherContacts.toList(), interfaces.toList(), true);
+
+ contacts->connect(attributes,
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(onAttributesFinished(Telepathy::Client::PendingOperation*)));
+ } else {
+ contacts->allAttributesFetched();
+ }
return contacts;
}
@@ -144,6 +186,18 @@ PendingContacts *ContactManager::contactsForIdentifiers(const QStringList &ident
return contacts;
}
+void ContactManager::onPendingContactsFinished(Telepathy::Client::PendingOperation *operation)
+{
+ PendingContacts *contacts = qobject_cast<PendingContacts *>(operation);
+
+ if (contacts->isValid()) {
+ debug() << this << "Caching" << contacts->contacts().size() << "contacts";
+ foreach (QSharedPointer<Contact> contact, contacts->contacts()) {
+ mPriv->contacts.insert(contact->handle()[0], contact);
+ }
+ }
+}
+
ContactManager::ContactManager(Connection *parent)
: QObject(parent), mPriv(new Private)
{
diff --git a/TelepathyQt4/Client/contact-manager.h b/TelepathyQt4/Client/contact-manager.h
index cd0ce17..dd1727d 100644
--- a/TelepathyQt4/Client/contact-manager.h
+++ b/TelepathyQt4/Client/contact-manager.h
@@ -29,6 +29,7 @@
#include <QObject>
#include <QSet>
+#include <QSharedPointer>
#include <TelepathyQt4/Types>
#include <TelepathyQt4/Client/Contact>
@@ -40,9 +41,12 @@ namespace Client
class Connection;
class PendingContacts;
+class PendingOperation;
class ContactManager : public QObject
{
+ Q_OBJECT
+
public:
Connection *connection() const;
@@ -57,6 +61,9 @@ class ContactManager : public QObject
PendingContacts *contactsForIdentifiers(const QStringList &identifiers,
const QSet<Contact::Feature> &features = QSet<Contact::Feature>());
+ private Q_SLOTS:
+ void onPendingContactsFinished(Telepathy::Client::PendingOperation *);
+
private:
ContactManager(Connection *parent);
~ContactManager();
diff --git a/TelepathyQt4/Client/pending-contacts.cpp b/TelepathyQt4/Client/pending-contacts.cpp
index d5188c2..91b8dc9 100644
--- a/TelepathyQt4/Client/pending-contacts.cpp
+++ b/TelepathyQt4/Client/pending-contacts.cpp
@@ -37,9 +37,11 @@ namespace Client
struct PendingContacts::Private
{
Private(ContactManager *manager, const UIntList &handles,
- const QSet<Contact::Feature> &features)
+ const QSet<Contact::Feature> &features,
+ const QMap<uint, QSharedPointer<Contact> > &satisfyingContacts)
: manager(manager),
features(features),
+ satisfyingContacts(satisfyingContacts),
isForIdentifiers(false),
handles(handles),
nested(0)
@@ -58,6 +60,7 @@ struct PendingContacts::Private
ContactManager *manager;
QSet<Contact::Feature> features;
+ QMap<uint, QSharedPointer<Contact> > satisfyingContacts;
bool isForIdentifiers;
UIntList handles;
@@ -153,20 +156,23 @@ void PendingContacts::onAttributesFinished(PendingOperation *operation)
}
ReferencedHandles validHandles = pendingAttributes->validHandles();
- mPriv->invalidHandles = pendingAttributes->invalidHandles();
ContactAttributesMap attributes = pendingAttributes->attributes();
debug() << " Success:" << validHandles.size() << "valid and"
<< mPriv->invalidHandles.size() << "invalid handles";
- for (int i = 0; i < validHandles.size(); i++) {
- uint handle = validHandles[i];
- ReferencedHandles referenced = validHandles.mid(i, 1);
- mPriv->contacts.push_back(QSharedPointer<Contact>(new Contact(mPriv->manager, referenced,
- attributes[handle])));
+ foreach (uint handle, mPriv->handles) {
+ int indexInValid = validHandles.indexOf(handle);
+ if (indexInValid >= 0) {
+ ReferencedHandles referenced = validHandles.mid(indexInValid, 1);
+ mPriv->satisfyingContacts.insert(handle, QSharedPointer<Contact>(new Contact(
+ mPriv->manager, referenced, attributes[handle])));
+ } else if (!mPriv->satisfyingContacts.contains(handle)) {
+ mPriv->invalidHandles.push_back(handle);
+ }
}
- setFinished();
+ allAttributesFetched();
}
void PendingContacts::onHandlesFinished(PendingOperation *operation)
@@ -209,9 +215,10 @@ void PendingContacts::onNestedFinished(PendingOperation *operation)
}
PendingContacts::PendingContacts(ContactManager *manager,
- const UIntList &handles, const QSet<Contact::Feature> &features)
+ const UIntList &handles, const QSet<Contact::Feature> &features,
+ const QMap<uint, QSharedPointer<Contact> > &satisfyingContacts)
: PendingOperation(manager),
- mPriv(new Private(manager, handles, features))
+ mPriv(new Private(manager, handles, features, satisfyingContacts))
{
}
@@ -221,5 +228,16 @@ PendingContacts::PendingContacts(ContactManager *manager,
{
}
+void PendingContacts::allAttributesFetched()
+{
+ foreach (uint handle, mPriv->handles) {
+ if (mPriv->satisfyingContacts.contains(handle)) {
+ mPriv->contacts.push_back(mPriv->satisfyingContacts[handle]);
+ }
+ }
+
+ setFinished();
+}
+
} // Telepathy::Client
} // Telepathy
diff --git a/TelepathyQt4/Client/pending-contacts.h b/TelepathyQt4/Client/pending-contacts.h
index b19f6a6..2123ffe 100644
--- a/TelepathyQt4/Client/pending-contacts.h
+++ b/TelepathyQt4/Client/pending-contacts.h
@@ -29,6 +29,7 @@
#include <TelepathyQt4/Client/PendingOperation>
#include <QList>
+#include <QMap>
#include <QSet>
#include <QSharedPointer>
#include <QStringList>
@@ -69,11 +70,15 @@ private Q_SLOTS:
private:
Q_DISABLE_COPY(PendingContacts);
+
PendingContacts(ContactManager *manager, const UIntList &handles,
- const QSet<Contact::Feature> &features);
+ const QSet<Contact::Feature> &features,
+ const QMap<uint, QSharedPointer<Contact> > &satisfyingContacts);
PendingContacts(ContactManager *manager, const QStringList &identifiers,
const QSet<Contact::Feature> &features);
+ void allAttributesFetched();
+
struct Private;
friend struct Private;
friend class ContactManager;
diff --git a/TelepathyQt4/Makefile.am b/TelepathyQt4/Makefile.am
index fa50f82..77ef0c3 100644
--- a/TelepathyQt4/Makefile.am
+++ b/TelepathyQt4/Makefile.am
@@ -96,6 +96,7 @@ nodist_libtelepathy_qt4_la_SOURCES = \
Client/_gen/connection-internal.moc.hpp \
Client/_gen/connection-manager-internal.moc.hpp \
Client/_gen/contact.moc.hpp \
+ Client/_gen/contact-manager.moc.hpp \
Client/_gen/dbus-proxy.moc.hpp \
Client/_gen/pending-account.moc.hpp \
Client/_gen/pending-channel.moc.hpp \
--
1.5.6.5
More information about the telepathy-commits
mailing list