Wrap implicit node hierarchy management behind feature flag property

This commit is contained in:
Levi McCallum 2016-02-10 19:21:29 -08:00
parent 5fa3b53503
commit b267821d4c
4 changed files with 37 additions and 17 deletions

View File

@ -39,6 +39,8 @@
/** @name Layout Transitioning */ /** @name Layout Transitioning */
@property (nonatomic) BOOL usesImplicitHierarchyManagement;
/** /**
* @discussion A place to perform your animation. New nodes have been inserted here. You can also use this time to re-order the hierarchy. * @discussion A place to perform your animation. New nodes have been inserted here. You can also use this time to re-order the hierarchy.
*/ */

View File

@ -32,7 +32,7 @@ NSInteger const ASDefaultDrawingPriority = ASDefaultTransactionPriority;
NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification = @"ASRenderingEngineDidDisplayScheduledNodes"; NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification = @"ASRenderingEngineDidDisplayScheduledNodes";
NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp"; NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp";
@interface ASDisplayNode () <UIGestureRecognizerDelegate> @interface ASDisplayNode () <UIGestureRecognizerDelegate, _ASDisplayLayerDelegate, _ASTransitionContextDelegate>
/** /**
* *
@ -54,12 +54,6 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
#define TIME_SCOPED(outVar) #define TIME_SCOPED(outVar)
#endif #endif
@interface ASDisplayNode () <_ASDisplayLayerDelegate, _ASTransitionContextDelegate>
@property (assign, nonatomic) BOOL implicitNodeHierarchyManagement;
@end
@implementation ASDisplayNode @implementation ASDisplayNode
// these dynamic properties all defined in ASLayoutOptionsPrivate.m // these dynamic properties all defined in ASLayoutOptionsPrivate.m
@ -611,7 +605,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize - (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
{ {
return [self measureWithSizeRange:constrainedSize completion:^{ return [self measureWithSizeRange:constrainedSize completion:^{
if ([[self class] usesImplicitHierarchyManagement]) { if (self.usesImplicitHierarchyManagement) {
[self __implicitlyInsertSubnodes]; [self __implicitlyInsertSubnodes];
[self __implicitlyRemoveSubnodes]; [self __implicitlyRemoveSubnodes];
} }
@ -640,7 +634,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
_previousConstrainedSize = _constrainedSize; _previousConstrainedSize = _constrainedSize;
_constrainedSize = constrainedSize; _constrainedSize = constrainedSize;
[self __calculateSubnodeOperationsWithLayout:_layout previousLayout:_previousLayout]; if (self.usesImplicitHierarchyManagement) {
[self __calculateSubnodeOperations];
}
_flags.isMeasured = YES; _flags.isMeasured = YES;
completion(); completion();
@ -657,32 +653,34 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (ASLayout *)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize animated:(BOOL)animated - (ASLayout *)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize animated:(BOOL)animated
{ {
_usesImplicitHierarchyManagement = YES; // Temporary flag for 1.9.x
return [self measureWithSizeRange:constrainedSize completion:^{ return [self measureWithSizeRange:constrainedSize completion:^{
_usesImplicitHierarchyManagement = NO; // Temporary flag for 1.9.x
_transitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated delegate:self]; _transitionContext = [[_ASTransitionContext alloc] initWithAnimation:animated delegate:self];
[self __implicitlyInsertSubnodes]; [self __implicitlyInsertSubnodes];
[self animateLayoutTransition:_transitionContext]; [self animateLayoutTransition:_transitionContext];
}]; }];
} }
- (void)__calculateSubnodeOperationsWithLayout:(ASLayout *)layout previousLayout:(ASLayout *)previousLayout - (void)__calculateSubnodeOperations
{ {
if (previousLayout) { if (_previousLayout) {
NSIndexSet *insertions, *deletions; NSIndexSet *insertions, *deletions;
[previousLayout.immediateSublayouts asdk_diffWithArray:layout.immediateSublayouts [_previousLayout.immediateSublayouts asdk_diffWithArray:_layout.immediateSublayouts
insertions:&insertions insertions:&insertions
deletions:&deletions deletions:&deletions
compareBlock:^BOOL(ASLayout *lhs, ASLayout *rhs) { compareBlock:^BOOL(ASLayout *lhs, ASLayout *rhs) {
return ASObjectIsEqual(lhs.layoutableObject, rhs.layoutableObject); return ASObjectIsEqual(lhs.layoutableObject, rhs.layoutableObject);
}]; }];
filterNodesInLayoutAtIndexes(layout, insertions, &_insertedSubnodes, &_insertedSubnodePositions); filterNodesInLayoutAtIndexes(_layout, insertions, &_insertedSubnodes, &_insertedSubnodePositions);
filterNodesInLayoutAtIndexesWithIntersectingNodes(previousLayout, filterNodesInLayoutAtIndexesWithIntersectingNodes(_previousLayout,
deletions, deletions,
_insertedSubnodes, _insertedSubnodes,
&_removedSubnodes, &_removedSubnodes,
&_removedSubnodePositions); &_removedSubnodePositions);
} else { } else {
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [layout.immediateSublayouts count])]; NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [_layout.immediateSublayouts count])];
filterNodesInLayoutAtIndexes(layout, indexes, &_insertedSubnodes, &_insertedSubnodePositions); filterNodesInLayoutAtIndexes(_layout, indexes, &_insertedSubnodes, &_insertedSubnodePositions);
_removedSubnodes = nil; _removedSubnodes = nil;
} }
} }
@ -768,6 +766,16 @@ static inline void filterNodesInLayoutAtIndexesWithIntersectingNodes(
#pragma mark - Layout Transition #pragma mark - Layout Transition
- (BOOL)usesImplicitHierarchyManagement
{
return _usesImplicitHierarchyManagement ?: [[self class] usesImplicitHierarchyManagement];
}
- (void)setUsesImplicitHierarchyManagement:(BOOL)value
{
_usesImplicitHierarchyManagement = value;
}
- (void)animateLayoutTransition:(id<ASContextTransitioning>)context - (void)animateLayoutTransition:(id<ASContextTransitioning>)context
{ {
[self __layoutSublayouts]; [self __layoutSublayouts];
@ -1820,7 +1828,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
layout = [ASLayout layoutWithLayoutableObject:self size:layout.size sublayouts:@[layout]]; layout = [ASLayout layoutWithLayoutableObject:self size:layout.size sublayouts:@[layout]];
} }
return [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) { return [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
if ([[self class] usesImplicitHierarchyManagement]) { if (self.usesImplicitHierarchyManagement) {
return ASObjectIsEqual(layout, evaluatedLayout) == NO && [evaluatedLayout.layoutableObject isKindOfClass:[ASDisplayNode class]]; return ASObjectIsEqual(layout, evaluatedLayout) == NO && [evaluatedLayout.layoutableObject isKindOfClass:[ASDisplayNode class]];
} else { } else {
return [_subnodes containsObject:evaluatedLayout.layoutableObject]; return [_subnodes containsObject:evaluatedLayout.layoutableObject];

View File

@ -72,6 +72,7 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
NSMutableArray *_subnodes; NSMutableArray *_subnodes;
_ASTransitionContext *_transitionContext; _ASTransitionContext *_transitionContext;
BOOL _usesImplicitHierarchyManagement;
NSArray<ASDisplayNode *> *_insertedSubnodes; NSArray<ASDisplayNode *> *_insertedSubnodes;
NSArray<ASDisplayNode *> *_removedSubnodes; NSArray<ASDisplayNode *> *_removedSubnodes;

View File

@ -63,6 +63,15 @@
- (void)testFeatureFlag - (void)testFeatureFlag
{ {
XCTAssert([ASDisplayNode usesImplicitHierarchyManagement]); XCTAssert([ASDisplayNode usesImplicitHierarchyManagement]);
ASDisplayNode *node = [[ASDisplayNode alloc] init];
XCTAssert(node.usesImplicitHierarchyManagement);
[ASDisplayNode setUsesImplicitHierarchyManagement:NO];
XCTAssertFalse([ASDisplayNode usesImplicitHierarchyManagement]);
XCTAssertFalse(node.usesImplicitHierarchyManagement);
node.usesImplicitHierarchyManagement = YES;
XCTAssert(node.usesImplicitHierarchyManagement);
} }
- (void)testInitialNodeInsertionWithOrdering - (void)testInitialNodeInsertionWithOrdering