adium 3485:4915e9d4158d: Efficiency in this less-used tableview ...
commits at adium.im
commits at adium.im
Tue Nov 2 01:26:42 UTC 2010
details: http://hg.adium.im/adium/rev/4915e9d4158d
revision: 3485:4915e9d4158d
author: Evan Schoenberg
date: Mon Nov 01 20:23:44 2010 -0500
Efficiency in this less-used tableview too. Every bit helps
(transplanted from e36d4a14d24962016f2d07308151fda9485d04a0)
Subject: adium 3486:d625dad0b4c0: Work around a bug in NSTableView by implementing our own drawRowIndexes:clipRect: so we can stop drawing once we're outside the clipping rect. Fixes #14463
details: http://hg.adium.im/adium/rev/d625dad0b4c0
revision: 3486:d625dad0b4c0
author: Evan Schoenberg
date: Mon Nov 01 20:24:45 2010 -0500
Work around a bug in NSTableView by implementing our own drawRowIndexes:clipRect: so we can stop drawing once we're outside the clipping rect. Fixes #14463
(transplanted from ab8a205c5901702ac8474c7f627a991803b1aa77)
diffs (84 lines):
diff -r 8e7c971af12a -r d625dad0b4c0 Frameworks/AIUtilities Framework/Source/AIVariableHeightFlexibleColumnsOutlineView.m
--- a/Frameworks/AIUtilities Framework/Source/AIVariableHeightFlexibleColumnsOutlineView.m Mon Nov 01 18:39:31 2010 -0500
+++ b/Frameworks/AIUtilities Framework/Source/AIVariableHeightFlexibleColumnsOutlineView.m Mon Nov 01 20:24:45 2010 -0500
@@ -36,7 +36,10 @@
#pragma mark Drawing
- (void)drawRow:(NSInteger)row clipRect:(NSRect)rect
{
- if (row >= 0 && row < [self numberOfRows]) { //Somebody keeps calling this method with row = numberOfRows, which is wrong.
+ if (row >= 0 && row < [self numberOfRows]) { //Somebody keeps calling this method with row = numberOfRows, which is wrong.
+ if (NSIntersectsRect([self rectOfRow:row], rect) == FALSE)
+ return;
+
NSArray *tableColumns = [self tableColumns];
id item = [self itemAtRow:row];
NSUInteger tableColumnIndex, count = [tableColumns count];
diff -r 8e7c971af12a -r d625dad0b4c0 Frameworks/AIUtilities Framework/Source/AIVariableHeightOutlineView.m
--- a/Frameworks/AIUtilities Framework/Source/AIVariableHeightOutlineView.m Mon Nov 01 18:39:31 2010 -0500
+++ b/Frameworks/AIUtilities Framework/Source/AIVariableHeightOutlineView.m Mon Nov 01 20:24:45 2010 -0500
@@ -232,14 +232,21 @@
}
}
-- (void)drawRow:(NSInteger)row clipRect:(NSRect)rect
+/*!
+ * @brief Our implementation of drawRow:clipRect: which returns whether the row was drawn
+ *
+ * This is very useful if you are iterating rows in sequence. If drawRowIndexes:clipRect: is passed 1000 rows,
+ * but row 61 is outside the clip rect, rows 62 through 1000 will also be outside the clip rect. Although
+ * -[self rectOfRow:] is reasonable cheap once, it can get quite expensive additively. See for example #14463 (700 Twitter contacts).
+ */
+- (BOOL)_ai_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;
+ return NO;
NSArray *tableColumns = [self tableColumns];
id item = [self itemAtRow:row];
@@ -273,6 +280,41 @@
[cell drawWithFrame:cellFrame inView:self];
}
}
+
+ return YES;
+}
+
+
+- (void)drawRow:(NSInteger)row clipRect:(NSRect)rect
+{
+ (void)[self _ai_drawRow:row clipRect:rect];
+}
+
+/*!
+ * @brief Override drawRowIndexes:clipRect: to stop when we're outside the clipRect.
+ *
+ * When -[NSTableView drawRect:] is called before any table view data is cached, it will pass every row of the table
+ * in indexes - not just those we'll soon know are outside of clipRect, which it does on subsequent calls.
+ *
+ * That's okay for a small table, but if, say, 1000 rows are in the list, it's expensive to check each one to see
+ * if it should be displayed.
+ */
+- (void)drawRowIndexes:(NSIndexSet *)indexes clipRect:(NSRect)clipRect
+{
+ NSUInteger bufSize = indexes.count;
+ NSUInteger *buf = malloc(bufSize * sizeof(NSUInteger));
+ NSUInteger i;
+
+ NSRange range = NSMakeRange(indexes.firstIndex, (indexes.lastIndex - indexes.firstIndex) + 1);
+ [indexes getIndexes:buf maxCount:bufSize inIndexRange:&range];
+
+ for (i = 0; i != bufSize; i++) {
+ /* draw until we're outside the clip rect.... */
+ if (![self _ai_drawRow:buf[i] clipRect:clipRect])
+ break;
+ }
+
+ free(buf);
}
- (NSImage *)dragImageForRows:(NSUInteger *)buf count:(NSUInteger)count tableColumns:(NSArray *)tableColumns event:(NSEvent*)dragEvent offset:(NSPointPointer)dragImageOffset
More information about the commits
mailing list