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