# HG changeset patch # User Paul Aurich # Date 1266214073 0 # Node ID 86204988c52262fce34329107c3a77e292fb1a1d # Parent 29bafbfca469bd406527fefc5f8d4913f1a814da jabber: Treat JabberBuddy->resources as a sorted list. Instead of having jabber_buddy_find_resource() do a bunch of calculations, just do all those when presence changes. The first entry in the list is the highest-priority resource. diff -r 29bafbfca469 -r 86204988c522 libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Mon Feb 15 06:04:51 2010 +0000 +++ b/libpurple/protocols/jabber/buddy.c Mon Feb 15 06:07:53 2010 +0000 @@ -177,48 +177,45 @@ JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb, const char *resource) { - JabberBuddyResource *jbr = NULL; GList *l; - if(!jb) + if (!jb) return NULL; - for(l = jb->resources; l; l = l->next) + if (resource == NULL) + return jb->resources ? jb->resources->data : NULL; + + for (l = jb->resources; l; l = l->next) { - JabberBuddyResource *tmp = (JabberBuddyResource *) l->data; - if (!jbr && !resource) { - jbr = tmp; - } else if (!resource) { - if (resource_compare_cb(tmp, jbr) < 0) - jbr = tmp; - } else if(tmp->name) { - if(!strcmp(tmp->name, resource)) { - jbr = tmp; - break; - } - } + JabberBuddyResource *jbr = l->data; + if (g_str_equal(resource, jbr->name)) + return jbr; } - return jbr; + return NULL; } JabberBuddyResource *jabber_buddy_track_resource(JabberBuddy *jb, const char *resource, int priority, JabberBuddyState state, const char *status) { + /* TODO: Optimization: Only reinsert if priority+state changed */ JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, resource); - if(!jbr) { + if (jbr) { + jb->resources = g_list_remove(jb->resources, jbr); + } else { jbr = g_new0(JabberBuddyResource, 1); jbr->jb = jb; jbr->name = g_strdup(resource); jbr->capabilities = JABBER_CAP_NONE; jbr->tz_off = PURPLE_NO_TZ_OFF; - jb->resources = g_list_append(jb->resources, jbr); } jbr->priority = priority; jbr->state = state; g_free(jbr->status); jbr->status = g_strdup(status); + jb->resources = g_list_insert_sorted(jb->resources, jbr, + resource_compare_cb); return jbr; } @@ -802,6 +799,8 @@ jbr = jabber_buddy_find_resource(jbi->jb, resource_name); add_jbr_info(jbi, resource_name, jbr); } else { + /* TODO: This is in priority-ascending order (lowest prio first), because + * everything is prepended. Is that ok? */ for (resources = jbi->jb->resources; resources; resources = resources->next) { jbr = resources->data; diff -r 29bafbfca469 -r 86204988c522 libpurple/protocols/jabber/buddy.h --- a/libpurple/protocols/jabber/buddy.h Mon Feb 15 06:04:51 2010 +0000 +++ b/libpurple/protocols/jabber/buddy.h Mon Feb 15 06:07:53 2010 +0000 @@ -31,6 +31,13 @@ #include "jutil.h" struct _JabberBuddy { + /** + * A sorted list of resources in priority descending order. + * This means that the first resource in the list is the + * "most available" (see resource_compare_cb in buddy.c for + * details). Don't play with this yourself, let + * jabber_buddy_track_resource and jabber_buddy_remove_resource do it. + */ GList *resources; char *error_msg; enum {