mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
Range controller registers to rendering engine and extern to full range if needed
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
#import "ASCellNode.h"
|
#import "ASCellNode.h"
|
||||||
|
|
||||||
NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority;
|
NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority;
|
||||||
|
NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification = @"ASRenderingEngineDidDisplayScheduledNodes";
|
||||||
|
|
||||||
@interface _ASDisplayNodePosition : NSObject
|
@interface _ASDisplayNodePosition : NSObject
|
||||||
|
|
||||||
@@ -279,6 +280,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
for (ASDisplayNode *node in displayingNodes) {
|
for (ASDisplayNode *node in displayingNodes) {
|
||||||
[node __recursivelyTriggerDisplayAndBlock:NO];
|
[node __recursivelyTriggerDisplayAndBlock:NO];
|
||||||
}
|
}
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:ASRenderingEngineDidDisplayScheduledNodesNotification
|
||||||
|
object:nil];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@interface ASAbstractLayoutController () {
|
@interface ASAbstractLayoutController () {
|
||||||
std::vector<ASRangeTuningParameters> _tuningParameters;
|
std::vector<std::vector<ASRangeTuningParameters>> _tuningParameters;
|
||||||
std::vector<ASRangeTuningParameters> _minimumTuningParameters;
|
|
||||||
CGSize _viewportSize;
|
CGSize _viewportSize;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
@@ -25,33 +24,33 @@
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
_tuningParameters = std::vector<ASRangeTuningParameters>(ASLayoutRangeTypeCount);
|
_tuningParameters = std::vector<std::vector<ASRangeTuningParameters>> (ASLayoutRangeModeCount, std::vector<ASRangeTuningParameters> (ASLayoutRangeTypeCount));
|
||||||
_tuningParameters[ASLayoutRangeTypeVisible] = {
|
|
||||||
|
_tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypeVisible] = {
|
||||||
.leadingBufferScreenfuls = 0,
|
.leadingBufferScreenfuls = 0,
|
||||||
.trailingBufferScreenfuls = 0
|
.trailingBufferScreenfuls = 0
|
||||||
};
|
};
|
||||||
_tuningParameters[ASLayoutRangeTypeDisplay] = {
|
_tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypeDisplay] = {
|
||||||
.leadingBufferScreenfuls = 1.5,
|
|
||||||
.trailingBufferScreenfuls = 0.75
|
|
||||||
};
|
|
||||||
_tuningParameters[ASLayoutRangeTypeFetchData] = {
|
|
||||||
.leadingBufferScreenfuls = 3,
|
|
||||||
.trailingBufferScreenfuls = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
_minimumTuningParameters = std::vector<ASRangeTuningParameters>(ASLayoutRangeTypeCount);
|
|
||||||
_minimumTuningParameters[ASLayoutRangeTypeVisible] = {
|
|
||||||
.leadingBufferScreenfuls = 0,
|
|
||||||
.trailingBufferScreenfuls = 0
|
|
||||||
};
|
|
||||||
_minimumTuningParameters[ASLayoutRangeTypeDisplay] = {
|
|
||||||
.leadingBufferScreenfuls = 0.25,
|
.leadingBufferScreenfuls = 0.25,
|
||||||
.trailingBufferScreenfuls = 0.25
|
.trailingBufferScreenfuls = 0.25
|
||||||
};
|
};
|
||||||
_minimumTuningParameters[ASLayoutRangeTypeFetchData] = {
|
_tuningParameters[ASLayoutRangeModeMinimum][ASLayoutRangeTypeFetchData] = {
|
||||||
.leadingBufferScreenfuls = 1,
|
.leadingBufferScreenfuls = 1,
|
||||||
.trailingBufferScreenfuls = 1
|
.trailingBufferScreenfuls = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypeVisible] = {
|
||||||
|
.leadingBufferScreenfuls = 0,
|
||||||
|
.trailingBufferScreenfuls = 0
|
||||||
|
};
|
||||||
|
_tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypeDisplay] = {
|
||||||
|
.leadingBufferScreenfuls = 1.5,
|
||||||
|
.trailingBufferScreenfuls = 0.75
|
||||||
|
};
|
||||||
|
_tuningParameters[ASLayoutRangeModeFull][ASLayoutRangeTypeFetchData] = {
|
||||||
|
.leadingBufferScreenfuls = 3,
|
||||||
|
.trailingBufferScreenfuls = 2
|
||||||
|
};
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@@ -60,33 +59,28 @@
|
|||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(rangeType < _tuningParameters.size(), @"Requesting a range that is OOB for the configured tuning parameters");
|
return [self tuningParametersForRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
|
||||||
return _tuningParameters[rangeType];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(rangeType < _tuningParameters.size(), @"Requesting a range that is OOB for the configured tuning parameters");
|
return [self setTuningParameters:tuningParameters forRangeMode:ASLayoutRangeModeFull rangeType:rangeType];
|
||||||
ASDisplayNodeAssert(rangeType != ASLayoutRangeTypeVisible, @"Must not set Visible range tuning parameters (always 0, 0)");
|
|
||||||
_tuningParameters[rangeType] = tuningParameters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASRangeTuningParameters)minimumTuningParametersForRangeType:(ASLayoutRangeType)rangeType
|
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(rangeType < _minimumTuningParameters.size(), @"Requesting a range that is OOB for the configured minimum tuning parameters");
|
ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(),
|
||||||
return _minimumTuningParameters[rangeType];
|
@"Requesting a range that is OOB for the configured tuning parameters");
|
||||||
|
return _tuningParameters[rangeMode][rangeType];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setMinimumTuningParameters:(ASRangeTuningParameters)minimumTuningParameters forRangeType:(ASLayoutRangeType)rangeType
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(rangeType < _minimumTuningParameters.size(), @"Requesting a range that is OOB for the configured minimum tuning parameters");
|
ASDisplayNodeAssert(rangeMode < _tuningParameters.size() && rangeType < _tuningParameters[rangeMode].size(),
|
||||||
ASDisplayNodeAssert(rangeType != ASLayoutRangeTypeVisible, @"Must not set Visible range minimum tuning parameters (always 0, 0)");
|
@"Setting a range that is OOB for the configured tuning parameters");
|
||||||
_minimumTuningParameters[rangeType] = minimumTuningParameters;
|
ASDisplayNodeAssert(rangeType != ASLayoutRangeTypeVisible,
|
||||||
}
|
@"Must not set Visible range minimum tuning parameters (always 0, 0)");
|
||||||
|
_tuningParameters[rangeMode][rangeType] = tuningParameters;
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType isFullRange:(BOOL)isFullRange
|
|
||||||
{
|
|
||||||
return isFullRange ? [self tuningParametersForRangeType:rangeType] : [self minimumTuningParametersForRangeType:rangeType];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Abstract Index Path Range Support
|
#pragma mark - Abstract Index Path Range Support
|
||||||
@@ -98,7 +92,7 @@
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType shouldUseFullRange:(BOOL)shouldUseFullRange
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssertNotSupported();
|
ASDisplayNodeAssertNotSupported();
|
||||||
return nil;
|
return nil;
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType shouldUseFullRange:(BOOL)shouldUseFullRange
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeType:rangeType isFullRange:shouldUseFullRange];
|
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeMode:rangeMode rangeType:rangeType];
|
||||||
ASRangeGeometry rangeGeometry = [self rangeGeometryWithScrollDirection:scrollDirection tuningParameters:tuningParameters];
|
ASRangeGeometry rangeGeometry = [self rangeGeometryWithScrollDirection:scrollDirection tuningParameters:tuningParameters];
|
||||||
_updateRangeBoundsIndexedByRangeType[rangeType] = rangeGeometry.updateBounds;
|
_updateRangeBoundsIndexedByRangeType[rangeType] = rangeGeometry.updateBounds;
|
||||||
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds];
|
return [self indexPathsForItemsWithinRangeBounds:rangeGeometry.rangeBounds];
|
||||||
@@ -133,9 +133,9 @@ typedef struct ASRangeGeometry ASRangeGeometry;
|
|||||||
|
|
||||||
@implementation ASCollectionViewLayoutControllerBeta
|
@implementation ASCollectionViewLayoutControllerBeta
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType shouldUseFullRange:(BOOL)shouldUseFullRange
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeType:rangeType isFullRange:shouldUseFullRange];
|
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeMode:rangeMode rangeType:rangeType];
|
||||||
CGRect rangeBounds = [self rangeBoundsWithScrollDirection:scrollDirection rangeTuningParameters:tuningParameters];
|
CGRect rangeBounds = [self rangeBoundsWithScrollDirection:scrollDirection rangeTuningParameters:tuningParameters];
|
||||||
return [self indexPathsForItemsWithinRangeBounds:rangeBounds];
|
return [self indexPathsForItemsWithinRangeBounds:rangeBounds];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
* IndexPath array for the element in the working range.
|
* IndexPath array for the element in the working range.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType shouldUseFullRange:(BOOL)shouldUseFullRange
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType
|
||||||
{
|
{
|
||||||
CGFloat viewportScreenMetric;
|
CGFloat viewportScreenMetric;
|
||||||
ASScrollDirection leadingDirection;
|
ASScrollDirection leadingDirection;
|
||||||
@@ -92,7 +92,7 @@ static const CGFloat kASFlowLayoutControllerRefreshingThreshold = 0.3;
|
|||||||
leadingDirection = ASScrollDirectionUp;
|
leadingDirection = ASScrollDirectionUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeType:rangeType isFullRange:shouldUseFullRange];
|
ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeMode:rangeMode rangeType:rangeType];
|
||||||
CGFloat backScreens = scrollDirection == leadingDirection ? tuningParameters.leadingBufferScreenfuls : tuningParameters.trailingBufferScreenfuls;
|
CGFloat backScreens = scrollDirection == leadingDirection ? tuningParameters.leadingBufferScreenfuls : tuningParameters.trailingBufferScreenfuls;
|
||||||
CGFloat frontScreens = scrollDirection == leadingDirection ? tuningParameters.trailingBufferScreenfuls : tuningParameters.leadingBufferScreenfuls;
|
CGFloat frontScreens = scrollDirection == leadingDirection ? tuningParameters.trailingBufferScreenfuls : tuningParameters.leadingBufferScreenfuls;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@class ASCellNode;
|
@class ASCellNode;
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSUInteger, ASLayoutRangeMode) {
|
||||||
|
ASLayoutRangeModeMinimum = 0,
|
||||||
|
ASLayoutRangeModeFull,
|
||||||
|
ASLayoutRangeModeCount
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CGFloat leadingBufferScreenfuls;
|
CGFloat leadingBufferScreenfuls;
|
||||||
CGFloat trailingBufferScreenfuls;
|
CGFloat trailingBufferScreenfuls;
|
||||||
@@ -24,23 +30,30 @@ typedef struct {
|
|||||||
@protocol ASLayoutController <NSObject>
|
@protocol ASLayoutController <NSObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tuning parameters for the range.
|
* Tuning parameters for the range type in full mode. This method is deprecated.
|
||||||
|
* Instead, use -setTuningParameters:forRangeMode:rangeType:
|
||||||
|
*
|
||||||
|
* @see setTuningParameters:forRangeMode:rangeType:
|
||||||
*/
|
*/
|
||||||
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType ASDISPLAYNODE_DEPRECATED;
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
/**
|
||||||
|
* Get tuning parameters for the range type in full mode. This method is deprecated.
|
||||||
|
* Instead, use -tuningParametersForRangeMode:rangeType:
|
||||||
|
*
|
||||||
|
* @see tuningParametersForRangeMode:rangeType:
|
||||||
|
*/
|
||||||
|
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType ASDISPLAYNODE_DEPRECATED;
|
||||||
|
|
||||||
- (void)setMinimumTuningParameters:(ASRangeTuningParameters)minimumTuningParameters forRangeType:(ASLayoutRangeType)rangeType;
|
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (ASRangeTuningParameters)minimumTuningParametersForRangeType:(ASLayoutRangeType)rangeType;
|
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType isFullRange:(BOOL)isFullRange;
|
|
||||||
|
|
||||||
// FIXME: This method can be removed once ASRangeControllerBeta becomes the main version.
|
// FIXME: This method can be removed once ASRangeControllerBeta becomes the main version.
|
||||||
// TODO: Now that it is the main version, can we remove this now?
|
// TODO: Now that it is the main version, can we remove this now?
|
||||||
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray<NSIndexPath *> *)indexPaths rangeType:(ASLayoutRangeType)rangeType;
|
- (BOOL)shouldUpdateForVisibleIndexPaths:(NSArray<NSIndexPath *> *)indexPaths rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeType:(ASLayoutRangeType)rangeType shouldUseFullRange:(BOOL)shouldUseFullRange;
|
- (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,9 @@
|
|||||||
id<ASRangeHandler> rangeHandler = _rangeTypeHandlers[rangeKey];
|
id<ASRangeHandler> rangeHandler = _rangeTypeHandlers[rangeKey];
|
||||||
|
|
||||||
if (!_rangeIsValid || [_layoutController shouldUpdateForVisibleIndexPaths:visibleNodePaths rangeType:rangeType]) {
|
if (!_rangeIsValid || [_layoutController shouldUpdateForVisibleIndexPaths:visibleNodePaths rangeType:rangeType]) {
|
||||||
NSSet *indexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:rangeType shouldUseFullRange:YES];
|
NSSet *indexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
||||||
|
rangeMode:ASLayoutRangeModeFull
|
||||||
|
rangeType:rangeType];
|
||||||
|
|
||||||
// Notify to remove indexpaths that are leftover that are not visible or included in the _layoutController calculated paths
|
// Notify to remove indexpaths that are leftover that are not visible or included in the _layoutController calculated paths
|
||||||
NSMutableSet *removedIndexPaths = _rangeIsValid ? [_rangeTypeIndexPaths[rangeKey] mutableCopy] : [NSMutableSet set];
|
NSMutableSet *removedIndexPaths = _rangeIsValid ? [_rangeTypeIndexPaths[rangeKey] mutableCopy] : [NSMutableSet set];
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#import "ASAssert.h"
|
#import "ASAssert.h"
|
||||||
#import "ASDisplayNodeExtras.h"
|
#import "ASDisplayNodeExtras.h"
|
||||||
|
#import "ASDisplayNodeInternal.h"
|
||||||
#import "ASMultiDimensionalArrayUtils.h"
|
#import "ASMultiDimensionalArrayUtils.h"
|
||||||
#import "ASRangeHandlerVisible.h"
|
#import "ASRangeHandlerVisible.h"
|
||||||
#import "ASRangeHandlerRender.h"
|
#import "ASRangeHandlerRender.h"
|
||||||
@@ -17,12 +18,6 @@
|
|||||||
#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;
|
||||||
@@ -30,7 +25,8 @@ typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
|
|||||||
BOOL _layoutControllerImplementsSetVisibleIndexPaths;
|
BOOL _layoutControllerImplementsSetVisibleIndexPaths;
|
||||||
ASScrollDirection _scrollDirection;
|
ASScrollDirection _scrollDirection;
|
||||||
NSSet<NSIndexPath *> *_allPreviousIndexPaths;
|
NSSet<NSIndexPath *> *_allPreviousIndexPaths;
|
||||||
ASRangeTypeUsed _rangeTypeUsed;
|
ASLayoutRangeMode _currentRangeMode;
|
||||||
|
BOOL _didRegisterForNotifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -44,13 +40,41 @@ typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_rangeIsValid = YES;
|
_rangeIsValid = YES;
|
||||||
_rangeTypeUsed = ASRangeTypeUsedNone;
|
_currentRangeMode = ASLayoutRangeModeCount;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if (_didRegisterForNotifications) {
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Core visible node range managment API
|
#pragma mark - Core visible node range managment API
|
||||||
|
|
||||||
|
+ (ASLayoutRangeMode)rangeModeForInterfaceState:(ASInterfaceState)interfaceState
|
||||||
|
scrollDirection:(ASScrollDirection)scrollDirection
|
||||||
|
currentRangeMode:(ASLayoutRangeMode)currentRangeMode
|
||||||
|
{
|
||||||
|
// If we used full mode, don't switch to minimum mode. That will destroy all the hard work done before.
|
||||||
|
if (currentRangeMode == ASLayoutRangeModeFull) {
|
||||||
|
return ASLayoutRangeModeFull;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL isVisible = (ASInterfaceStateIncludesVisible(interfaceState));
|
||||||
|
BOOL isScrolling = (scrollDirection != ASScrollDirectionNone);
|
||||||
|
BOOL isUsingMinimumRangeMode = (currentRangeMode == ASLayoutRangeModeMinimum);
|
||||||
|
// 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 finished displaying minimum mode, extend to full mode
|
||||||
|
if (isVisible && (isScrolling || isUsingMinimumRangeMode)) {
|
||||||
|
return ASLayoutRangeModeFull;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ASLayoutRangeModeMinimum;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
|
- (void)visibleNodeIndexPathsDidChangeWithScrollDirection:(ASScrollDirection)scrollDirection
|
||||||
{
|
{
|
||||||
_scrollDirection = scrollDirection;
|
_scrollDirection = scrollDirection;
|
||||||
@@ -62,7 +86,7 @@ typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
|
|||||||
if (_queuedRangeUpdate) {
|
if (_queuedRangeUpdate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// coalesce these events -- handling them multiple times per runloop is noisy and expensive
|
// coalesce these events -- handling them multiple times per runloop is noisy and expensive
|
||||||
_queuedRangeUpdate = YES;
|
_queuedRangeUpdate = YES;
|
||||||
|
|
||||||
@@ -117,25 +141,25 @@ typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
|
|||||||
NSMutableOrderedSet<NSIndexPath *> *allIndexPaths = [[NSMutableOrderedSet alloc] initWithSet:visibleIndexPaths];
|
NSMutableOrderedSet<NSIndexPath *> *allIndexPaths = [[NSMutableOrderedSet alloc] initWithSet:visibleIndexPaths];
|
||||||
|
|
||||||
ASInterfaceState selfInterfaceState = [_dataSource interfaceStateForRangeController:self];
|
ASInterfaceState selfInterfaceState = [_dataSource interfaceStateForRangeController:self];
|
||||||
BOOL selfIsVisible = (ASInterfaceStateIncludesVisible(selfInterfaceState));
|
ASLayoutRangeMode rangeMode = [ASRangeControllerBeta rangeModeForInterfaceState:selfInterfaceState
|
||||||
BOOL selfIsScrolling = (_scrollDirection != ASScrollDirectionNone);
|
scrollDirection:_scrollDirection
|
||||||
BOOL didUseMinimumRange = (_rangeTypeUsed == ASRangeTypeUsedMinimum);
|
currentRangeMode:_currentRangeMode];
|
||||||
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 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.
|
|
||||||
BOOL useFullRange = ((selfIsVisible && (selfIsScrolling || didUseMinimumRange)) || didUseFullRange);
|
|
||||||
NSLog(@"%@ range: %@", useFullRange ? @"Full" : @"Minimum", [((ASCollectionView *)_delegate).asyncDelegate description]);
|
|
||||||
|
|
||||||
fetchDataIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection rangeType:ASLayoutRangeTypeFetchData shouldUseFullRange:useFullRange];
|
fetchDataIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
||||||
|
rangeMode:rangeMode
|
||||||
|
rangeType:ASLayoutRangeTypeFetchData];
|
||||||
|
|
||||||
ASRangeTuningParameters parametersDisplay = [_layoutController tuningParametersForRangeType:ASLayoutRangeTypeDisplay isFullRange:useFullRange];
|
ASRangeTuningParameters parametersDisplay = [_layoutController tuningParametersForRangeMode:rangeMode
|
||||||
ASRangeTuningParameters parametersFetchData = [_layoutController tuningParametersForRangeType:ASLayoutRangeTypeFetchData isFullRange:useFullRange];
|
rangeType:ASLayoutRangeTypeDisplay];
|
||||||
|
ASRangeTuningParameters parametersFetchData = [_layoutController tuningParametersForRangeMode:rangeMode
|
||||||
|
rangeType:ASLayoutRangeTypeFetchData];
|
||||||
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:useFullRange];
|
displayIndexPaths = [_layoutController indexPathsForScrolling:_scrollDirection
|
||||||
|
rangeMode:rangeMode
|
||||||
|
rangeType:ASLayoutRangeTypeDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -151,11 +175,13 @@ typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
|
|||||||
NSSet<NSIndexPath *> *allCurrentIndexPaths = [[allIndexPaths set] copy];
|
NSSet<NSIndexPath *> *allCurrentIndexPaths = [[allIndexPaths set] copy];
|
||||||
[allIndexPaths unionSet:_allPreviousIndexPaths];
|
[allIndexPaths unionSet:_allPreviousIndexPaths];
|
||||||
_allPreviousIndexPaths = allCurrentIndexPaths;
|
_allPreviousIndexPaths = allCurrentIndexPaths;
|
||||||
_rangeTypeUsed = useFullRange ? ASRangeTypeUsedFull : ASRangeTypeUsedMinimum;
|
_currentRangeMode = rangeMode;
|
||||||
|
|
||||||
if (!_rangeIsValid) {
|
if (!_rangeIsValid) {
|
||||||
[allIndexPaths addObjectsFromArray:ASIndexPathsForMultidimensionalArray(allNodes)];
|
[allIndexPaths addObjectsFromArray:ASIndexPathsForMultidimensionalArray(allNodes)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self registerForNotificationsIfNeeded];
|
||||||
|
|
||||||
// This array is only used if logging is enabled.
|
// This array is only used if logging is enabled.
|
||||||
NSMutableArray<NSIndexPath *> *modifiedIndexPaths = (RangeControllerLoggingEnabled ? [NSMutableArray array] : nil);
|
NSMutableArray<NSIndexPath *> *modifiedIndexPaths = (RangeControllerLoggingEnabled ? [NSMutableArray array] : nil);
|
||||||
@@ -240,6 +266,33 @@ typedef NS_ENUM(NSUInteger, ASRangeTypeUsed) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Notification observers
|
||||||
|
|
||||||
|
- (void)registerForNotificationsIfNeeded
|
||||||
|
{
|
||||||
|
if (!_didRegisterForNotifications) {
|
||||||
|
BOOL selfInterfaceState = [_dataSource interfaceStateForRangeController:self];
|
||||||
|
ASLayoutRangeMode nextRangeMode = [ASRangeControllerBeta rangeModeForInterfaceState:selfInterfaceState
|
||||||
|
scrollDirection:_scrollDirection
|
||||||
|
currentRangeMode:_currentRangeMode];
|
||||||
|
if (_currentRangeMode != nextRangeMode) {
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(scheduledNodesDidDisplay)
|
||||||
|
name:ASRenderingEngineDidDisplayScheduledNodesNotification
|
||||||
|
object:nil];
|
||||||
|
_didRegisterForNotifications = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)scheduledNodesDidDisplay
|
||||||
|
{
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
_didRegisterForNotifications = NO;
|
||||||
|
|
||||||
|
[self scheduleRangeUpdate];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Cell node view handling
|
#pragma mark - Cell node view handling
|
||||||
|
|
||||||
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node
|
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides)
|
|||||||
@class _ASPendingState;
|
@class _ASPendingState;
|
||||||
@class _ASDisplayNodePosition;
|
@class _ASDisplayNodePosition;
|
||||||
|
|
||||||
|
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification;
|
||||||
|
|
||||||
// Allow 2^n increments of begin disabling hierarchy notifications
|
// Allow 2^n increments of begin disabling hierarchy notifications
|
||||||
#define VISIBILITY_NOTIFICATIONS_DISABLED_BITS 4
|
#define VISIBILITY_NOTIFICATIONS_DISABLED_BITS 4
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user