From ec7a3599bd30b3b1c4fb8890b1385d5957e0281e Mon Sep 17 00:00:00 2001 From: Levi McCallum Date: Wed, 27 Jan 2016 14:52:37 -0800 Subject: [PATCH] Add `setNeedsDataFetch` method to queue off screen `fetchData` calls --- AsyncDisplayKit/ASDisplayNode.h | 8 +++++- AsyncDisplayKit/ASDisplayNode.mm | 14 ++++++++-- AsyncDisplayKit/ASDisplayNodeExtras.h | 27 +++++++++++++++++++ .../Private/ASDisplayNodeInternal.h | 2 ++ 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/AsyncDisplayKit/ASDisplayNode.h b/AsyncDisplayKit/ASDisplayNode.h index ab3b40b524..e462e0a76b 100644 --- a/AsyncDisplayKit/ASDisplayNode.h +++ b/AsyncDisplayKit/ASDisplayNode.h @@ -442,7 +442,6 @@ NS_ASSUME_NONNULL_BEGIN * * @see displaySuspended and setNeedsDisplay */ - - (void)recursivelyClearContents; /** @@ -465,6 +464,13 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)recursivelyFetchData; +/** + * @abstract Marks the node as needing to call fetchData + * @discussion If the node is outside of the preload range, it is queued to call fetchData the next time it enters the range. + * Otherwise, fetchData is called immediately if the node is currently within the preload range. + */ +- (void)setNeedsDataFetch; + /** * @abstract Toggle displaying a placeholder over the node that covers content until the node and all subnodes are * displayed. diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 9c7cbe6d75..9921de366a 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1727,6 +1727,15 @@ static BOOL ShouldUseNewRenderingRange = YES; // subclass override } +- (void)setNeedsDataFetch +{ + if (ASInterfaceStateIncludesFetchData(_interfaceState)) { + [self fetchData]; + } else { + _needsDataFetch = YES; + } +} + // TODO: Replace this with ASDisplayNodePerformBlockOnEveryNode or enterInterfaceState: - (void)recursivelyFetchData { @@ -1793,9 +1802,10 @@ static BOOL ShouldUseNewRenderingRange = YES; BOOL nowFetchData = ASInterfaceStateIncludesFetchData(newState); BOOL wasFetchData = ASInterfaceStateIncludesFetchData(oldState); - if (nowFetchData != wasFetchData) { - if (nowFetchData) { + if (nowFetchData != wasFetchData || _needsDataFetch) { + if (nowFetchData || _needsDataFetch) { [self fetchData]; + _needsDataFetch = NO; } else { if ([self supportsRangeManagedInterfaceState]) { [self clearFetchedData]; diff --git a/AsyncDisplayKit/ASDisplayNodeExtras.h b/AsyncDisplayKit/ASDisplayNodeExtras.h index 0ab9957cc3..e453c84ea7 100644 --- a/AsyncDisplayKit/ASDisplayNodeExtras.h +++ b/AsyncDisplayKit/ASDisplayNodeExtras.h @@ -29,6 +29,33 @@ inline BOOL ASInterfaceStateIncludesFetchData(ASInterfaceState interfaceState) return ((interfaceState & ASInterfaceStateFetchData) == ASInterfaceStateFetchData); } +inline BOOL ASInterfaceStateIncludesMeasureLayout(ASInterfaceState interfaceState) +{ + return ((interfaceState & ASInterfaceStateMeasureLayout) == ASInterfaceStateMeasureLayout); +} + +inline NSString * _Nonnull NSStringFromASInterfaceState(ASInterfaceState interfaceState) +{ + NSMutableString *result = [NSMutableString stringWithString:@"{ "]; + if (interfaceState == ASInterfaceStateNone) { + [result appendString:@"No state"]; + } + if (ASInterfaceStateIncludesMeasureLayout(interfaceState)) { + [result appendString:@"MeasureLayout"]; + } + if (ASInterfaceStateIncludesFetchData(interfaceState)) { + [result appendString:@" - FetchData"]; + } + if (ASInterfaceStateIncludesDisplay(interfaceState)) { + [result appendString:@" - Display"]; + } + if (ASInterfaceStateIncludesVisible(interfaceState)) { + [result appendString:@" - Visible"]; + } + [result appendString:@" }"]; + return result; +} + NS_ASSUME_NONNULL_BEGIN ASDISPLAYNODE_EXTERN_C_BEGIN diff --git a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h index f1ffb377e9..ade418dd89 100644 --- a/AsyncDisplayKit/Private/ASDisplayNodeInternal.h +++ b/AsyncDisplayKit/Private/ASDisplayNodeInternal.h @@ -100,6 +100,8 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) } _flags; ASDisplayNodeExtraIvars _extra; + + BOOL _needsDataFetch; #if TIME_DISPLAYNODE_OPS @public