Swiftgram/AsyncDisplayKit/Private/ASDisplayNodeInternal.h
2016-03-01 09:57:07 -08:00

212 lines
7.2 KiB
Objective-C

/* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
//
// The following methods are ONLY for use by _ASDisplayLayer, _ASDisplayView, and ASDisplayNode.
// These methods must never be called or overridden by other classes.
//
#import "_AS-objc-internal.h"
#import "ASDisplayNodeExtraIvars.h"
#import "ASDisplayNode.h"
#import "ASSentinel.h"
#import "ASThread.h"
#import "ASLayoutOptions.h"
#import "_ASTransitionContext.h"
#include <vector>
@protocol _ASDisplayLayerDelegate;
@class _ASDisplayLayer;
@class _ASPendingState;
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
/// Get the pending view state for the node, creating one if needed.
_ASPendingState *ASDisplayNodeGetPendingState(ASDisplayNode *node);
typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides)
{
ASDisplayNodeMethodOverrideNone = 0,
ASDisplayNodeMethodOverrideTouchesBegan = 1 << 0,
ASDisplayNodeMethodOverrideTouchesCancelled = 1 << 1,
ASDisplayNodeMethodOverrideTouchesEnded = 1 << 2,
ASDisplayNodeMethodOverrideTouchesMoved = 1 << 3,
ASDisplayNodeMethodOverrideLayoutSpecThatFits = 1 << 4
};
@class _ASDisplayNodePosition;
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayScheduledNodesNotification;
FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp;
// Allow 2^n increments of begin disabling hierarchy notifications
#define VISIBILITY_NOTIFICATIONS_DISABLED_BITS 4
#define TIME_DISPLAYNODE_OPS 0 // If you're using this information frequently, try: (DEBUG || PROFILE)
@interface ASDisplayNode ()
{
@package
_ASPendingState *_pendingViewState;
// Protects access to _view, _layer, _pendingViewState, _subnodes, _supernode, and other properties which are accessed from multiple threads.
ASDN::RecursiveMutex _propertyLock;
UIView *_view;
CALayer *_layer;
struct ASDisplayNodeFlags {
// public properties
unsigned synchronous:1;
unsigned layerBacked:1;
unsigned displaysAsynchronously:1;
unsigned shouldRasterizeDescendants:1;
unsigned shouldBypassEnsureDisplay:1;
unsigned displaySuspended:1;
unsigned hasCustomDrawingPriority:1;
// whether custom drawing is enabled
unsigned implementsInstanceDrawRect:1;
unsigned implementsDrawRect:1;
unsigned implementsInstanceImageDisplay:1;
unsigned implementsImageDisplay:1;
unsigned implementsDrawParameters:1;
// internal state
unsigned isMeasured:1;
unsigned isEnteringHierarchy:1;
unsigned isExitingHierarchy:1;
unsigned isInHierarchy:1;
unsigned isMovingBetweenNodes:1;
unsigned visibilityNotificationsDisabled:VISIBILITY_NOTIFICATIONS_DISABLED_BITS;
} _flags;
@protected
ASDisplayNode * __weak _supernode;
ASSentinel *_displaySentinel;
ASSentinel *_replaceAsyncSentinel;
// This is the desired contentsScale, not the scale at which the layer's contents should be displayed
CGFloat _contentsScaleForDisplay;
ASLayout *_previousLayout;
ASLayout *_layout;
ASSizeRange _previousConstrainedSize;
ASSizeRange _constrainedSize;
UIEdgeInsets _hitTestSlop;
NSMutableArray *_subnodes;
_ASTransitionContext *_transitionContext;
BOOL _usesImplicitHierarchyManagement;
NSArray<ASDisplayNode *> *_insertedSubnodes;
NSArray<ASDisplayNode *> *_removedSubnodes;
std::vector<NSInteger> _insertedSubnodePositions;
std::vector<NSInteger> _removedSubnodePositions;
ASDisplayNodeViewBlock _viewBlock;
ASDisplayNodeLayerBlock _layerBlock;
ASDisplayNodeDidLoadBlock _nodeLoadedBlock;
Class _viewClass;
Class _layerClass;
UIImage *_placeholderImage;
CALayer *_placeholderLayer;
// keeps track of nodes/subnodes that have not finished display, used with placeholders
NSMutableSet *_pendingDisplayNodes;
ASDisplayNodeExtraIvars _extra;
ASDisplayNodeContextModifier _willDisplayNodeContentWithRenderingContext;
ASDisplayNodeContextModifier _didDisplayNodeContentWithRenderingContext;
#if TIME_DISPLAYNODE_OPS
@public
NSTimeInterval _debugTimeToCreateView;
NSTimeInterval _debugTimeToApplyPendingState;
NSTimeInterval _debugTimeToAddSubnodeViews;
NSTimeInterval _debugTimeForDidLoad;
#endif
}
+ (void)scheduleNodeForRecursiveDisplay:(ASDisplayNode *)node;
// The _ASDisplayLayer backing the node, if any.
@property (nonatomic, readonly, retain) _ASDisplayLayer *asyncLayer;
// Bitmask to check which methods an object overrides.
@property (nonatomic, assign, readonly) ASDisplayNodeMethodOverrides methodOverrides;
// Swizzle to extend the builtin functionality with custom logic
- (BOOL)__shouldLoadViewOrLayer;
- (BOOL)__shouldSize;
/**
Invoked before a call to setNeedsLayout to the underlying view
*/
- (void)__setNeedsLayout;
/**
Invoked after a call to setNeedsDisplay to the underlying view
*/
- (void)__setNeedsDisplay;
- (void)__layout;
- (void)__setSupernode:(ASDisplayNode *)supernode;
// Private API for helper functions / unit tests. Use ASDisplayNodeDisableHierarchyNotifications() to control this.
- (BOOL)__visibilityNotificationsDisabled;
- (BOOL)__selfOrParentHasVisibilityNotificationsDisabled;
- (void)__incrementVisibilityNotificationsDisabled;
- (void)__decrementVisibilityNotificationsDisabled;
// Helper method to summarize whether or not the node run through the display process
- (BOOL)__implementsDisplay;
// Display the node's view/layer immediately on the current thread, bypassing the background thread rendering. Will be deprecated.
- (void)displayImmediately;
// Alternative initialiser for backing with a custom view class. Supports asynchronous display with _ASDisplayView subclasses.
- (id)initWithViewClass:(Class)viewClass;
// Alternative initialiser for backing with a custom layer class. Supports asynchronous display with _ASDisplayLayer subclasses.
- (id)initWithLayerClass:(Class)layerClass;
@property (nonatomic, assign) CGFloat contentsScaleForDisplay;
- (void)applyPendingViewState;
/**
* // TODO: NOT YET IMPLEMENTED
*
* @abstract Prevents interface state changes from affecting the node, until disabled.
*
* @discussion Useful to avoid flashing after removing a node from the hierarchy and re-adding it.
* Removing a node from the hierarchy will cause it to exit the Display state, clearing its contents.
* For some animations, it's desirable to be able to remove a node without causing it to re-display.
* Once re-enabled, the interface state will be updated to the same value it would have been.
*
* @see ASInterfaceState
*/
@property (nonatomic, assign) BOOL interfaceStateSuspended;
/**
* This method has proven helpful in a few rare scenarios, similar to a category extension on UIView,
* but it's considered private API for now and its use should not be encouraged.
* @param checkViewHierarchy If YES, and no supernode can be found, method will walk up from `self.view` to find a supernode.
* If YES, this method must be called on the main thread and the node must not be layer-backed.
*/
- (ASDisplayNode *)_supernodeWithClass:(Class)supernodeClass checkViewHierarchy:(BOOL)checkViewHierarchy;
@end