Better decision on when to use full range

This commit is contained in:
Huy Nguyen 2016-02-01 22:14:03 -08:00
parent 191d978154
commit 1145b6e40e

View File

@ -17,6 +17,12 @@
#import "ASInternalHelpers.h" #import "ASInternalHelpers.h"
#import "ASDisplayNode+FrameworkPrivate.h" #import "ASDisplayNode+FrameworkPrivate.h"
typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
ASRangeTypeUsedNone,
ASRangeTypeUsedMinimum,
ASRangeTypeUsedFull,
};
@interface ASRangeControllerBeta () @interface ASRangeControllerBeta ()
{ {
BOOL _rangeIsValid; BOOL _rangeIsValid;
@ -24,7 +30,7 @@
BOOL _layoutControllerImplementsSetVisibleIndexPaths; BOOL _layoutControllerImplementsSetVisibleIndexPaths;
ASScrollDirection _scrollDirection; ASScrollDirection _scrollDirection;
NSSet<NSIndexPath *> *_allPreviousIndexPaths; NSSet<NSIndexPath *> *_allPreviousIndexPaths;
BOOL _didUseFullRange; ASRangeTypeUsed _rangeTypeUsed;
} }
@end @end
@ -38,6 +44,7 @@
} }
_rangeIsValid = YES; _rangeIsValid = YES;
_rangeTypeUsed = ASRangeTypeUsedNone;
return self; return self;
} }
@ -47,7 +54,11 @@
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection - (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
{ {
_scrollDirection = scrollDirection; _scrollDirection = scrollDirection;
[self scheduleRangeUpdate];
}
- (void)scheduleRangeUpdate
{
if (_queuedRangeUpdate) { if (_queuedRangeUpdate) {
return; return;
} }
@ -108,19 +119,23 @@
ASInterfaceState selfInterfaceState = [_dataSource interfaceStateForRangeController:self]; ASInterfaceState selfInterfaceState = [_dataSource interfaceStateForRangeController:self];
BOOL selfIsVisible = (ASInterfaceStateIncludesVisible(selfInterfaceState)); BOOL selfIsVisible = (ASInterfaceStateIncludesVisible(selfInterfaceState));
BOOL selfIsScrolling = (_scrollDirection != ASScrollDirectionNone); BOOL selfIsScrolling = (_scrollDirection != ASScrollDirectionNone);
BOOL didUseMinimumRange = (_rangeTypeUsed == ASRangeTypeUsedMinimum);
BOOL didUseFullRange = (_rangeTypeUsed == ASRangeTypeUsedFull);
// If we are already visible and scrolling, get busy! Better get started on preloading before the user scrolls more... // If we are already visible and scrolling, get busy! Better get started on preloading before the user scrolls more...
// If we are already visible and did finish displaying minimum range, extend to full range
// If we used full range, don't switch to minimum range now. That will destroy all the hard work done before. // If we used full range, don't switch to minimum range now. That will destroy all the hard work done before.
BOOL shouldUseFullRange = ((selfIsVisible && selfIsScrolling) || _didUseFullRange); BOOL useFullRange = ((selfIsVisible && (selfIsScrolling || didUseMinimumRange)) || didUseFullRange);
NSLog(@"%@ range: %@", useFullRange ? @"Full" : @"Minimum", [((ASCollectionView *)_delegate).asyncDelegate description]);
fetchDataIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeFetchData shouldUseFullRange:shouldUseFullRange]; fetchDataIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeFetchData shouldUseFullRange:useFullRange];
ASRangeTuningParameters parametersDisplay = [_layoutController tuningParametersForRangeType:ASLayoutRangeTypeDisplay isFullRange:shouldUseFullRange]; ASRangeTuningParameters parametersDisplay = [_layoutController tuningParametersForRangeType:ASLayoutRangeTypeDisplay isFullRange:useFullRange];
ASRangeTuningParameters parametersFetchData = [_layoutController tuningParametersForRangeType:ASLayoutRangeTypeFetchData isFullRange:shouldUseFullRange]; ASRangeTuningParameters parametersFetchData = [_layoutController tuningParametersForRangeType:ASLayoutRangeTypeFetchData isFullRange:useFullRange];
if (parametersDisplay.leadingBufferScreenfuls == parametersFetchData.leadingBufferScreenfuls && if (parametersDisplay.leadingBufferScreenfuls == parametersFetchData.leadingBufferScreenfuls &&
parametersDisplay.trailingBufferScreenfuls == parametersFetchData.trailingBufferScreenfuls) { parametersDisplay.trailingBufferScreenfuls == parametersFetchData.trailingBufferScreenfuls) {
displayIndexPaths = fetchDataIndexPaths; displayIndexPaths = fetchDataIndexPaths;
} else { } else {
displayIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeDisplay shouldUseFullRange:shouldUseFullRange]; displayIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeDisplay shouldUseFullRange:useFullRange];
} }
// Typically the fetchDataIndexPaths will be the largest, and be a superset of the others, though it may be disjoint. // Typically the fetchDataIndexPaths will be the largest, and be a superset of the others, though it may be disjoint.
@ -136,7 +151,7 @@
NSSet<NSIndexPath *> *allCurrentIndexPaths = [[allIndexPaths set] copy]; NSSet<NSIndexPath *> *allCurrentIndexPaths = [[allIndexPaths set] copy];
[allIndexPaths unionSet:_allPreviousIndexPaths]; [allIndexPaths unionSet:_allPreviousIndexPaths];
_allPreviousIndexPaths = allCurrentIndexPaths; _allPreviousIndexPaths = allCurrentIndexPaths;
_didUseFullRange = shouldUseFullRange; _rangeTypeUsed = useFullRange ? ASRangeTypeUsedFull : ASRangeTypeUsedMinimum;
if (!_rangeIsValid) { if (!_rangeIsValid) {
[allIndexPaths addObjectsFromArray:ASIndexPathsForMultidimensionalArray(allNodes)]; [allIndexPaths addObjectsFromArray:ASIndexPathsForMultidimensionalArray(allNodes)];