adium 3434:80b1767f9d18: Added debug logging for redraw requests

commits at adium.im commits at adium.im
Sat Oct 30 07:10:07 UTC 2010


details:	http://hg.adium.im/adium/rev/80b1767f9d18
revision:	3434:80b1767f9d18
author:		Evan Schoenberg
date:		Fri Oct 29 22:32:43 2010 -0500

Added debug logging for redraw requests
(transplanted from 76e37395bb7ef2735a3f677eb8996ac77897a44f)
Subject: adium 3435:5a41f3686bc2: Delay list object notifications as libpurple initializes; it can be expensive in terms of adding contacts from the permit and deny lists. Also, include a delayListObjectNotificationsUntilInactivity call as a few behaviors occur on the next runloop

details:	http://hg.adium.im/adium/rev/5a41f3686bc2
revision:	3435:5a41f3686bc2
author:		Evan Schoenberg
date:		Fri Oct 29 23:44:34 2010 -0500

Delay list object notifications as libpurple initializes; it can be expensive in terms of adding contacts from the permit and deny lists. Also, include a delayListObjectNotificationsUntilInactivity call as a few behaviors occur on the next runloop
(transplanted from c959997fcffbbc1b743ba725e74e571c6870c4c4)
Subject: adium 3436:79cdbe8f549a: Several fixes related to listObjectAttributesChanged:

details:	http://hg.adium.im/adium/rev/79cdbe8f549a
revision:	3436:79cdbe8f549a
author:		Evan Schoenberg
date:		Fri Oct 29 23:47:23 2010 -0500

Several fixes related to listObjectAttributesChanged:
 * Fix an abysmal bug in which we were deliberately calling _performDelayedUpdates: when shouldDelayUpdates was YES instead of when it was NO
 * Add a ListObject_AttributeChangesComplete notification to let us distinguish a change for a particular object (which always notifies for that object) from a group of changes which should trigger a display update.
 * Add a grace period for delayListObjectNotificationsUntilInactivity; previously a 1 second delay was enough to make all delays stop, which was bad if we had a network halt during a connection as subsequent contacts would appear to sign on one-by-one, with all the costs that entails.  The grace period is 3 seconds.
(transplanted from cbd40f45797a8d117b7143fd7c296c0f1d1c09fb)
Subject: adium 3437:c1972c52417b: Made debug logging less noisy here

details:	http://hg.adium.im/adium/rev/c1972c52417b
revision:	3437:c1972c52417b
author:		Evan Schoenberg
date:		Sat Oct 30 01:57:58 2010 -0500

Made debug logging less noisy here
(transplanted from 03ee59ce5bcf4fcaedbc4698c746bf65271b426e)
Subject: adium 3438:624a108a2aff: Removed temporary debug logging

details:	http://hg.adium.im/adium/rev/624a108a2aff
revision:	3438:624a108a2aff
author:		Evan Schoenberg
date:		Sat Oct 30 01:58:17 2010 -0500

Removed temporary debug logging
(transplanted from a5e6a0a2bba3d3a78555a3363f759121cef7012a)
Subject: adium 3439:34e99ff21728: Typo fix in a comment

details:	http://hg.adium.im/adium/rev/34e99ff21728
revision:	3439:34e99ff21728
author:		Evan Schoenberg
date:		Sat Oct 30 02:00:50 2010 -0500

Typo fix in a comment
(transplanted from f524212f94f7738325e48ba400aa2532f7580301)
Subject: adium 3440:6108f73e9dde: Another typo fix in a comment

details:	http://hg.adium.im/adium/rev/6108f73e9dde
revision:	3440:6108f73e9dde
author:		Evan Schoenberg
date:		Sat Oct 30 02:01:24 2010 -0500

Another typo fix in a comment
(transplanted from 8fc0082821be7fdcaaffe98e29f063b5211def39)
Subject: adium 3441:71276e1e9307: Removed another debug log

details:	http://hg.adium.im/adium/rev/71276e1e9307
revision:	3441:71276e1e9307
author:		Evan Schoenberg
date:		Sat Oct 30 02:01:49 2010 -0500

Removed another debug log
(transplanted from f2c01853e0f399d0c0a41f7fbe2391a9e907a18c)
Subject: adium 3442:57bb90426409: Huge optimization: Respect the clipRect when drawing the contact list. If you have 1000 contacts, of whom 20 are visible, we now draw 20, not 1000. Wow. Just wow. This also prevents needing to load usericons from disk for the 980 contacts for the unseeen display... though that is less useful given #14440 (the contacts menu in the status menu item loads 'em all anyways)

details:	http://hg.adium.im/adium/rev/57bb90426409
revision:	3442:57bb90426409
author:		Evan Schoenberg
date:		Sat Oct 30 02:03:05 2010 -0500

Huge optimization: Respect the clipRect when drawing the contact list. If you have 1000 contacts, of whom 20 are visible, we now draw 20, not 1000. Wow. Just wow. This also prevents needing to load usericons from disk for the 980 contacts for the unseeen display... though that is less useful given #14440 (the contacts menu in the status menu item loads 'em all anyways)
(transplanted from 9fcc0b9d488981cc1959f30397b7ec88b67af4f1)

diffs (315 lines):

diff -r a96bd47113d7 -r 57bb90426409 Frameworks/AIUtilities Framework/Source/AIOutlineViewAdditions.m
--- a/Frameworks/AIUtilities Framework/Source/AIOutlineViewAdditions.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/AIUtilities Framework/Source/AIOutlineViewAdditions.m	Sat Oct 30 02:03:05 2010 -0500
@@ -24,6 +24,9 @@
 //Redisplay an item (passing nil is the same as requesting a redisplay of the entire list)
 - (void)redisplayItem:(id)item
 {
+	static int redisplayNumber = 0;
+	NSLog(@"Redisplay #%i  %@", ++redisplayNumber, item);
+
 	if (item) {
 		NSInteger row = [self rowForItem:item];
 		if (row >= 0 && row < [self numberOfRows]) {
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/AIUtilities Framework/Source/AIVariableHeightOutlineView.m
--- a/Frameworks/AIUtilities Framework/Source/AIVariableHeightOutlineView.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/AIUtilities Framework/Source/AIVariableHeightOutlineView.m	Sat Oct 30 02:03:05 2010 -0500
@@ -235,6 +235,12 @@
 - (void)drawRow:(NSInteger)row clipRect:(NSRect)rect
 {
 	if (row >= 0 && row < [self numberOfRows]) { //Somebody keeps calling this method with row = numberOfRows, which is wrong.
+	
+		/* Most important optimization ever:
+		 * Only draw if some part of this row's rect is in the clip rect */
+		if (NSIntersectsRect([self rectOfRow:row], rect) == FALSE)
+			return;
+
 		NSArray		*tableColumns = [self tableColumns];
 		id			item = [self itemAtRow:row];
 		NSUInteger	tableColumnIndex, count = [tableColumns count];
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIAbstractListController.h
--- a/Frameworks/Adium Framework/Source/AIAbstractListController.h	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIAbstractListController.h	Sat Oct 30 02:03:05 2010 -0500
@@ -219,7 +219,7 @@
 - (void)updateLayoutFromPrefDict:(NSDictionary *)prefDict andThemeFromPrefDict:(NSDictionary *)themeDict;
 - (void)updateCellRelatedThemePreferencesFromDict:(NSDictionary *)prefDict;
 
-- (void)listObjectAttributesChanged:(NSNotification *)notification;
+- (void)listObjectAttributeChangesComplete:(NSNotification *)notification;
 - (void)contactListDesiredSizeChanged;
 - (void)updateTransparency;
 - (BOOL)useAliasesInContactListAsRequested;
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIAbstractListController.m
--- a/Frameworks/Adium Framework/Source/AIAbstractListController.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIAbstractListController.m	Sat Oct 30 02:03:05 2010 -0500
@@ -101,8 +101,8 @@
 										 object:nil];
 		
 		[[NSNotificationCenter defaultCenter] addObserver:self
-									   selector:@selector(listObjectAttributesChanged:)
-										   name:ListObject_AttributesChanged
+									   selector:@selector(listObjectAttributeChangesComplete:)
+										   name:ListObject_AttributeChangesComplete
 										 object:nil];
 		
 		[[NSNotificationCenter defaultCenter] addObserver:self
@@ -582,10 +582,10 @@
  *
  * Redisplay the object in question
  */
-- (void)listObjectAttributesChanged:(NSNotification *)notification
+- (void)listObjectAttributeChangesComplete:(NSNotification *)notification
 {
     AIListObject	*object = [notification object];
-	
+
 	//Redraw the modified object (or the whole list, if object is nil)
 	if (object) {
 		for (AIProxyListObject *proxyObject in [[object.proxyObjects copy] autorelease]) {
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIAbstractListObjectMenu.m
--- a/Frameworks/Adium Framework/Source/AIAbstractListObjectMenu.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIAbstractListObjectMenu.m	Sat Oct 30 02:03:05 2010 -0500
@@ -64,8 +64,8 @@
 /*!
  * @brief Returns a menu containing our menu items
  *
- * Remember that menu items can only be in one menu at a time, so if you use this functions you cannot do anything
- * manually the menu items
+ * Remember that menu items can only be in one menu at a time, so if you use this function you cannot do anything
+ * manually with the menu items
  */
 - (NSMenu *)menu
 {
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIContactControllerProtocol.h
--- a/Frameworks/Adium Framework/Source/AIContactControllerProtocol.h	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIContactControllerProtocol.h	Sat Oct 30 02:03:05 2010 -0500
@@ -11,7 +11,13 @@
 @class AIListObject, AIListContact, AIChat;
 @protocol AIContainingObject;
 
+/* Posted for a single object whose attributes changed */
 #define ListObject_AttributesChanged			@"ListObject_AttributesChanged"
+
+/* Called when one or more ListObject_AttributesChanged notifications are done and all delays have cleared.
+ * We're ready to update the display at this point. */
+#define ListObject_AttributeChangesComplete			@"ListObject_AttributeChangesComplete"
+
 #define ListObject_StatusChanged				@"ListObject_StatusChanged"
 #define Contact_OrderChanged					@"Contact_OrderChanged"
 #define Contact_ListChanged						@"Contact_ListChanged"
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIContactMenu.m
--- a/Frameworks/Adium Framework/Source/AIContactMenu.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIContactMenu.m	Sat Oct 30 02:03:05 2010 -0500
@@ -318,7 +318,7 @@
 			[inModifiedKeys containsObject:@"idleSince"] ||
 			[inModifiedKeys containsObject:@"listObjectStatusType"]) {
 
-			//Note that this will return nil if we don't ahve a menu item for inObject
+			//Note that this will return nil if we don't have a menu item for inObject
 			NSMenuItem	*menuItem = [self existingMenuItemForContact:(AIListContact *)inObject];
 
 			//Update the changed menu item (or rebuild the entire menu if this item should be removed or added)
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIContactObserverManager.h
--- a/Frameworks/Adium Framework/Source/AIContactObserverManager.h	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIContactObserverManager.h	Sat Oct 30 02:03:05 2010 -0500
@@ -26,6 +26,9 @@
 	NSMutableSet			*contactObservers;
 	NSMutableSet			*removedContactObservers;
 	NSTimer					*delayedUpdateTimer;
+	NSInteger				quietDelayedUpdatePeriodsRemaining;
+	
+	
 	NSInteger				delayedStatusChanges;
 	NSMutableSet			*delayedModifiedStatusKeys;
 	NSInteger				delayedAttributeChanges;
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIContactObserverManager.m
--- a/Frameworks/Adium Framework/Source/AIContactObserverManager.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIContactObserverManager.m	Sat Oct 30 02:03:05 2010 -0500
@@ -121,7 +121,7 @@
 {
 	if (delayedUpdateRequests > 0) {
 		delayedUpdateRequests--;
-		if ([self shouldDelayUpdates])
+		if (![self shouldDelayUpdates])
 			[self _performDelayedUpdates:nil];
 	}
 }
@@ -148,6 +148,7 @@
 		BOOL restoreDelayUntilInactivity = (self.delayedUpdateTimer != nil);
 		
 		[self.delayedUpdateTimer invalidate]; self.delayedUpdateTimer = nil;
+
 		[self _performDelayedUpdates:nil];
 		
 		/* After immediately performing updates as requested, go back to delaying until inactivity if that was the
@@ -158,6 +159,8 @@
 	}
 }
 
+#define QUIET_DELAYED_UPDATE_PERIODS 3
+
 //Delay all list object notifications until a period of inactivity occurs.  This is useful for accounts that do not
 //know when they have finished connecting but still want to mute events.
 - (void)delayListObjectNotificationsUntilInactivity
@@ -169,9 +172,12 @@
 																 selector:@selector(_performDelayedUpdates:)
 																 userInfo:nil
 																  repeats:YES];
+		quietDelayedUpdatePeriodsRemaining = QUIET_DELAYED_UPDATE_PERIODS; 
+
     } else {
 		//Reset the timer
 		[delayedUpdateTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:UPDATE_CLUMP_INTERVAL]];
+		quietDelayedUpdatePeriodsRemaining = QUIET_DELAYED_UPDATE_PERIODS;
 	}
 }
 
@@ -228,7 +234,8 @@
 //(When modifying display attributes in response to a status change, this is not necessary)
 - (void)listObjectAttributesChanged:(AIListObject *)inObject modifiedKeys:(NSSet *)inModifiedKeys
 {
-	if ([self shouldDelayUpdates]) {
+	BOOL shouldDelay = [self shouldDelayUpdates];
+	if (shouldDelay) {
 		delayedAttributeChanges++;
 		[delayedModifiedAttributeKeys unionSet:inModifiedKeys];
 	} else {
@@ -240,11 +247,19 @@
 
 	//Post an attributes changed message
 	[[NSNotificationCenter defaultCenter] postNotificationName:ListObject_AttributesChanged
-											  object:inObject
-											userInfo:(inModifiedKeys ?
-													  [NSDictionary dictionaryWithObject:inModifiedKeys
-																				  forKey:@"Keys"] :
-													  nil)];	
+														object:inObject
+													  userInfo:(inModifiedKeys ?
+																[NSDictionary dictionaryWithObject:inModifiedKeys
+																							forKey:@"Keys"] :
+																nil)];
+	 
+	if (!shouldDelay) {
+		/* Note that we completed 1 or more delayed attribute changes */
+		[[NSNotificationCenter defaultCenter] postNotificationName:ListObject_AttributeChangesComplete
+															object:inObject
+														  userInfo:[NSDictionary dictionaryWithObject:inModifiedKeys
+																							   forKey:@"Keys"]];
+	}
 }
 
 //Performs any delayed list object/handle updates
@@ -252,8 +267,6 @@
 {
 	BOOL	updatesOccured = (delayedStatusChanges || delayedAttributeChanges || delayedContactChanges);
 	
-	static int updatesDone = 0;
-	
 	//Send out global attribute & status changed notifications (to cover any delayed updates)
 	if (updatesOccured) {
 		BOOL shouldSort = NO;
@@ -276,6 +289,13 @@
 				[[AISortController activeSortController] shouldSortForModifiedAttributeKeys:delayedModifiedAttributeKeys]) {
 				shouldSort = YES;
 			}
+			
+			/* Note that we completed 1 or more delayed attribute changes; the precise object isn't known */
+			[[NSNotificationCenter defaultCenter] postNotificationName:ListObject_AttributeChangesComplete
+																object:nil
+															  userInfo:[NSDictionary dictionaryWithObject:delayedModifiedAttributeKeys
+																								   forKey:@"Keys"]];
+			 
 			[delayedModifiedAttributeKeys removeAllObjects];
 			delayedAttributeChanges = 0;
 		}
@@ -289,10 +309,10 @@
     //If no more updates are left to process, disable the update timer
 	//If there are no delayed update requests, remove the hold
 	if (!delayedUpdateTimer || !updatesOccured) {
-		if (delayedUpdateTimer) {
+		if (delayedUpdateTimer && (quietDelayedUpdatePeriodsRemaining-- <= 0)) {
 			[delayedUpdateTimer invalidate];
 			self.delayedUpdateTimer = nil;
-			updatesAreDelayedUntilInactivity = NO;
+			updatesAreDelayedUntilInactivity = NO;			
 		}
     }
 
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIListOutlineView+Drawing.m
--- a/Frameworks/Adium Framework/Source/AIListOutlineView+Drawing.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIListOutlineView+Drawing.m	Sat Oct 30 02:03:05 2010 -0500
@@ -278,6 +278,9 @@
 
 - (void)drawRect:(NSRect)rect
 {	
+	static int timesDrawn = 0;
+	NSLog(@"-[AIListOUtlineView drawRect:] Drew %i times", ++timesDrawn);
+	
 	[super drawRect:rect];
 	
 	/*	#################### Crappy Code ###################
diff -r a96bd47113d7 -r 57bb90426409 Frameworks/Adium Framework/Source/AIUserIcons.m
--- a/Frameworks/Adium Framework/Source/AIUserIcons.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Frameworks/Adium Framework/Source/AIUserIcons.m	Sat Oct 30 02:03:05 2010 -0500
@@ -422,7 +422,7 @@
 											   proportionally:YES
 											   allowAnimation:YES];
 #ifdef AIUSERICON_DEBUG
-		AILogWithSignature(@"%@ regenerated (cache? %i; listIconCache was %@)",inObject, cache, listIconCache);
+		AILogWithSignature(@"%@ regenerated (cache? %i)",inObject, cache);
 #endif
 		
 		if (cache) {
diff -r a96bd47113d7 -r 57bb90426409 Plugins/Purple Service/SLPurpleCocoaAdapter.m
--- a/Plugins/Purple Service/SLPurpleCocoaAdapter.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Plugins/Purple Service/SLPurpleCocoaAdapter.m	Sat Oct 30 02:03:05 2010 -0500
@@ -31,6 +31,7 @@
 #import <Adium/AIContentTyping.h>
 #import <Adium/AIHTMLDecoder.h>
 #import <Adium/AIListContact.h>
+#import <Adium/AIContactObserverManager.h>
 #import <Adium/AIUserIcons.h>
 #import <AIUtilities/AIImageAdditions.h>
 
@@ -164,6 +165,11 @@
 
 - (void)initLibPurple
 {
+	/* Initializing libpurple may result in loading a ton of buddies if our permit and deny lists are large; that, in
+	 * turn, would create and update a ton of contacts.
+	 */
+	[[AIContactObserverManager sharedManager] delayListObjectNotifications];
+
 	// Init the glib type system (used by GObjects)
 	g_type_init();
 	
@@ -245,6 +251,14 @@
 								   selector:@selector(networkDidChange:)
 									   name:AINetworkDidChangeNotification
 									 object:nil];
+
+	/* For any behaviors which occur on the next run loop, provide a buffer time of continued expectation of 
+	 * heavy activity.
+	 */
+	[[AIContactObserverManager sharedManager] delayListObjectNotificationsUntilInactivity];
+	
+	[[AIContactObserverManager sharedManager] endListObjectNotificationsDelay];
+
 }
 
 #pragma mark Lookup functions
diff -r a96bd47113d7 -r 57bb90426409 Source/AIListController.m
--- a/Source/AIListController.m	Fri Oct 29 21:24:47 2010 -0500
+++ b/Source/AIListController.m	Sat Oct 30 02:03:05 2010 -0500
@@ -432,9 +432,9 @@
  *
  * Resize horizontally if desired and the display name changed
  */
-- (void)listObjectAttributesChanged:(NSNotification *)notification
+- (void)listObjectAttributeChangesComplete:(NSNotification *)notification
 {	
-	[super listObjectAttributesChanged:notification];
+	[super listObjectAttributeChangesComplete:notification];
 	
 	if (((AIListObject *)notification.object).isStranger)
 		return;




More information about the commits mailing list