From: <aar...@us...> - 2006-07-09 21:40:31
|
Revision: 16474 Author: aaronsheldon Date: 2006-07-09 14:40:17 -0700 (Sun, 09 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16474&view=rev Log Message: ----------- Compositing icons takes time. Instead of compositing the same icons over and over again, let's store them in a hash table and retrieve them when we need them. This saves a lot of time when we redo the entire buddy list, such as in a "View Offline Buddies" click, or any other preference change. This way we can reuse them instead of constantly regenerating them. This is especially saving when you have many buddies. Modified Paths: -------------- branches/soc-2006-blist-efficiency/src/gtkblist.c Modified: branches/soc-2006-blist-efficiency/src/gtkblist.c =================================================================== --- branches/soc-2006-blist-efficiency/src/gtkblist.c 2006-07-09 16:48:25 UTC (rev 16473) +++ branches/soc-2006-blist-efficiency/src/gtkblist.c 2006-07-09 21:40:17 UTC (rev 16474) @@ -104,6 +104,7 @@ static guint visibility_manager_count = 0; static gboolean gtk_blist_obscured = FALSE; +GHashTable* status_icon_hash_table = NULL; static GList *gaim_gtk_blist_sort_methods = NULL; static struct gaim_gtk_blist_sort_method *current_sort_method = NULL; @@ -2704,7 +2705,7 @@ { GdkPixbuf *scale, *status = NULL; int i, scalesize = 30; - char *filename; + char *filename, *key, *tmp; const char *protoname = NULL; struct _gaim_gtk_blist_node *gtknode = node->ui_data; struct _gaim_gtk_blist_node *gtkbuddynode = NULL; @@ -2714,6 +2715,9 @@ GaimBuddy *buddy = NULL; GaimChat *chat = NULL; + if (!status_icon_hash_table) + status_icon_hash_table = g_hash_table_new (g_str_hash,g_str_equal); + if(GAIM_BLIST_NODE_IS_CONTACT(node)) { if(!gtknode->contact_expanded) { buddy = gaim_contact_get_priority_buddy((GaimContact*)node); @@ -2780,6 +2784,70 @@ emblems[1].filename = emblems[2].filename = emblems[3].filename = NULL; } +/* Begin Generating Lookup Key */ + if (buddy) { + + if (GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) + key = g_strconcat(protoname, "login", NULL); + else if (!GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) + key = g_strconcat(protoname, "logout", NULL); + else + key = g_strdup(protoname); + + presence = gaim_buddy_get_presence(buddy); + if (!GAIM_BUDDY_IS_ONLINE(buddy)) { + tmp = key; + key = g_strconcat(key, "off", NULL); + g_free(tmp); + } else if (gaim_presence_is_idle(presence)) { + tmp = key; + key = g_strconcat(key, "idle", NULL); + g_free(tmp); + } + + if (!gaim_privacy_check(buddy->account, gaim_buddy_get_name(buddy))) { + tmp = key; + key = g_strconcat(key, "blocked", NULL); + g_free(tmp); + } + + if (size == GAIM_STATUS_ICON_SMALL) { + tmp = key; + key = g_strconcat(key, "small", NULL); + g_free(tmp); + } + + for(i=0; i<4; i++) { + if(emblems[i].filename) { + tmp = key; + key = g_strconcat(key, emblems[i].filename, NULL); + g_free(tmp); + } + } + } + /* There are only two options for chat or gaimdude - big or small */ + else if (chat && size == GAIM_STATUS_ICON_SMALL) + key = g_strconcat(protoname, "chat-s", NULL); + else if (chat) + key = g_strconcat(protoname, "chat", NULL); + else if (size == GAIM_STATUS_ICON_SMALL) + key = g_strdup("gaimdude-s"); + else + key = g_strdup("gaimdude"); + +/* End Generating Lookup Key */ + + +/* If we already know this icon, just return it */ + scale = g_hash_table_lookup (status_icon_hash_table, key); + if (scale) { + gdk_pixbuf_ref(scale); + g_free(key); + return scale; + } + +/* Create a new composite icon */ + if(buddy && GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", "default", "login.png", NULL); } else if(buddy && !GAIM_BUDDY_IS_ONLINE(buddy) && gtkbuddynode && gtkbuddynode->recent_signonoff) { @@ -2835,7 +2903,6 @@ } if(buddy) { - presence = gaim_buddy_get_presence(buddy); if (!GAIM_BUDDY_IS_ONLINE(buddy)) gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); @@ -2866,6 +2933,10 @@ } } + /* Insert the new icon into the status icon hash table */ + g_hash_table_insert (status_icon_hash_table, key, scale); + gdk_pixbuf_ref(scale); + return scale; } @@ -3927,7 +3998,10 @@ if (remove && !GAIM_BLIST_NODE_IS_GROUP(node)) gaim_gtk_blist_hide_node(list, node); - gaim_gtk_blist_update(list, node); + if (GAIM_BLIST_NODE_IS_BUDDY(node)) + gaim_gtk_blist_update_contact(list, node); + else if (GAIM_BLIST_NODE_IS_CHAT(node)) + gaim_gtk_blist_update(list, node); node = gaim_blist_node_next(node, FALSE); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |