gobjectification: 0379396d: Populate lookup tables for buddies when ...

sadrul at pidgin.im sadrul at pidgin.im
Tue Jul 6 17:20:36 EDT 2010


----------------------------------------------------------------------
Revision: 0379396dde576bccfa74fcd060da4396b868ea40
Parent:   d89369c8e21a5db6efd61e7ddbdf5b3b60c86866
Author:   sadrul at pidgin.im
Date:     07/06/10 14:35:00
Branch:   im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/0379396dde576bccfa74fcd060da4396b868ea40

Changelog: 

Populate lookup tables for buddies when new buddies are added.

Changes against parent d89369c8e21a5db6efd61e7ddbdf5b3b60c86866

  patched  libpurple/blist.c
  patched  libpurple/blist.h

-------------- next part --------------
============================================================
--- libpurple/blist.c	acb1164af26af2248cbf9e800def969e0a393c07
+++ libpurple/blist.c	8c01ace2773aae2e601f21734d10e83c1654f324
@@ -82,6 +82,28 @@ static void purple_blist_buddies_cache_a
 
 static void purple_blist_buddies_cache_add_account(PurpleAccount *account);
 
+struct _purple_hbuddy {
+	char *name;
+	PurpleAccount *account;
+	PurpleGroup *group;
+
+	int ref;		/* A stupid ref-counter */
+};
+
+static struct _purple_hbuddy *
+create_purple_hbuddy(PurpleBuddy *buddy)
+{
+	struct _purple_hbuddy *hb = g_new(struct _purple_hbuddy, 1);
+	PurpleAccount *account = purple_buddy_get_account(buddy);
+
+	hb->name = g_strdup(purple_normalize(account, purple_buddy_get_name(buddy)));
+	hb->account = account;
+	hb->group = purple_buddy_get_group(buddy);
+	hb->ref = 1;
+
+	return hb;
+}
+
 static PurpleBuddyList *
 purple_blist_get_list()
 {
@@ -122,6 +144,9 @@ static void _purple_blist_hbuddy_free_ke
 
 static void _purple_blist_hbuddy_free_key(struct _purple_hbuddy *hb)
 {
+	if (--hb->ref)
+		return;
+
 	g_free(hb->name);
 	g_free(hb);
 }
@@ -332,7 +357,6 @@ parse_group(xmlnode *groupnode)
 		name = _("Buddies");
 
 	group = purple_group_new(name);
-	purple_blist_node_add_child(PURPLE_BLIST_NODE(group), PURPLE_BLIST_NODE(PURPLE_BLIST));
 
 	for (cnode = groupnode->child; cnode; cnode = cnode->next) {
 		if (cnode->type != XMLNODE_TYPE_TAG)
@@ -353,6 +377,9 @@ purple_blist_load()
 {
 	xmlnode *purple, *blist, *privacy;
 
+	if (PURPLE_BLIST->blist_loaded)
+		return;
+
 	PURPLE_BLIST->blist_loaded = TRUE;
 
 	purple = purple_util_read_xml_from_file("blist.xml", _("buddy list"));
@@ -620,15 +647,12 @@ purple_blist_rename_buddy(PurpleBuddy *b
 {
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleBuddyList *list = PURPLE_BLIST;
-	struct _purple_hbuddy *hb, *hb2;
+	struct _purple_hbuddy *hb;
 	GHashTable *account_buddies;
 
 	g_return_if_fail(buddy != NULL);
 
-	hb = g_new(struct _purple_hbuddy, 1);
-	hb->name = g_strdup(purple_normalize(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)));
-	hb->account = purple_buddy_get_account(buddy);
-	hb->group = (PURPLE_BLIST_NODE(buddy))->parent->parent;
+	hb = create_purple_hbuddy(buddy);
 	g_hash_table_remove(list->buddies, hb);
 
 	account_buddies = g_hash_table_lookup(list->buddies_cache, purple_buddy_get_account(buddy));
@@ -638,13 +662,9 @@ purple_blist_rename_buddy(PurpleBuddy *b
 	hb->name = g_strdup(purple_normalize(purple_buddy_get_account(buddy), name));
 	g_hash_table_replace(list->buddies, hb, buddy);
 
-	hb2 = g_new(struct _purple_hbuddy, 1);
-	hb2->name = g_strdup(hb->name);
-	hb2->account = purple_buddy_get_account(buddy);
-	hb2->group = (PURPLE_BLIST_NODE(buddy))->parent->parent;
+	hb->ref++;
+	g_hash_table_replace(account_buddies, hb, buddy);
 
-	g_hash_table_replace(account_buddies, hb2, buddy);
-
 	purple_buddy_set_name(buddy, name);
 
 	if (ops && ops->save_node)
@@ -686,12 +706,12 @@ PurpleBuddy *purple_find_buddy(PurpleAcc
 	hb.account = account;
 	hb.name = (gchar *)purple_normalize(account, name);
 
-	group = purple_blist_node_first_child(PURPLE_BLIST_NODE(list));
+	group = purple_blist_get_root();
 	for (;group; group = group->next) {
 		if (!group->child)
 			continue;
 
-		hb.group = group;
+		hb.group = PURPLE_GROUP(group);
 		if ((buddy = g_hash_table_lookup(list->buddies, &hb))) {
 			g_free(hb.name);
 			return buddy;
@@ -724,12 +744,12 @@ GSList *purple_find_buddies(PurpleAccoun
 		hb.name = (gchar *)purple_normalize(account, name);
 		hb.account = account;
 
-		node = purple_blist_node_first_child(PURPLE_BLIST_NODE(list));
+		node = purple_blist_get_root();
 		for (; node != NULL; node = node->next) {
 			if (!node->child)
 				continue;
 
-			hb.group = node;
+			hb.group = PURPLE_GROUP(node);
 			if ((buddy = g_hash_table_lookup(list->buddies, &hb)) != NULL)
 				ret = g_slist_prepend(ret, buddy);
 		}
@@ -978,7 +998,7 @@ void purple_blist_add_buddy(PurpleBuddy 
 	PurpleGroup *g;
 	PurpleContact *c;
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
-	struct _purple_hbuddy *hb, *hb2;
+	struct _purple_hbuddy *hb;
 	GHashTable *account_buddies;
 	PurpleBuddyList *list = PURPLE_BLIST;
 
@@ -1043,17 +1063,13 @@ void purple_blist_add_buddy(PurpleBuddy 
 
 
 		if (bnode->parent->parent != PURPLE_BLIST_NODE(g)) {
-			hb = g_new(struct _purple_hbuddy, 1);
-			hb->name = g_strdup(purple_normalize(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)));
-			hb->account = purple_buddy_get_account(buddy);
-			hb->group = bnode->parent->parent;
+			hb = create_purple_hbuddy(buddy);
 			g_hash_table_remove(list->buddies, hb);
 
 			account_buddies = g_hash_table_lookup(list->buddies_cache, purple_buddy_get_account(buddy));
 			g_hash_table_remove(account_buddies, hb);
 
-			g_free(hb->name);
-			g_free(hb);
+			_purple_blist_hbuddy_free_key(hb);
 		}
 
 		if (!bnode->parent->child) {
@@ -1091,22 +1107,14 @@ void purple_blist_add_buddy(PurpleBuddy 
 	}
 	PURPLE_CONTACT(bnode->parent)->totalsize++;*/
 
-	hb = g_new(struct _purple_hbuddy, 1);
-	hb->name = g_strdup(purple_normalize(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy)));
-	hb->account = purple_buddy_get_account(buddy);
-	hb->group = (PURPLE_BLIST_NODE(buddy))->parent->parent;
-
+	hb = create_purple_hbuddy(buddy);
 	g_hash_table_replace(list->buddies, hb, buddy);
 
 	account_buddies = g_hash_table_lookup(list->buddies_cache, purple_buddy_get_account(buddy));
 
-	hb2 = g_new(struct _purple_hbuddy, 1);
-	hb2->name = g_strdup(hb->name);
-	hb2->account = purple_buddy_get_account(buddy);
-	hb2->group = (PURPLE_BLIST_NODE(buddy))->parent->parent;
+	hb->ref++;
+	g_hash_table_replace(account_buddies, hb, buddy);
 
-	g_hash_table_replace(account_buddies, hb2, buddy);
-
 	purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy));
 
 	if (ops && ops->save_node)
@@ -1192,7 +1200,7 @@ PurpleBuddy *purple_find_buddy_in_group(
 
 	hb.name = g_strdup(purple_normalize(account, name));
 	hb.account = account;
-	hb.group = PURPLE_BLIST_NODE(group);
+	hb.group = group;
 
 	ret = g_hash_table_lookup(PURPLE_BLIST->buddies, &hb);
 	g_free(hb.name);
@@ -1300,6 +1308,7 @@ purple_blist_init(void)
 void
 purple_blist_init(void)
 {
+	purple_blist_get_list();
 }
 
 void
@@ -1349,7 +1358,6 @@ new_group_added(PurpleGroup *group, gpoi
 static void
 new_group_added(PurpleGroup *group, gpointer null)
 {
-	/* A new group was created. Add it at the end of the list of groups. */
 	PurpleBuddyList *list = PURPLE_BLIST;
 	if (list->node == NULL)
 		list->node = PURPLE_BLIST_NODE(group);
@@ -1374,6 +1382,34 @@ static void
 }
 
 static void
+new_buddy_added(PurpleBuddy *buddy, gpointer null)
+{
+	PurpleBuddyList *list = PURPLE_BLIST;
+	PurpleAccount *account;
+	struct _purple_hbuddy *hb;
+	GHashTable *accbuddies;
+
+	/* Update the hashtables for buddies. */
+	account = purple_buddy_get_account(buddy);
+	hb = create_purple_hbuddy(buddy);
+
+	g_hash_table_insert(list->buddies, hb, buddy);
+
+	/* Now update the hashtable used for looking up buddies of a specific account */
+	accbuddies = g_hash_table_lookup(list->buddies_cache, account);
+	if (!accbuddies) {
+		accbuddies = g_hash_table_new_full((GHashFunc)_purple_blist_hbuddy_hash,
+				(GEqualFunc)_purple_blist_hbuddy_equal,
+				(GDestroyNotify)_purple_blist_hbuddy_free_key, NULL);
+		g_hash_table_insert(list->buddies_cache, account, accbuddies);
+	}
+	g_return_if_fail(accbuddies);
+
+	hb->ref++;
+	g_hash_table_insert(accbuddies, hb, buddy);
+}
+
+static void
 purple_blist_class_init(PurpleBuddyListClass *klass)
 {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
@@ -1477,15 +1513,16 @@ purple_blist_class_init(PurpleBuddyListC
 			PURPLE_CALLBACK(purple_blist_buddies_cache_remove_account),
 			NULL);
 
-#if 0
-	purple_signal_connect(purple_blist_node_get_handle(), "group-removed",
-			handle,
-			PURPLE_CALLBACK(purple_blist_remove_group),
-			NULL);
-#endif
-
+	/* When a new group gets created, we add it to the list. We also update the
+	 * 'groups_cache' hashtable in the list. We update the list and the hashtable
+	 * when the group gets removed or renamed. (TODO) */
 	purple_g_signal_connect(PURPLE_GROUP_TYPE, "new", G_CALLBACK(new_group_added), NULL);
 	purple_g_signal_connect(PURPLE_GROUP_TYPE, "destroying", G_CALLBACK(group_destroyed), NULL);
+
+	/* When a new buddy gets created, we update the 'buddies' and 'buddies_cache'
+	 * hashtables. We also update the hashtables when the buddy gets removed, moved
+	 * or renamed. (TODO) */
+	purple_g_signal_connect(PURPLE_BUDDY_TYPE, "new", G_CALLBACK(new_buddy_added), NULL);
 }
 
 static void
@@ -1542,3 +1579,4 @@ purple_blist_get_gtype(void)
 
 	return type;
 }
+
============================================================
--- libpurple/blist.h	cf9764c2b8feb7410b30d7f427d0c36e7569b598
+++ libpurple/blist.h	5742698a108a08797e7cf5f473eb02548ee8d780
@@ -127,13 +127,6 @@ struct _list_account_buddies {
 	PurpleAccount *account;
 };
 
-struct _purple_hbuddy {
-	char *name;
-	PurpleAccount *account;
-	PurpleBlistNode *group;
-};
-
-
 #ifdef __cplusplus
 extern "C" {
 #endif


More information about the Commits mailing list