Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 92ce6ce

Browse files
author
Scott Goodson
committed
[ASRangeControllerBeta] Improve comments, code clarity, cache respondsToSelector:
1 parent 351f4a9 commit 92ce6ce

1 file changed

Lines changed: 27 additions & 19 deletions

File tree

AsyncDisplayKit/Details/ASRangeControllerBeta.mm

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ @interface ASRangeControllerBeta ()
2121
{
2222
BOOL _rangeIsValid;
2323
BOOL _queuedRangeUpdate;
24+
BOOL _layoutControllerImplementsSetVisibleIndexPaths;
2425
ASScrollDirection _scrollDirection;
2526
NSSet<NSIndexPath *> *_allPreviousIndexPaths;
2627
}
@@ -58,43 +59,49 @@ - (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scr
5859
});
5960
}
6061

62+
- (void)setLayoutController:(id<ASLayoutController>)layoutController
63+
{
64+
_layoutController = layoutController;
65+
_layoutControllerImplementsSetVisibleIndexPaths = [_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)];
66+
}
67+
6168
- (void)_updateVisibleNodeIndexPaths
6269
{
63-
if (!_queuedRangeUpdate) {
70+
ASDisplayNodeAssert(_layoutController, @"An ASLayoutController is required by ASRangeController");
71+
if (!_queuedRangeUpdate || !_layoutController) {
6472
return;
6573
}
6674

67-
// FIXME: Consider if we need to check this separately from the range calculation below.
75+
// TODO: Consider if we need to use this codepath, or can rely on something more similar to the data & display ranges
76+
// Example: ... = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeVisible];
6877
NSArray<NSIndexPath *> *visibleNodePaths = [_dataSource visibleNodeIndexPathsForRangeController:self];
6978

7079
if (visibleNodePaths.count == 0) { // if we don't have any visibleNodes currently (scrolled before or after content)...
7180
_queuedRangeUpdate = NO;
7281
return; // don't do anything for this update, but leave _rangeIsValid == NO to make sure we update it later
7382
}
7483

75-
CGSize viewportSize = [_dataSource viewportSizeForRangeController:self];
76-
[_layoutController setViewportSize:viewportSize];
84+
[_layoutController setViewportSize:[_dataSource viewportSizeForRangeController:self]];
7785

7886
// the layout controller needs to know what the current visible indices are to calculate range offsets
79-
if ([_layoutController respondsToSelector:@selector(setVisibleNodeIndexPaths:)]) {
87+
if (_layoutControllerImplementsSetVisibleIndexPaths) {
8088
[_layoutController setVisibleNodeIndexPaths:visibleNodePaths];
8189
}
8290

83-
NSArray<NSArray *> *allNodes = [_dataSource completedNodes]; // 2D array: section arrays, each containing nodes.
84-
NSArray<ASDisplayNode *> *currentSectionNodes = nil;
85-
NSInteger currentSectionIndex = -1; // Will be unequal to any indexPath.section, so we set currentSectionNodes.
86-
91+
// allNodes is a 2D array: it contains arrays for each section, each containing nodes.
92+
NSArray<NSArray *> *allNodes = [_dataSource completedNodes];
8793
NSUInteger numberOfSections = [allNodes count];
94+
95+
NSArray<ASDisplayNode *> *currentSectionNodes = nil;
96+
NSInteger currentSectionIndex = -1; // Set to -1 so we don't match any indexPath.section on the first iteration.
8897
NSUInteger numberOfNodesInSection = 0;
8998

90-
NSSet<NSIndexPath *> *visibleIndexPaths = [NSSet setWithArray:visibleNodePaths];
91-
// = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeVisible];
99+
NSSet<NSIndexPath *> *visibleIndexPaths = [NSSet setWithArray:visibleNodePaths];
92100
NSSet<NSIndexPath *> *displayIndexPaths = nil;
93101
NSSet<NSIndexPath *> *fetchDataIndexPaths = nil;
94-
NSMutableArray<NSIndexPath *> *modifiedIndexPaths = (RangeControllerLoggingEnabled ? [NSMutableArray array] : nil);
95102

96103
// Prioritize the order in which we visit each. Visible nodes should be updated first so they are enqueued on
97-
// the network or display queues before offscreen, preloading nodes are.
104+
// the network or display queues before preloading (offscreen) nodes are enqueued.
98105
NSMutableOrderedSet<NSIndexPath *> *allIndexPaths = [[NSMutableOrderedSet alloc] initWithSet:visibleIndexPaths];
99106

100107
ASInterfaceState selfInterfaceState = [_dataSource interfaceStateForRangeController:self];
@@ -107,20 +114,21 @@ - (void)_updateVisibleNodeIndexPaths
107114
// Typically the fetchDataIndexPaths will be the largest, and be a superset of the others, though it may be disjoint.
108115
// Because allIndexPaths is an NSMutableOrderedSet, this adds the non-duplicate items /after/ the existing items.
109116
// This means that during iteration, we will first visit visible, then display, then fetch data nodes.
110-
// Nodes within the visible range may be getting their first display and fetch data call too, so enqueue them first.
111117
[allIndexPaths unionSet:displayIndexPaths];
112118
[allIndexPaths unionSet:fetchDataIndexPaths];
113119
}
114120

115-
// Sets are magical. Add anything we had applied interfaceState to in the last update, so we can clear any
121+
// Add anything we had applied interfaceState to in the last update, but is no longer in range, so we can clear any
116122
// range flags it still has enabled. Most of the time, all but a few elements are equal; a large programmatic
117-
// scroll or major main thread stall could cause entirely disjoint sets, but we must visit all.
118-
119-
// Calling set on NSMutableOrderedSet just references the underlying data store, so we must copy it.
123+
// scroll or major main thread stall could cause entirely disjoint sets. In either case we must visit all.
124+
// Calling "-set" on NSMutableOrderedSet just references the underlying mutable data store, so we must copy it.
120125
NSSet<NSIndexPath *> *allCurrentIndexPaths = [[allIndexPaths set] copy];
121126
[allIndexPaths unionSet:_allPreviousIndexPaths];
122127
_allPreviousIndexPaths = allCurrentIndexPaths;
123-
128+
129+
// This array is only used if logging is enabled.
130+
NSMutableArray<NSIndexPath *> *modifiedIndexPaths = (RangeControllerLoggingEnabled ? [NSMutableArray array] : nil);
131+
124132
for (NSIndexPath *indexPath in allIndexPaths) {
125133
// Before a node / indexPath is exposed to ASRangeController, ASDataController should have already measured it.
126134
// For consistency, make sure each node knows that it should measure itself if something changes.

0 commit comments

Comments
 (0)