[Automatic Hierarchy Management] Rename IHM to automatic hierarchy management and move out of beta header (#2066)

* Rename automaticHierarchy to automaticallyManagesSubnodes

* Comment adjustments
This commit is contained in:
Michael Schneider 2016-08-15 12:06:06 -07:00 committed by Adlai Holler
parent f05ccea860
commit 11215bf97f
10 changed files with 77 additions and 66 deletions

View File

@ -14,7 +14,6 @@
#import "ASDisplayNode+Subclasses.h" #import "ASDisplayNode+Subclasses.h"
#import "ASBackgroundLayoutSpec.h" #import "ASBackgroundLayoutSpec.h"
#import "ASInsetLayoutSpec.h" #import "ASInsetLayoutSpec.h"
#import "ASDisplayNode+Beta.h"
#import "ASStaticLayoutSpec.h" #import "ASStaticLayoutSpec.h"
@interface ASButtonNode () @interface ASButtonNode ()
@ -56,7 +55,7 @@
- (instancetype)init - (instancetype)init
{ {
if (self = [super init]) { if (self = [super init]) {
self.usesImplicitHierarchyManagement = YES; self.automaticallyManagesSubnodes = YES;
_contentSpacing = 8.0; _contentSpacing = 8.0;
_laysOutHorizontally = YES; _laysOutHorizontally = YES;

View File

@ -18,7 +18,6 @@
#import "ASCollectionViewFlowLayoutInspector.h" #import "ASCollectionViewFlowLayoutInspector.h"
#import "ASDisplayNodeExtras.h" #import "ASDisplayNodeExtras.h"
#import "ASDisplayNode+FrameworkPrivate.h" #import "ASDisplayNode+FrameworkPrivate.h"
#import "ASDisplayNode+Beta.h"
#import "ASInternalHelpers.h" #import "ASInternalHelpers.h"
#import "UICollectionViewLayout+ASConvenience.h" #import "UICollectionViewLayout+ASConvenience.h"
#import "ASRangeController.h" #import "ASRangeController.h"

View File

@ -20,9 +20,6 @@ ASDISPLAYNODE_EXTERN_C_END
@interface ASDisplayNode (Beta) @interface ASDisplayNode (Beta)
+ (BOOL)usesImplicitHierarchyManagement;
+ (void)setUsesImplicitHierarchyManagement:(BOOL)enabled;
/** /**
* ASTableView and ASCollectionView now throw exceptions on invalid updates * ASTableView and ASCollectionView now throw exceptions on invalid updates
* like their UIKit counterparts. If YES, these classes will log messages * like their UIKit counterparts. If YES, these classes will log messages
@ -63,8 +60,6 @@ ASDISPLAYNODE_EXTERN_C_END
/** @name Layout Transitioning */ /** @name Layout Transitioning */
@property (nonatomic) BOOL usesImplicitHierarchyManagement;
/** /**
* @abstract Currently used by ASNetworkImageNode and ASMultiplexImageNode to allow their placeholders to stay if they are loading an image from the network. * @abstract Currently used by ASNetworkImageNode and ASMultiplexImageNode to allow their placeholders to stay if they are loading an image from the network.
* Otherwise, a display pass is scheduled and completes, but does not actually draw anything - and ASDisplayNode considers the element finished. * Otherwise, a display pass is scheduled and completes, but does not actually draw anything - and ASDisplayNode considers the element finished.

View File

@ -813,8 +813,24 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
/* /*
ASDisplayNode participates in ASAsyncTransactions, so you can determine when your subnodes are done rendering. * ASDisplayNode support for automatic subnode management.
See: -(void)asyncdisplaykit_asyncTransactionContainerStateDidChange in ASDisplayNodeSubclass.h */
@interface ASDisplayNode (AutomaticSubnodeManagement)
/**
* @abstract A boolean that shows whether the node automatically inserts and removes nodes based on the presence or
* absence of the node and its subnodes is completely determined in its layoutSpecThatFits: method.
*
* @discussion If flag is YES the node no longer require addSubnode: or removeFromSupernode method calls. The presence
* or absence of subnodes is completely determined in its layoutSpecThatFits: method.
*/
@property (nonatomic, assign) BOOL automaticallyManagesSubnodes;
@end
/*
* ASDisplayNode participates in ASAsyncTransactions, so you can determine when your subnodes are done rendering.
* See: -(void)asyncdisplaykit_asyncTransactionContainerStateDidChange in ASDisplayNodeSubclass.h
*/ */
@interface ASDisplayNode (ASDisplayNodeAsyncTransactionContainer) <ASDisplayNodeAsyncTransactionContainer> @interface ASDisplayNode (ASDisplayNodeAsyncTransactionContainer) <ASDisplayNodeAsyncTransactionContainer>
@end @end
@ -829,7 +845,9 @@ NS_ASSUME_NONNULL_BEGIN
- (void)addSubnode:(nonnull ASDisplayNode *)node; - (void)addSubnode:(nonnull ASDisplayNode *)node;
@end @end
/** CALayer(AsyncDisplayKit) defines convenience method for adding sub-ASDisplayNode to a CALayer. */ /*
* CALayer(AsyncDisplayKit) defines convenience method for adding sub-ASDisplayNode to a CALayer.
*/
@interface CALayer (AsyncDisplayKit) @interface CALayer (AsyncDisplayKit)
/** /**
* Convenience method, equivalent to [layer addSublayer:node.layer]. * Convenience method, equivalent to [layer addSublayer:node.layer].
@ -890,6 +908,17 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
- (void)cancelLayoutTransitionsInProgress ASDISPLAYNODE_DEPRECATED; - (void)cancelLayoutTransitionsInProgress ASDISPLAYNODE_DEPRECATED;
/**
* @abstract A boolean that shows whether the node automatically inserts and removes nodes based on the presence or
* absence of the node and its subnodes is completely determined in its layoutSpecThatFits: method.
*
* @discussion If flag is YES the node no longer require addSubnode: or removeFromSupernode method calls. The presence
* or absence of subnodes is completely determined in its layoutSpecThatFits: method.
*
* @deprecated Deprecated in version 2.0: Use automaticallyManagesSubnodes
*/
@property (nonatomic, assign) BOOL usesImplicitHierarchyManagement ASDISPLAYNODE_DEPRECATED;
- (void)reclaimMemory ASDISPLAYNODE_DEPRECATED; - (void)reclaimMemory ASDISPLAYNODE_DEPRECATED;
- (void)recursivelyReclaimMemory ASDISPLAYNODE_DEPRECATED; - (void)recursivelyReclaimMemory ASDISPLAYNODE_DEPRECATED;
@property (nonatomic, assign) BOOL placeholderFadesOut ASDISPLAYNODE_DEPRECATED; @property (nonatomic, assign) BOOL placeholderFadesOut ASDISPLAYNODE_DEPRECATED;

View File

@ -77,18 +77,6 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
@synthesize isFinalLayoutable = _isFinalLayoutable; @synthesize isFinalLayoutable = _isFinalLayoutable;
@synthesize threadSafeBounds = _threadSafeBounds; @synthesize threadSafeBounds = _threadSafeBounds;
static BOOL usesImplicitHierarchyManagement = NO;
+ (BOOL)usesImplicitHierarchyManagement
{
return usesImplicitHierarchyManagement;
}
+ (void)setUsesImplicitHierarchyManagement:(BOOL)enabled
{
usesImplicitHierarchyManagement = enabled;
}
static BOOL suppressesInvalidCollectionUpdateExceptions = YES; static BOOL suppressesInvalidCollectionUpdateExceptions = YES;
+ (BOOL)suppressesInvalidCollectionUpdateExceptions + (BOOL)suppressesInvalidCollectionUpdateExceptions
@ -703,6 +691,20 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
return !self.isNodeLoaded; return !self.isNodeLoaded;
} }
#pragma mark - Automatic Hierarchy
- (BOOL)automaticallyManagesSubnodes
{
ASDN::MutexLocker l(__instanceLock__);
return _automaticallyManagesSubnodes;
}
- (void)setAutomaticallyManagesSubnodes:(BOOL)automaticallyManagesSubnodes
{
ASDN::MutexLocker l(__instanceLock__);
_automaticallyManagesSubnodes = automaticallyManagesSubnodes;
}
#pragma mark - Layout Transition #pragma mark - Layout Transition
- (void)transitionLayoutAnimated:(BOOL)animated measurementCompletion:(void (^)())completion - (void)transitionLayoutAnimated:(BOOL)animated measurementCompletion:(void (^)())completion
@ -751,11 +753,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
ASLayoutableSetCurrentContext(ASLayoutableContextMake(transitionID, NO)); ASLayoutableSetCurrentContext(ASLayoutableContextMake(transitionID, NO));
ASDN::MutexLocker l(__instanceLock__); ASDN::MutexLocker l(__instanceLock__);
BOOL disableImplicitHierarchyManagement = self.usesImplicitHierarchyManagement == NO; BOOL automaticallyManagesSubnodesDisabled = (self.automaticallyManagesSubnodes == NO);
self.usesImplicitHierarchyManagement = YES; // Temporary flag for 1.9.x self.automaticallyManagesSubnodes = YES; // Temporary flag for 1.9.x
newLayout = [self calculateLayoutThatFits:constrainedSize]; newLayout = [self calculateLayoutThatFits:constrainedSize];
if (disableImplicitHierarchyManagement) { if (automaticallyManagesSubnodesDisabled) {
self.usesImplicitHierarchyManagement = NO; // Temporary flag for 1.9.x self.automaticallyManagesSubnodes = NO; // Temporary flag for 1.9.x
} }
ASLayoutableClearCurrentContext(); ASLayoutableClearCurrentContext();
@ -820,18 +822,6 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
} }
} }
- (BOOL)usesImplicitHierarchyManagement
{
ASDN::MutexLocker l(__instanceLock__);
return _usesImplicitHierarchyManagement ? : [[self class] usesImplicitHierarchyManagement];
}
- (void)setUsesImplicitHierarchyManagement:(BOOL)value
{
ASDN::MutexLocker l(__instanceLock__);
_usesImplicitHierarchyManagement = value;
}
- (BOOL)_isTransitionInProgress - (BOOL)_isTransitionInProgress
{ {
ASDN::MutexLocker l(__instanceLock__); ASDN::MutexLocker l(__instanceLock__);
@ -1019,8 +1009,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
*/ */
- (void)_completeLayoutTransition:(ASLayoutTransition *)layoutTransition - (void)_completeLayoutTransition:(ASLayoutTransition *)layoutTransition
{ {
// Layout transition is not supported for non implicit hierarchy managed nodes yet // Layout transition is not supported for nodes that are not have automatic subnode management enabled
if (layoutTransition == nil || self.usesImplicitHierarchyManagement == NO) { if (layoutTransition == nil || self.automaticallyManagesSubnodes == NO) {
return; return;
} }
@ -1186,7 +1176,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
ASDN::MutexLocker l(__instanceLock__); ASDN::MutexLocker l(__instanceLock__);
// FIXME: Ideally we'd call this as soon as the node receives -setNeedsLayout // FIXME: Ideally we'd call this as soon as the node receives -setNeedsLayout
// but implicit hierarchy management would require us to modify the node tree // but automatic subnode management would require us to modify the node tree
// in the background on a loaded node, which isn't currently supported. // in the background on a loaded node, which isn't currently supported.
if (_pendingViewState.hasSetNeedsLayout) { if (_pendingViewState.hasSetNeedsLayout) {
[self __setNeedsLayout]; [self __setNeedsLayout];
@ -1982,7 +1972,7 @@ static NSInteger incrementIfFound(NSInteger i) {
// If a node was added to a supernode, the supernode could be in a layout pending state. All of the hierarchy state // If a node was added to a supernode, the supernode could be in a layout pending state. All of the hierarchy state
// properties related to the transition need to be copied over as well as propagated down the subtree. // properties related to the transition need to be copied over as well as propagated down the subtree.
// This is especially important as with Implicit Hierarchy Management adding subnodes can happen while a transition // This is especially important as with automatic subnode management, adding subnodes can happen while a transition
// is in fly // is in fly
if (ASHierarchyStateIncludesLayoutPending(stateToEnterOrExit)) { if (ASHierarchyStateIncludesLayoutPending(stateToEnterOrExit)) {
int32_t pendingTransitionId = newSupernode.pendingTransitionID; int32_t pendingTransitionId = newSupernode.pendingTransitionID;
@ -2701,7 +2691,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
ASDisplayNodeAssertTrue(layout.size.width >= 0.0); ASDisplayNodeAssertTrue(layout.size.width >= 0.0);
ASDisplayNodeAssertTrue(layout.size.height >= 0.0); ASDisplayNodeAssertTrue(layout.size.height >= 0.0);
if (layoutTransition == nil || self.usesImplicitHierarchyManagement == NO) { if (layoutTransition == nil || self.automaticallyManagesSubnodes == NO) {
return; return;
} }
@ -3294,6 +3284,16 @@ static const char *ASDisplayNodeAssociatedNodeKey = "ASAssociatedNode";
[self cancelLayoutTransition]; [self cancelLayoutTransition];
} }
- (BOOL)usesImplicitHierarchyManagement
{
return self.automaticallyManagesSubnodes;
}
- (void)setUsesImplicitHierarchyManagement:(BOOL)enabled
{
self.automaticallyManagesSubnodes = enabled;
}
- (void)setPlaceholderFadesOut:(BOOL)placeholderFadesOut - (void)setPlaceholderFadesOut:(BOOL)placeholderFadesOut
{ {
self.placeholderFadeDuration = placeholderFadesOut ? 0.1 : 0.0; self.placeholderFadeDuration = placeholderFadesOut ? 0.1 : 0.0;

View File

@ -17,7 +17,6 @@
#import "ASChangeSetDataController.h" #import "ASChangeSetDataController.h"
#import "ASDelegateProxy.h" #import "ASDelegateProxy.h"
#import "ASDisplayNodeExtras.h" #import "ASDisplayNodeExtras.h"
#import "ASDisplayNode+Beta.h"
#import "ASDisplayNode+FrameworkPrivate.h" #import "ASDisplayNode+FrameworkPrivate.h"
#import "ASInternalHelpers.h" #import "ASInternalHelpers.h"
#import "ASLayout.h" #import "ASLayout.h"

View File

@ -344,7 +344,7 @@ if (shouldApply) { _layer.layerProperty = (layerValueExpr); } else { ASDisplayNo
// The node is loaded but we're not on main. // The node is loaded but we're not on main.
// We will call [self __setNeedsLayout] when we apply // We will call [self __setNeedsLayout] when we apply
// the pending state. We need to call it on main if the node is loaded // the pending state. We need to call it on main if the node is loaded
// to support implicit hierarchy management. // to support automatic subnode management.
[ASDisplayNodeGetPendingState(self) setNeedsLayout]; [ASDisplayNodeGetPendingState(self) setNeedsLayout];
} else { } else {
// The node is not loaded and we're not on main. // The node is not loaded and we're not on main.

View File

@ -124,7 +124,7 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
// Main thread only // Main thread only
_ASTransitionContext *_pendingLayoutTransitionContext; _ASTransitionContext *_pendingLayoutTransitionContext;
BOOL _usesImplicitHierarchyManagement; BOOL _automaticallyManagesSubnodes;
NSTimeInterval _defaultLayoutTransitionDuration; NSTimeInterval _defaultLayoutTransitionDuration;
NSTimeInterval _defaultLayoutTransitionDelay; NSTimeInterval _defaultLayoutTransitionDelay;
UIViewAnimationOptions _defaultLayoutTransitionOptions; UIViewAnimationOptions _defaultLayoutTransitionOptions;

View File

@ -15,6 +15,7 @@
#import "NSIndexSet+ASHelpers.h" #import "NSIndexSet+ASHelpers.h"
#import "ASAssert.h" #import "ASAssert.h"
#import "ASDisplayNode+Beta.h" #import "ASDisplayNode+Beta.h"
#import <unordered_map> #import <unordered_map>
#define ASFailUpdateValidation(...)\ #define ASFailUpdateValidation(...)\

View File

@ -47,28 +47,13 @@
@implementation ASDisplayNodeImplicitHierarchyTests @implementation ASDisplayNodeImplicitHierarchyTests
- (void)setUp {
[super setUp];
[ASDisplayNode setUsesImplicitHierarchyManagement:YES];
}
- (void)tearDown {
[ASDisplayNode setUsesImplicitHierarchyManagement:NO];
[super tearDown];
}
- (void)testFeatureFlag - (void)testFeatureFlag
{ {
XCTAssert([ASDisplayNode usesImplicitHierarchyManagement]);
ASDisplayNode *node = [[ASDisplayNode alloc] init]; ASDisplayNode *node = [[ASDisplayNode alloc] init];
XCTAssert(node.usesImplicitHierarchyManagement); XCTAssertFalse(node.automaticallyManagesSubnodes);
[ASDisplayNode setUsesImplicitHierarchyManagement:NO]; node.automaticallyManagesSubnodes = YES;
XCTAssertFalse([ASDisplayNode usesImplicitHierarchyManagement]); XCTAssertTrue(node.automaticallyManagesSubnodes);
XCTAssertFalse(node.usesImplicitHierarchyManagement);
node.usesImplicitHierarchyManagement = YES;
XCTAssert(node.usesImplicitHierarchyManagement);
} }
- (void)testInitialNodeInsertionWithOrdering - (void)testInitialNodeInsertionWithOrdering
@ -80,6 +65,7 @@
ASDisplayNode *node5 = [[ASDisplayNode alloc] init]; ASDisplayNode *node5 = [[ASDisplayNode alloc] init];
ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init]; ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init];
node.automaticallyManagesSubnodes = YES;
node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize) { node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize) {
ASStaticLayoutSpec *staticLayout = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[node4]]; ASStaticLayoutSpec *staticLayout = [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[node4]];
@ -106,6 +92,7 @@
ASDisplayNode *node3 = [[ASDisplayNode alloc] init]; ASDisplayNode *node3 = [[ASDisplayNode alloc] init];
ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init]; ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init];
node.automaticallyManagesSubnodes = YES;
node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize){ node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize){
ASSpecTestDisplayNode *strongNode = (ASSpecTestDisplayNode *)weakNode; ASSpecTestDisplayNode *strongNode = (ASSpecTestDisplayNode *)weakNode;
if ([strongNode.layoutState isEqualToNumber:@1]) { if ([strongNode.layoutState isEqualToNumber:@1]) {
@ -136,6 +123,7 @@
ASDisplayNode *node2 = [[ASDisplayNode alloc] init]; ASDisplayNode *node2 = [[ASDisplayNode alloc] init];
ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init]; ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init];
node.automaticallyManagesSubnodes = YES;
node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize) { node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize) {
ASSpecTestDisplayNode *strongNode = (ASSpecTestDisplayNode *)weakNode; ASSpecTestDisplayNode *strongNode = (ASSpecTestDisplayNode *)weakNode;
if ([strongNode.layoutState isEqualToNumber:@1]) { if ([strongNode.layoutState isEqualToNumber:@1]) {
@ -179,6 +167,7 @@
ASDisplayNode *node2 = [[ASDisplayNode alloc] init]; ASDisplayNode *node2 = [[ASDisplayNode alloc] init];
ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init]; ASSpecTestDisplayNode *node = [[ASSpecTestDisplayNode alloc] init];
node.automaticallyManagesSubnodes = YES;
node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize) { node.layoutSpecBlock = ^(ASDisplayNode *weakNode, ASSizeRange constrainedSize) {
ASSpecTestDisplayNode *strongNode = (ASSpecTestDisplayNode *)weakNode; ASSpecTestDisplayNode *strongNode = (ASSpecTestDisplayNode *)weakNode;